Willkommen zurück zum Arduino-Kurs,

im letzten Tutorial hatte dein Mikrocontroller frei und wir haben stattdessen einen kleinen Audio-Verstärker gebaut.

Den können wir heute gut gebrauchen, denn wir werden ein sehr schwaches Signal generieren und wollen dieses über den Lautsprecher hörbar machen.

Aber von Anfang an: Mit Tonerzeugung auf dem Arduino haben wir uns in der vorletzten Lektion bereits beschäftigt.

Wenn du den Sketch dort ausprobiert hast und vielleicht auch deine eigenen Musik-Ideen verwirklicht hast, dann hast du dir vielleicht gewünscht, ein paar andere Klangfarben zu erzeugen als diesen im Grunde nicht sehr aufregenden Piepton.

Mit Bordmitteln ist das leider nicht möglich, aber natürlich können wir da trotzdem Abhilfe schaffen. Und zwar dadurch, dass wir die elektronische Klangerzeugung heute komplett selbst in die Hand nehmen!

Von Zahlen zu Spannungen

Die Schaltung, die dies ermöglicht heißt Digital Analog Wandler (DA Wandler) oder manchmal auch Digital-Analog-Umsetzer (DAU) genannt. Sie dient dazu, das digitale Audio-Format, das im Speicher des Arduino liegt umzuwandeln in ein elektrisches Signal, das einen Verstärker ansteuern kann und schließlich in Form von Schall auf einem Lautsprecher wiedergegeben wird.

Die umgekehrte Funktion hast du ja bereits in den früheren Lektionen kennen gelernt: Der Arduino Uno verfügt mit seinen 6 Analogeingängen über einen Analog-Digital Wandler, mit dem du eine analoge Spannung am Eingang in eine Zahl zwischen 0 und 1024 umwandeln kannst. Jetzt wollen wir stattdessen eine Zahl in einen Spannungswert umwandeln.

Die Wellenform, die den Klang beschreibt ist zunächst mal nur eine eihe von Zahlen. Sie wird als Byte-Array im Speicher des Arduino abgelegt. Das heißt, in diesem Array steht für jeden Zeitpunkt eine Zahl, die beschreibt, wie stark die Membran des Lautsprechers ausgelenkt sein muss.

Im Loop-Block werden dann die einzelnen Werte im genauen Timing an den Digital zu Analog Wandler geschickt. Dieser wandelt die digitalen Werte in eine Ausgangsspannung um, die wir an den Eingang eines Verstärkers schicken.

Kommen wir also zuerst zum Herzstück der Schaltung, dem DA Wandler:

 Sag es mit 1 und 0

Um einen digitalen Wert umzuwandeln, nutzen wir natürlich die digitalen Pins 0 bis 7. Damit haben wir 8 Bit zur Verfügung und können den Wertebereich von 0 bis 255 verwenden. Das heißt 0 entspricht einer Ausgangsspannung von 0 V (MAsse) und 255 entspricht +5V.

Die Binärdarstellung von Zahlen ist dir sicher ein Begriff, schließlich basiert ja die ganze Digitaltechnik darauf. Daher erklären wir hier nur sehr kurz das System:

Jeder digitale Pin steht für eine Zweierpotenz. Man kann jede Zahl zwischen 0 und 255 als Summe von Zweierpotenzen darstellen. Beispielsweise ist 51 = 32 + 16 + 2+1 = 24+23+21+20.

Im Dualsystem schreiben wir dann 11011  und meinen damit 1* 24 + 1 * 23 + 0 * 22+1*22 +1*20.

Um diese Zahl darzustellen, liegen also die Pins 0, 1, 3 und 4 auf HIGH,  die anderen Pins liegen auf LOW .

Die Binärdarstellung ist mit dem Arduino sehr leicht umzusetzen, denn intern speichert der Mikrocontroller alle ganzen Zahlen ja ohnehin als Dualzahlen ab. Deswegen stellt der Arduino einen komfortablen Weg zur Verfügung, um die digitalen Pins mit einer Dualzahl zu belegen.

Mit PORTD die digitalen Pins kontrollieren

Anstatt wie du vielleicht erwartet hast, in einer For-Schleife den Befehl digitalWrite  8 mal hintereinander auszuführen und die einzelnen Binärstellen zu übertragen (das könnte man so machen, aber es geht einfacher!), schicken wir einfach mit der Systemvariablen PORTD  die Zahl auf einen Schlag an die digitalen Ausgänge.

Mit   <span style="font-size: medium;">PORTD  hast du Zugriff auf alle digitalen Ports des Arduino auf einen Schlag, denn die Zahl, die in dieser Variablen abgespeichert ist, gibt eben gerade die Pinbelegung der Ports als Binärwert wieder.

