Mit dem Raspberry Pi einen passiven Lautsprecher ansprechen und zur Sirene machen

Bisher haben wir ja nur immer den aktiven Buzzer benutzt, der ja von sich selbst aus einen Piep-Ton aus gibt. In meinem Starter-Kit war natürlich auch ein passiver Lautsprecher und aus dem muss doch auch ein Ton herauszukriegen sein.

Wir wandeln unsere Schaltung mit LED und Buzzer nur ganz leicht ab und setzen statt des Buzzers den passiven Lautsprecher ein, der fast genauso aussieht. Auch er hat eine Polarität (auch wenn ich jetzt aus dem Stegreif nicht weiß, warum), aber ein polaritätsloser, normaler Mini-Lautsprecher (z. B. aus einem alten Telefon oder Stereobox) sollte es genauso tun.

Da der Lautsprecher nur mit 3.3 Volt angesprochen ist er nicht besonders laut. Man kann ihn schon ganz gut hören, wenn es im Zimmer still ist, aber ich habe festgestellt, das mein Exemplar etwas lauter wird, wenn man einen Streifen Klebefilm oben auf das Löchlein klebt.

Zuerst wieder ein kleines Video, dass das Ergebnis zeigt, damit ihr schon einmal wisst, wo wir hinwollen:





Für den aktiven Buzzer reichte es, eine Spannung anzulegen und schon piepte er fröhlich los. Eine darin befindliche Schaltung sorgt dafür, dass die Membran darin mit eine bestimmte Frequenz (gemessen in Hertz, Schwingungen pro Sekunde) schwingt.

Bei dem passiven Lautsprecher müssen wir selbst dafür sorgen, dass dieser schwingt, und zwar indem wir ihn ganz schnell hintereinander ein- und ausschalten. Bei Spannung wird ein kleiner Elektomagnet aktiv und zieht eine an einer Spule angebrachte Membran nach innen. Bei Spannungsabfall schwingt die Membran wieder in den Ruhezustand nach außen. Durch schnelles Ein-/Ausschalten können wir die Membran zum schwingen bringen. Tun wir dies z. B. 440 mal pro Sekunde, so spricht man von einer Frequenz von 440 Hz, was übrigenz dem Kammerton A entspricht.

Die LED, die ja immer noch angeschlossen ist, wird übrigens genau so schnell ein- und ausgeschaltet. Das macht der LED aber nichts aus. Eine LED kann sehr schnelle Schaltvorgängen abbilden, allerdings reicht das menschliche Auge nicht aus, um das schnelle Ein-/Ausschalten wahrzunehmen. Man nimmt lediglich ein etwas helleres oder dunkleres Licht wahr. Bei der Sirene kann man ganz gut erkennen, wie die LED ihre Helligkeit ändert.

Indem wir die Frequenz in einer Schleife erst erhöhen und dann wieder verringern, erzeugen wir ein Auf- und Abschwellen des Tones, nichts anderes ist eine Sirene.

Da der Raspberry im Hintergrund noch einiges anderes zu tun hat, ist das Timing nicht 100%ig sauber. Das merkt man ganz deutlich, wenn man z. B. über eine Samba-Freigabe eine Datei auf dem Raspi speichert. Das hat Auswirkungen auf die Auslastung des Raspi und minimal auch auf die Ausführzeit von time.sleep(). Bei Aktivität können sich die Sirenen dann etwas schräg anhören - das menschliche Gehör ist da sehr sensibel und erkennt schnell Abweichungen. Damit müssen wir aber leben, Python ist nunmal kein Echtzeit-Betriebssystem.

Bewerkstelligt werden die Sirenen durch den folgenden Code, der mit den Inline-Kommentaren schon gut dokumentiert ist. Auf ein paar Eigenarten gehen ich nach dem Listing ein.

# -*- encoding: utf-8 -*- # 2018 by Oliver Kuhlemann # Bei Verwendung freue ich mich über Namensnennung, # Quellenangabe und Verlinkung # Quelle: http://cool-web.de/raspberry/ import RPi.GPIO as GPIO # Funktionen für die GPIO-Ansteuerung laden import time # für sleep() (Pause) nötig GPIO.setmode(GPIO.BCM) # die GPIO-Pins im BCM-Modus ansprechen led=14 # unsere LED hängt an BCM-Pin 14 GPIO.setup(led, GPIO.OUT) # in den LED-Pin wird "geschrieben" def sound(freq, t): # Diese Funktion erzeugt eine bestimmte Zeit t lang dur=1.0/freq/2.0 # die Frequenz freq auf dem LED-Pin anz=int(t/dur/2) for i in range (0,anz): # range macht, solange der zweite Wert kleiner ist # (nicht gleich), darum beginnen wir bei 0 GPIO.output(led, GPIO.HIGH) time.sleep (dur) GPIO.output(led, GPIO.LOW) time.sleep (dur) def sirene (fVon, fBis, speed, wdhl): # Frequenz: von, bis (Hz) # speed: je kleiner, desto schneller # wdhl: wie oft wiederholen? f=fVon for w in range (1,wdhl+1): while f <= fBis: sound (f, speed) f+=10 while f >= fVon: sound (f, speed) f-=10 print "langsame Polizeisirene..." sirene (500,1500,0.01,4) time.sleep (1) print "schnelle Polizeisirene..." sirene (1500,3000,0.0012,10) time.sleep (1) print "Spaceship..." sirene (500,1500,0.002,7) time.sleep (1) print "langsame Sirene..." sirene (100,500,0.05,3) GPIO.cleanup() # Programm sauber verlassen und Resourcen wieder freigeben Das meiste (Funktionen und Schleifen) kennen wir ja schon. Wer da noch Lücken hat, sollte sich vorher die vorherigen Teile anschauen. Darauf gehe ich hier nicht erneut ein.

Die Funktion sound(freq, t) ist die Kernfunktion: sie bringt den Lautsprecher zum schwingen. Und zwar mit der Frequenz freq über einen Zeitraum t. sound(1000,1) würde also einen 1000 Hz-Ton für eine Sekunde lang abspielen. Dazu würde die Funktion den Lautsprecher 1000 mal ein- und ausschalten in dieser Sekunde.

Auf die sound-Funktion baut die sirene (fVon, fBis, speed, wdhl) Funktion auf. Diese spielt einfach hintereinander alle Töne zwischen den beiden übergebenen Frequenzen ab, erst aufwärts von fVon bis fBis und dann wieder abwärts von fBis bis fVon. Der Parameter speed bestimmt die Einzeltonlänge. Je kleiner speed ist, desto schneller wird das Auf- und Abschwellen der Sirene. Das Ganze macht die Funktion so oft, wie in wdhl angegeben.

Das war auch schon der ganze Zauber. Danach wird die sirene-Funktion nur mit unterschiedlichen Parametern aufgerufen, um unterschiedliche Sirenen zu simulieren. Viel Spaß beim experimentieren und Erschaffen von weiteren Sirenen.