Musik und Geräusche mit einem Arduino abspielen? Kein Problem mit dem guten alten WAVE-Format, einem SD-Kartenleser und der TMRpcm Library.

Arduino WAV Musik SD-Karte Eins gleich vorweg: Hifi-Qualität darf man von der hier beschriebenen Lösung nicht erwarten. Aber als Low-Budget-Player für einfache Zwecke reicht es auf jeden Fall. Habe ich beispielsweise hier im Kunstprojekt RIBB@TACKING Bruce Lee – a C64 game tribute and homage verwendet.

Was man braucht

Natürlich einen Arduino; der hier beschriebene Aufbau wurde mit einem Uno getestet. Alle 328er basierten, also auch Nano, LilyPad, Pro etc. sollten gleichermaßen funktionieren.

Da die WAVE-Dateien irgendwo abgespeichert sein müssen, bietet sich ein SD Kartenleser an. Es gibt Breakout Boards mit Micro-SD-Karten Slot oder andere Shields, auf denen solch ein Slot bereits integriert ist, bspw. das Ethernet-Shield. Hier kommt ein sehr einfacher 1 EUR SD-Kartenleser von eBay zum Einsatz. Dazu eine (alte) SD Karte.

Damit man etwas hört, braucht es einen Verstärker. Bryan beschreibt in diesem Blog-Artikel, wie man mit einem einzigen Transistor nebst Widerstand (4,7 kOhm) einen simplen Verstärker zusammenschustert. Der BC548B hat nicht ausreichend verstärkt. Mit dem 2N3904 (eBay) macht es mehr Spaß.

Dazu natürlich ein Lautsprecher, da hatte ich noch einen mit 0,25 Watt 4 Ohm auf Halde liegen.

Verkabelung / Aufbau

Die Anbindung des SD-Kartenlesers erfolgt über die Hardware SPI Pins des Arduino. Welche Pins das genau sind, hängt vom Arduino-Typ ab. Die hier gezeigte Verkabelung sollte für alle 328er Typen (Nano, Uno, etc.) funktionieren. Chip Select ist frei wählbar; vgl. auch der weiter unten stehende Arduino Sketch. Die Schaltung auf dem Breadboard ist der erwähnte Ein-Transistor-Verstärker. Wenn man hier den Widerstand zwischen Arduino-Ausgang (Pin 9) und der Transistorbasis zu klein wählt, kann man nach kurzer Zeit auf dem Transistor Eier braten, da zu viel Strom durch die Collector-Emitter-Strecke fliesst.

Arduino-WAVE-Player-Steckplatine-Breadboard-450x345

Wagemutige können den Widerstand einfach mal ganz weglassen und sich an einer, dann, recht ordentlichen Beschallung nebst Transistorheizung erfreuen. Das sei hiermit also ausdrücklich nicht empfohlen.

Kartenleser PINArduino PINWas ist das?
GNDGNDGround
+5V5VVolle Power! 🙂
MOSI11DATA, MOSI DATA, SDA, Hardware MOSI
MISO12MISO, Hardware MISO
CLK13CLK, SCL, Hardware SCK
CS4CS, Chip Select
GNDGNDGround

In der Tabelle ist die PIN-Verkabelung noch einmal aufgeführt. Der verwendete SD-Kartenleser hat zwei GND-Anschlüsse und funktioniert auch nur zuverlässig, wenn tatsächlich beide mit Masse verbunden werden. Der Lautsprecherausgang ist, ebenso wie Chip Select, über den Arduino Sketch frei wählbar (hier PIN 9).

Zwei Blog Posts haben bei Verkabelung und Inbetriebnahme gut geholfen. Zum einen dieser Beitrag bei maxoffsky.com sowie insbesondere diese Anleitung auf instructables.com.

Format der SD Karte

