Hi,

1880 haben die Brüder Jacques und Pierre Curie den Piezo Effekt entdeckt. Dieser ist bahnbrechend, da er in vielen Branchen eingesetzt wird. Im Jahr 2010 erzielte der weltweite Markt für piezoelektrische Bauelemente einen Umsatz von rund 14,8 Milliarden US-Dollar.

Wir machen uns diesen Effekt heute zu nutze um mit dem Arduino Sound zu erzeugen. Mal sehen, welche musikalischen Talente im Arduino bzw. in euch stecken.

In Lektion 6 hatten wir die Weltzeituhr bereits mit einer Alarm-Funktion ausgestattet und dafür einen Piezo-Buzzer angeschlossen. In dieser Arduino Anleitungen lernst du eigene Lieder zu komponieren und kannst deinen Wecker sogar erweitern.

Ohne Sound geht nichts – Piezo am Arduino

Du kannst die Schaltungen alle mit einem Piezo Summer am Ausgang betreiben, aber für die etwas fortgeschritteneren Sound Projekte ist es besser, gleich einen kleinen Lautsprecher mit einer Impedanz von  8 Ohm anzuschließen.

Piezo-Summer (links) und Kleinlautsprecher
Piezo-Summer (links) und Kleinlautsprecher

Wenn du dann für die Sound-Projekte Feuer gefangen hast und einen richtigen Synthesizer oder eine Drum-Machine verwirklichen willst, dann willst du wahrscheinlich mit dem Arduino einen Endverstärker ansteuern, um die erzeugten Klänge auf vielfältige Weise wiederzugeben und weiter zu verarbeiten.

Aber wir fangen klein an und schließen erstmal nur den Summer oder Lautsprecher an GND und den digitalen Ausgang 7 an.

Folgender Sketch enthält das Tonausgabe-Modul, wie wir es in Lektion 6 bei der Weltzeituhr benutzt hatten:

 

Der Befehl tone erhält als Parameter die Pinnummer und die Frequenz des abzuspielenden Tons. Dies können wir schon nutzen, um einfache Melodien abzuspielen. Du weißt sicher, dass Töne und Schallwellen nichts anderes sind, als Schwingungen der Luft. Die Frequenz gibt an, wie viele Schwingungen pro Sekunde stattfinden. Je höher die Frequenz, desto höher ist auch der wahrgenommene Ton.  Gemessen wird die Frequenz in der Einheit Herz (Hz), die einfach die Anzahl der Schwingungen pro Sekunde angibt.

Aufstieg zur Tonleiter hinauf

Um die Töne einer Tonleiter zu spielen, brauchen wir also eine Zuordnung der einzelnen Töne zu deren Frequenzen.

Eine solche findet sich z.B. auf der Arduino-Seite:

Diese übersetzen wir einfach in eine Folge von Konstanten mit der Anweisung #define.
Das vorangestellte # steht für eine Compileranweisung. Das heißt, hier kommt kein Befehl, der in Maschinencode für den Arduino übersetzt wird, sondern eine Anweisung, die der Compiler noch vor dem eigentlichen Übersetzungsvorgang ausführt.

Die  #define Anweisung nimmt dabei eine Ersetzung vor, du kannst damit beliebige Zeichenketten abkürzen und ihnen einen einprägsamen Namen geben, den du im späteren Code verwenden kannst.

Damit unterscheidet sich diese Definition von einer Variablen: Die würde nämlich zur Programmlaufzeit im Arduino-Speicher angelegt und ist daher während des Programmablaufs veränderbar.

Die Compileranweisung #define hingegen führt nicht dazu, dass eine Variable angelegt wird, sondern alles was dahinter steht wird vor dem eigentlichen Übersetzungsvorgang im Code ausgewechselt. Das ist in vielen Fällen durchaus sinnvoll, da der Speicherplatz im Arduino etwas knapper bemessen ist.

Wir hinterlegen also die Abkürzungen für die Töne und Frequenzen einer C-Dur Tonleiter:

Dabei haben wir noch ein Symbol P für Pause hinzugefügt. Du kannst nun auf die Frequenzwerte zugreifen, indem du einfach die Notennamen verwendest so wie sie in den Anweisungen stehen. Doch etwas fehlt noch, bevor eine Melodie erklingen kann:

Auf das Timing kommt es an

Klar, die Dauer der einzelnen Noten muss noch festgelegt werden.

Für unsere erste Lösung verwenden wir ein Array für die Notennamen und ein weiteres Array für die Längen der Noten und Pausen in Millisekunden.

So kannst du einen kurzen Jingle oder ein Melodiefragment definieren. Hier ein Beispiel, das du vielleicht schon mal gehört hast:

Das weitere Vorgehen dürfte jetzt klar sein: Mit einer For-Schleife holen wir die Tonhöhe und Haltedauer nacheinander ab und füttern damit den tone  Befehl.

Das kannst du sinnvoll in eine eigene Funktion packen:

Die Laufweite der For-Schleife wird hier durch eine neue Funktion namens sizeof definiert. Sie gibt zurück, wie viele Bytes eine  Variable im Speicher belegt. Dies zu wissen ist oft sehr nützlich. Ansonsten müsstest du jedes mal, wenn Töne in der Melodie hinzukommen oder entfernt werden auch die Abfrage in der For-Schleife entsprechend abändern. Das geschieht aber jetzt automatisch. Denn die Einträge des  Arrays melodie  bestehen ja  aus  int-Variablen und eine solche belegt  gerade 2 Bytes.

