Ein MEMS-Mikrofon am ATtiny85    


Elektronik-Labor   Projekte   AVR  Tiny85




Video: https://youtu.be/DLYipkY-TOk


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