Die verwendete SD-Library unterstützt prinzipiell die Dateisysteme FAT16 und FAT32. Es wird jedoch empfohlen, wenn möglich, FAT16 einzusetzen. Bei mir hat’s mit einer FAT32-formatierten SD-Karte nicht funktioniert, daher wollte ich sie “mal eben” auf FAT16 formatieren. Das geht auch mit MacOS Bordmitteln, ist aber etwas komplizierter, als erwartet. Dieser Post im Adafruit-Forum beschreibt den Weg in Englisch; hier in knappem Deutsch:

  1. SD-Karte in den Mac stecken.
  2. Terminal-Fenster öffnen. Bspw. mit CMD+Space, dort “terminal” tippen und Return.
  3. Geräte-ID finden. Dazu im Terminal df gefolgt von Return eingeben. Es erscheint eine Filesystem-Übersicht, die unter anderem die folgenden Informationen enthält. Ganz unten ist die SD-Karte “NO NAME” zu sehen. Wer auf Nummer sicher gehen will, gibt seiner Karte einen eindeutigen Namen. Dann kann man sie in dieser Übersicht schneller finden. Die in den folgenden Schritten benötigte Geräte-ID lautet /dev/disk3s1.
    Filesystem        Used Available Capacity   iused   ifree %iused  Mounted on
    /dev/disk1   909007896  65197032    94% 113689985 8149629   93%   /
    devfs              371         0   100%       642       0  100%   /dev
    map -hosts           0         0   100%         0       0  100%   /net
    map auto_home        0         0   100%         0       0  100%   /home
    /dev/disk3s1     20928   4172608     1%       512       0  100%   /Volumes/NO NAME
    
  4. SD-Karte unmounten (nicht auswerfen!). Im Terminal diskutil unmount /dev/disk3s1 gefolgt von Return eingeben. Dabei disk3s1 natürlich durch die eigene Geräte-ID ersetzen. Erfolgreiches unmounten wird bspw. mit Volume NO NAME on disk3s1 unmounted quittiert.
  5. FAT16 Filesystem auf SD-Karte schreiben. ACHTUNG! Der folgende Befehl löscht alle Daten auf dem Gerät. Wenn die Geräte-ID nicht die von der eingesteckten SD-Karte ist, sondern bspw. aus Versehen die der eingebauten Festplatte, dann wird diese gelöscht. U have been warned.
    Folgendes Kommando im Terminal eingeben und nicht vergessen die Geräte-ID anzupassen. newfs_msdos -F 16 /dev/disk3s1
    Ich habe alle Warnmeldungen, die der Befehl produziert hat, konsequent ignoriert und als Lohn der Mühe im Anschluß eine lauffähige FAT16-formatierte SD-Karte gehabt.

Format der WAVE Dateien

Die Library TMRpcm benötigt zum Abspielen die WAVE-Dateien im Format acht Bit, acht bis 32 kHz Sample Rate, mono. Im WIKI zur Library werden zwei Wege beschrieben, wie man iTunes oder Audacity verwenden kann, um aus dem musikalischen Quellmaterial das Zielformat zu generieren. Audacity ist prima, und so geht’s damit:

  1. Hauptmenü “Tracks”, dort “Stereo Track to Mono” wählen.
  2. Unten links die “Project Rate (Hz)” mit dem Popup auf 8000, 11025, 16000, 22050 oder 32000 setzen. Je niedriger die Sampling Rate, desto schlechter die Qualität.
  3. Hauptmenü “File”, dort “Export Audio…” und im File Selection Dialog unten als Format “Other uncompressed files” wählen. Dann “Options…” klicken und als Header “WAV (Microsoft)” sowie bei Encoding “Unsigned 8-bit PCM” wählen. OK.
  4. Datei mit “Save” speichern.

Dateinamen

Dateinamen müssen zwingend dem – aus alten MS-DOS Zeiten bekannten – 8.3-Format folgen, also maximal acht Zeichen für den Dateinamen gefolgt von Punkt und einer Endung mit drei Zeichen beispielsweise “NAME0001.EXT”. Der Dateiname kann kürzer als acht Zeichen sein, in keinem Fall aber länger. Die Wikipedia widmet dem 8.3 short filename (SFN) tatsächlich einen eigenen Artikel.

Arduino Sketch