Diese müssen wir nun also in eine Ausgangsspannung  umwandeln. Das erledigt die sogenannte Widerstandsleiter. Im Schaltplan findest du ein Netzwerk von 16 Widerständen, die alle entweder 10 kOhm oder 20 kOhm gross sind. Das ist das Herzstück des DA Wandlers.

Die Widerstände sind so verschaltet, dass die Ausgangsspannung um so stärker auf die Spannung an einem Digitalpin reagiert, je höher der Stellenwert dieses Pins im Binärsystem ist, sprich welche Zweierpotenz ihm zugeordnet ist.

Stell dir einfach am Ausgang, also da wo „zum Verstärker“ steht, einen weiteren Widerstand von 20k gegen Masse vor. Er symbolisiert den Verstärker oder allgemein irgendeinen Verbraucher.

Wenn du nun etwa Pin 7 von LOW auf HIGH schaltest, springt die Ausgangsspannung direkt von 0 V auf 2.5 V.

Schaltest du stattdessen  Pin 1, teilt sich die Spannung über die komplette Widerstandsreihe von R11 bis R17 einerseits und dem Verbraucher auf, so dass eine viel kleinere Spannung am Ausgang entsteht.

So wird auf natürliche Weise die an den Pins anliegende Binärzahl in einen Spannungswert verwandelt. Alle Pins, die auf High liegen, legen +5V an entsprechender Stelle in die Widerstandsreihe. Und je niedriger der Stellenwert des Bits ist, desto mehr Widerstände sind zu überbrücken, desto niedriger wird also die Spannungsänderung am Ausgang sein.

DA Wandler Schaltplan

Wenn du die Widerstandsleiter angeschlossen hast, dann kannst du mit einem Multimeter die Ausgangsspannung messen und verschiedene Werte über PORTD an die Pins senden.  So kannst du die Funktion des Da Wandlers schrittweise untersuchen und nachvollziehen.

Mit diesem kleinen Testsketch wird die Ausgangsspannung alle 3 Sekunden um ca. 0.2 V steigen, du kannst das mit leicht mit einem Messgerät verfolgen:

 

dawandler_Steckplatine

 

Damit hätten wir den Hardware-Teil bereits erledigt.

 

Bridge

 

Oben siehst du die Widerstandsreihe auf einem Breadboard und das untere Bild zeiggt, wie die Module ineinandergreifen und der Ausgang des DA Wandlers den Verstärkerbaustein aus der letzten Lektion füttert:

Gesamtaufbau

Auf die Klangfarbe kommt es an

Nun kommen wir zum Sketch.

Bei der Programmierung geht es jetzt vor allem darum, die Wellenform zu definieren, die zum Lautsprecher geschickt wird.

Für das Gehör äußert sich das in der Klangfarbe, die der Ton als Höreindruck hinterlässt. Der reinste Ton wird durch eine Sinuswelle erzeugt. Sie ist durch einen sanft geschwungenen, runden Verlauf gekennzeichnet.

Die Sinuskurve ist gleichzeitig die Grundform aller Schwingungen, das heißt du kannst jede beliebige periodische Kurve durch Überlagerung von Sinuskurven beschreiben.

Je stärker die abgespielte Wellenform von dieser Sinusform abweicht, desto schärfer und stechender wird der Klang. Und das liegt gerade daran, dass dadurch zusätzliche Wellen in höheren Frequenzen hinzukommen. Man spricht dann von Obertönen oder Oberwellen.

Jeder Ton hat eine Grundschwingung und eine Reihe von Obertönen. Die Grundschwingung ist eine Sinuskurve und gibt an, welchen Ton wir da überhaupt hören, also die Tonhöhe oder Frequenz.

Aber das hohe c auf der Geige klingt anders als das auf der Blockflöte, obwohl es dieselbe Tonhöhe hat. Das liegt an den unterschiedlichen Oberwellen, die in diesen beiden Instrumenten erzeugt werden. Die Flöte klingt weicher, runder. Die Geige hat dagegen mehr Schärfe im Klang. Sie hat ein reicheres Obertonspektrum.

Für unseren Arduino-Synthesizer  schauen wir uns drei Kurvenformen an, die in der Elektronik immer wieder vorkommen. Und zwar sind das Sinus-, Rechteck- und Dreieckschwingung.

Sie sehen so aus, wie in der Abbildung:

wellenformen

Die Rechteckschwingung besteht einfach aus einem schnellen periodischen Ein- und Ausschalten des Signals. Das ist übrigens der Klang, den der tone Befehl aus Teil 1 dieses Tutorials erzeugt. Sie hat sehr viele Oberwellen und klingt daher scharf und stechend.