Der Ausdruck  sizeof(melodie)/2  gibt also die Anzahl der Elemente des Arrays an, in diesem Beispiel also die Anzahl der Töne.

Die If-Abfrage sorgt dafür, dass bei einer Pause auch tatsächlich kein Ton ausgegeben wird. Der Gedanke, dass bei einer Tonfrequenz von 0 Hz auch kein Ton kommt ist zwar logisch, funktioniert aber in der Praxis nicht, weil der Lautsprecher dann trotzdem ein knackendes Geräusch von sich gibt. Deshalb brauchen wir dort die Abfrage.

Der Melodiegenerator ist startbereit

Führen wir nun alles zusammen, dann erhalten wir den ersten kleinen Melodiegenerator:

 

Als nächstes kannst du noch einen Lautstärkeregler einbauen. Das hierzu nötige Bauteil kennst du auch schon: Das Potentiometer.

Am besten geeignet ist ein 1 kOhm Poti, zur Not tut es auch die 10 kOhm-Variante, dann ist aber der sinnvolle Einstellbereich auf eine Zehnteldrehung eingeschränkt, doch mit genügend Fingerspitzengefühl lässt sich auch damit die Lautstärke vernünftig regeln.

Das Poti wird einfach in den Lautsprecherkreis eingehängt, wobei du einen der  äußeren und den mittleren Anschluss verwenden musst.

Doch das Poti kann als einstellbares Element noch viele andere spannende Funktionen in der elektronischen Musikerzeugung übernehmen. Ein Beispiel schauen wir uns jetzt genauer an:

Ein Pitch-Regler kontrolliert die Tonhöhe

Wie wäre es, wenn du mit dem Poti die Tonhöhe der Melodie kontrollieren könntest und sie zwischen tiefen Bass oder hohem Piepsen hin- und herschieben könntest?

Anschlussplan für den Lautsprecher und das Poti
Anschlussplan für den Lautsprecher und das Poti

 

Dank einer Eigenheit der Tonhöhenwahrnehmung können wir das relativ leicht erreichen.Dazu müssen wir aber erst Mal ein wenig in die Theorie eintauchen:

Das menschliche Gehör empfindet ein Intervall zwischen zwei Tönen nicht etwa dann als gleich, wenn der Abstand zwischen den Frequenzen gleich ist. Stattdessen muss das Verhältnis der beiden Frequenzen gleich sein.

Rechnen mit Tönen

Ein Beispiel soll dies verdeutlichen:

Nehmen wir das Intervall c1-g1.(Der Musiker sagt dazu Quinte).

Aus unserer Tabelle wissen wir, dass die entsprechenden Frequenzen dann f_c1=261 Hz  und f_g1=392 Hz  sind. Der Abstand dazwischen ist also 131 Hz.

Wenn das Intervall jetzt eine Oktave höher erklingen soll, dann ist der neue Grundton C2 und liegt bei f_c2= 523 Hz .

Liegt nun f_g2  bei 523+131=654 Hz ?

Nein, das wäre der Fall, wenn die Abstände der Frequenzen die Intervalle bestimmen würden. Stattdessen müssen wir das Verhältnis anschauen:  f_g1/f_c1=392/261=1,5

Deshalb liegt die Frequenz für g2 bei f_g2=784 Hz , denn es muss ja wieder gelten: f_g2/f_c2=1,5 .

Der Sinn dieser ganzen Rechnerei ist die Erkenntnis, dass wir eine Tonfolge komplett in ihrer Tonhöhe hoch- oder runterschieben können, ohne dass sich die musikalische Melodie ändert, indem wir einfach jede einzelne Tonfrequenz mit demselben konstanten Faktor multiplizieren. (Musiker nennen das dann Transponieren.)

 

Aufbau
Aufbau

Und damit haben wir gleich die Lösung für den Arduino parat: Wir legen ein Poti an den Analogeingang, fragen dort einen veränderbaren Wert ab und multiplizieren beim Abspielen alle Frequenzen damit. Schon haben wir einen Pitch-Regler gebaut.

 

Auf und Ab

Probiere es aus und lass deine Melodie in allen Tonarten hoch und runter erklingen mit diesem Sketch:

 

Der Funktion spiele_Melodie müssen wir nun den Parameter Pitch mitgeben. Darin steht der Faktor, mit dem alle Töne beim Abspielen multipliziert werden. Um ihn zu erhalten, wird der Analogpin 0 ausgelesen. Aufgrund der Division durch 256 erhalten wir Werte zwischen 0 und 4 (der A/D-Wandler liefert ja Werte bis 1023).

Das heißt gegenüber der vorigen Version können wir jetzt bis zu 4 Oktaven höher einstellen. Nach unten sind irgendwann physikalische Grenzen gesetzt, weil unter einer bestimmten Schwingungsanzahl nicht mehr wirklich Töne wahrgenommen werden können. Aber probiere es einfach aus und experimentiere mit den Einstellungen und was passiert, wenn du dort andere Zahlen einsetzt.

Auch in Zeile 25 ist eine kleine Änderung hinzugekommen: Wir müssen den Frequenzwert in eine float-Zahl umwandeln, um sicherzustellen, dass die Berechnung richtig ausgeführt wird.

Das war es erstmal, aber nächstes Mal setzen wir den Streifzug durch die elektronische Musik mit dem Arduino fort!

 

 

 

Wie Du mit dem Sound von 1880 deinen Arduino rockst (1/2)

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.