
Ein MEMS-Mikrofon am ATtiny85
Elektronik-Labor Projekte AVR Tiny85
Kürzlich
habe ich ja ein MEMS-Mikrofon und andere schöne Bauteile aus dem abgesoffenen
Smartphone meines Bruders ausgebaut. Es fehlte noch ein Funktionstest, den ich
jetzt mit einem Tiny85 erfolgreich nachgeholt habe. Er hat den Vorteil, dass
man den AD-Wandler mit einer Referenz von 1,1 V betreiben kann und zusätzlich
eine Differenzmessung mit 20-facher Verstärkung durchführen kann. Beide
Maßnahmen ersetzen einen Vorverstärker mit 100-facher Spannungsverstärkung.
Deshalb sollte der Controller allein mit der relativ geringen Signalspannung im
Bereich 1 mV auskommen.
Außerdem
habe ich auch den offenen Vibrationsmotor aus dem Smartphone mit
eingebaut. Der Motor soll dann auf Geräusche reagieren. Die Idee
habe ich überigns von einem Calliope-Projekt, und ich wollte mal
ausprobieren, ob der Tiny85 das nicht mit weniger Aufwand schafft. Dass
er direkt am Port einen solchen Motor treiben kann, wurde ja schon getestet.
Für
den Differenzeingang des AD-Wandlers habe ich ADC2/3 gewählt, also PB3
und PB4. Das ist insofern eine gewisse Verschwendung, als zwei Ports
für nur einen Signaleingang verwendet werden. Aber an PB4 liegt
gleichzeitig der Motor, sodass man abwechselnd messen und vibrieren
kann.
Die
Mikrofonspannung wird zwischen PB3 und PB4 gemessen, die im Ruhezustand
beide bei 0 V liegen. PB4 ist dann als Ausgang auf Null geschaltet.
Trotzdem kann auch der Motor eine messbare Signalspannung abgeben. Wenn
man ihn mit dem Finger anstößt, erzeugt er trotz des niedrigen
Innenwiderstands am Port eine ausreichend große Induktionsspannung, die
dieselbe Wirkung hat wie ein Geräusch am Mikrofon. Man kann einen
Vorgang also entweder mit einem Geräusch oder mit einer Bewegung
triggern.
'MEMS.bas MEMS an ADC2 und ADC3
$regfile = "attiny85.dat"
$crystal = 8000000
$hwstack = 8
$swstack = 4
$framesize = 4
Dim D As Word
Open "comb.1:9600,8,n,1" For Output As #1
Config Adc = Single , Prescaler = Auto , Reference = Internal_1.1
Adcsrb = 0 ' Unipolar
Ddrb.4 = 1 ' Referenz-Pin
Portb.4 = 0
Do
D = Getadc(7) ' (ADC2-ADC3)*20
If D > 100 Then
Waitms 500
Portb.4 = 1
Waitms 1000
Portb.4 = 0
Waitms 1000
End If
Loop
Do
D = Getadc(7) ' (ADC2-ADC3)*20
Waitus 200
Print #1 , D
Loop
End
In
der Steuersoftware wird laufend nach einem Grenzwert geschaut.
Wird er überschritten, wartet das Programm erst noch einen Moment, weil
das dann intelligenter aussieht, so als müsste das Ereignis erst noch
mühsam ausgewertet werden. Dann wird der Motor für eine Sekunde
eingeschaltet. Man kann also komplexe Kommandos rufen (Motor an!
Und Los!), solange sie nicht länger als eine halbe Sekunde sind.
Oder man verschiebt die Platine auf dem Tisch, einen Moment später
bringt die Vibration sie wieder zurück.
Das
Programm enthält noch eine alternative Hauptschleife, in der alle
Messwerte über die serielle Schnittstelle weitergegeben werden. Zur
Darstellung wurde der serielle Plotter aus der aktuellen Arduino-IDE
verwendet. Achtung, Arduino setzt DTR, was auf der Platine zu einem
Reset führt. Man muss die Reset-Leitung des Tin85 mit VCC verbinden, um
das zu verhindern. Dann hat man ein kleines Oszilloskop. Der Nullpunkt
ist aufgrund zufälliger Toleranzen auf 50 hochgerutscht. Die Amplitude
erreicht hier etwa 25, was mit der gegebenen Verstärkung rund 1,3 mV
bedeutet.
Elektronik-Labor Projekte AVR Tiny85