Die Dreieckschwingung ist schließlich ein Zwischending: Hier steigt das Signal linear mit der Zeit an und schwillt dann wieder ab und so immer weiter. Sie hat mehr Oberwellen als eine sinusfürmige Schwingung, aber weniger als die Rechteckschwingung.

Wir speichern in den zeilen 14 bis 16 diese drei Grundformen in drei Arrays mit jeweils 100 Werten ab. Diese müssen jetzt via PORTD mit dem richtigen Timing an den DA Wandler geschickt werden. Das erledigen die Zeilen 36 und 37.

Das Delay in Zeile 37 enthält einen neuen Befehl: delayMicroseconds.

Du kannst nämlich ein Delay nicht nur in Millisekunden, sondern auch in tausendstel Millisekunden oder Mikrosekunden angeben.

Für die sehr zeitkritische Anwendung einer direkten Tonerzeugung mit dem Arduino ist das wichtig. Dieses Delay gibt die Zeit an zwischen zwei Sample-Werten, die an den Verstärker gehen. Je größer das Delay, desto länger dauert es, bis die Wellenform komplett abgespielt wird. Das heißt dann hast du eine kleinere Frequenz und damit einen tieferen Ton. Experimentiere hier ruhig erst einmal mit festen Werten für das Delay zwischen 5 und 50.

Der Arduino gibt den Takt vor

Um die Wellenform zu ändern, musst du in Zeile 36 den Variablennamen ändern und den Sketch neu an den Arduino abschicken. Ersetze also sine[t] in Zeile 37 durch rect[t]  oder triag[t]  und übertrage den Sketch neu.

Das mag etwas umständlich erscheinen: Warum bauen wir nicht einen Taster ein und lassen damit den Arduino das Umschalten übernehmen?

Das könnte man in der Tat machen, aber dann stößt man auf eine Schwierigkeit. Mit der Tonerzeugung über den Sketch haben wir die Taktfrequenz von 16 MHz des Arduino bis ans Limit ausgereizt. Diese Taktfrequenz gibt vor, wie schnell die Programmbefehle vom Mikrocontroller zur Laufzeit bearbeitet werden.

Jeder zusätzliche Befehl verlängert die Delayzeit zwischen zwei Samples und das ist sofort im Ausgabeton deutlich hörbar. Eine zusätzliche If-Abfrage würde so viel Zeit kosten, dass die Tonerzeugungs-Schleife zusammenbricht. Du kannst es ja ruhig einmal ausprobieren was passiert, wenn du zusätzliche Abfragen in den Sketch einbaust.

Natürlich ist es trotzdem möglich, solche Abfragen zu verwirklichen, ohne dass die Tonerzeugung dadurch gestört wird. Dann müssten wir aber mit einem ganz anderen Konzept arbeiten, mit sogenannten Interrupts. Dieses Thema ist ein wenig mehr fortgeschritten und wird daher in diesem Kurs nicht behandelt, aber du siehst, dass auch nach Abschluss des Online-Kurses noch genügend zum Lernen übrig bleibt. 🙂

 

Jetzt wird Sound draus

Der Arduino tönt nun in der von uns gewählten Wellenform. Die Tonhöhe gibst du über die Variable del ein, die in Zeile 19 definiert wird. Je kleiner der Wert, desto höher der Ton.

Aber bisher spielt die Schaltung nur einen Dauerton. Interessanter wäre natürlich, wenn wir die Tonhöhe beeinflussen könnten. Da liegt es doch nahe, den Wert des Delay an ein Poti zu koppeln, das wir über einen  analogen Pin auslesen. Das ist für dich kein Hexenwerk mehr, denn das haben wir schon öfters gemacht. Das Poti kommt mit den beiden äußeren Anschlüssen zwischen +5V und Masse und der mittlere Abgriff wird mit dem Analoginput A0 verbunden. In Zeile 33 fragen wir den dort eingestellten Wert ab und berechnen daraus einen Wert für die Variable del, die das Mikrosekunden-Delay trägt.  Auch hier kannst du wie immer an den Parametern herumspielen, um die Schaltung so klingen zu lassen, wie du es wünschst.

Aufbau_mit_poti

Mit der Tonerzeugung haben wir ein weites Feld angestoßen, es gibt viele Möglichkeiten das Projekt zu erweitern oder abzuändern. Dies sollte eine kleine Einführung sein, um zu zeigen, dass der Bau eines kleinen Synthesizers mit Arduino DA Wandler gar nicht so schwer ist, aber eine Menge Spaß bringt.

Bis zum nächsten Mal!

 

Bist du bereit, aus Arduino und DA Wandler einen Synthesizers zu bauen?
Markiert in:    

Schreibe einen Kommentar

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