Der folgende Sketch bindet zunächst die benötigten Libraries ein, definiert Chip Select- und Lautsprecherausgangs-PIN, initialisiert die SD-Karte mit SD.begin() und spielt im Erfolgsfall die Wave-Datei snakec16.wav direkt von der SD-Karte ab. Im Fehlerfall wird eine kurze Meldung über den seriellen Monitor ausgegeben.

Wenn alles läuft…

…dann sollte das in etwa so aussehen, wie in dem Video.

Musik © Snake Charmer (Synapsis) / CC BY-ND 4.0

Join the conversation!

    • Hallo Peter! Danke für die Blumen und den wichtigen Hinweis! Das sollte nicht so sein. Habe ich gerade korrigiert! Viele Grüße, Axel

    • Ahoi! Habe die Schaltung sowohl mit 4 als auch 8 Ohm Lautsprechern ausprobiert. Geht.
      Generell würde ich aber zur Verwendung eines kleinen Verstärkermoduls raten, bspw. sowas hier http://www.ebay.de/itm/LM386-200-Gain-Audio-Verstarker-Modul-Board-Arduino-/282104829385?hash=item41aec215c9:g:FDIAAOSwdzVXutKq
      Die kosten nicht die Welt und machen ausreichend krach. Ist natürlich, nach wie vor, kein Hifi, und falls du sowas in China orderst, würde ich gleich mehrere Module nehmen – da gibt es immer mal Blindgänger.

      • Hallo! Danke für diese super Anleitung! Ich würde aber gerne einen 80 Ohm Lautsprecher verwenden. Wie binde ich den Verstärker ein? Muss ich einfach den Transistor und den Widerstand entfernen und den Pluspol des Verstärkers an die 5V anschließen? Was mache ich mit dem Minuspol des Verstärkers?

        MfG

        • Hi Lars,
          ein achtzig(?) Ohm LS? Really? Bestimmt ein Typo. 😉 Schau’ Dir mal das Schaltbild in diesem Artikel http://zeropage.io/ribbattacking-bruce-lee-c64-game-tribute-and-homage/ an. Da habe ich so einen kleinen LM386-basierten Verstärker eingebaut. Der hat drei Eingänge: +5V und Masse ist klar und den Eingang für’s Tonsignal. Da geht der Speaker Pin (in meinem Sketch Pin 9) rein. Die beiden Ausgänge in den Lautsprecher.
          VGxl

  • Hallo! Super erklärt, bei mir funktioniert das ganze aber trotzdem noch nicht. Ich bekomme folgende Fehlermeldung:
    C:\Users\Elena\Documents\Arduino\musikkkk\musikkkk.ino: In function 'void setup()':

    C:\Users\Elena\Documents\Arduino\musikkkk\musikkkk.ino:16:25: warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]

    tmrpcm.play( "test" );

    Der Sketch wird trotzdem hochgeladen und Ich habe zu dem tmrpcm.play() noch ein Serial.println( “SD ok” ); eingebaut, welches in meinem Fall ausgegeben wird. Demnach muss das Lesen von der SD-Karte doch funktioniert haben, oder? Es wird trotzdem nichts über den Speaker ausgegeben. Den Speaker habe ich mit anderen Programmen getestet und der funktioniert dort einwandfrei. Ich habe für Testzwecke zwar erstmal nur einen piezo Speaker, aber das dürfte doch kein Problem sein, oder?

    Ich hoffe du kannst mir helfen, bin ein ziemlicher Anfänger und etwas aufgeschmissen…

    • Hallo ln(a),
      die Fehlermeldung beim Kompilieren weist Dich darauf hin, dass der implizite Cast “überholt” (deprecated) ist. Mag irgendwann vom Compiler nicht mehr unterstützt werden, aber jetzt ist es nur eine Warnung. Daher klappt auch der Upload auf den Arduino.
      Das ist also nicht die Ursache, warum es bei Dir nicht geht. Wenn “SD ok” ausgegeben wird, dann konnte er zumindest die SD Karte initialisieren. Das ist schonmal gut.
      Heisst Deine Wave-Datei auf der SD Karte wirklich nur “test”? Ohne Dateiendung?
      Viele Grüße
      Axel

Leave a Reply

Your email address will not be published. Required fields are marked *