Construye una jukebox con tonos de llamada RTTTL

FunduinoÚltima actualización el

Klingeltöne im RTTTL-Format per Tastenpad auswählen und abspielen

Mit einem Lautsprecher, einem analogen Tastenpad und einem I²C-LCD baust du eine kleine Jukebox. Jede Taste startet ein anderes Musikstück, und das Display zeigt Interpret und Titel an.

Die Melodien liegen im RTTTL-Format vor, das Nokia für die Klingeltöne seiner Handys entwickelt hat. Abgespielt werden sie mit der Bibliothek PlayRtttl.

Schaltplan: Lautsprecher an Pin 7, Tastenpad an A0, I²C-LCD an SDA und SCL

RTTTL-Klingeltöne

Nokia hat für seine Mobiltelefone Klingeltöne entwickelt, die zum Beispiel als Anrufsignal abgespielt wurden. Der daraus entstandene Standard RTTTL (Ring Tone Text Transfer Language) besteht aus drei Teilen:

  • dem Namen des Klingeltons
  • der Standarddauer der Noten und der verwendeten Oktave
  • den durch Kommas getrennten Noten in internationaler Notenbezeichnung (c, d, e, f, g, a, b)

Ein Doppelpunkt trennt die drei Teile voneinander. Als Beispiel der Anfang des Te Deum:

TeDeum:d=4,o=5,b=63:8c,8f,16f,16g,8a

  • d=4: Die Standardlänge einer Note ist eine Viertelnote.
  • o=5: Die Noten werden in der fünften Oktave gespielt.
  • b=63: Das Tempo beträgt 63 Schläge pro Minute.
  • 8c: Die Note C wird als Achtelnote gespielt.

Klingeltöne zum Herunterladen findest du bei PICAXE.

In der internationalen Notenbezeichnung steht b für den Ton, den du im Deutschen als h kennst.

Benötigte Bauteile

Mit den Tasten eines Tastenpads wählst du einen Titel aus. Das LCD zeigt den Titel an, und der Lautsprecher spielt ihn ab. Dafür brauchst du:

Ist dir der Lautsprecher zu laut, kannst du die Lautstärke mit einem Widerstand verringern, wie im zweiten Bild gezeigt.

Der Sketch ist für ein LCD mit vier Zeilen zu je 20 Zeichen geschrieben. Mit einem zweizeiligen 1602-Display fehlen die Zeilen 3 und 4 der Anzeige, also der Titel und ein Teil des Menüs.

Verschiedene Lautsprecher, die für die Jukebox geeignet sind
Beispiele für Lautsprecher
Anschluss des Lautsprechers mit einem Widerstand zur Lautstärkeminderung
1 / 2

Der Schaltplan

Schließe die Bauteile wie im Schaltplan an. Der Lautsprecher hängt an Pin 7, das Tastenpad am analogen Eingang A0. Das LCD ist über den I²C-Bus angeschlossen.

Schaltplan: Lautsprecher an Pin 7, Tastenpad an A0, I²C-LCD an SDA und SCL

Benötigte Bibliotheken installieren

Klicke in der Arduino IDE auf das Symbol Bibliothek und suche im Bibliotheksverwalter nach der Bibliothek LiquidCrystal I2C. Installiere sie und suche anschließend nach der Bibliothek PlayRtttl.

Die Bibliothek LiquidCrystal I2C im Bibliotheksverwalter
Die Bibliothek PlayRtttl im Bibliotheksverwalter
1 / 2

Bibliotheken einbinden und Variablen definieren

Zu Beginn bindest du die beiden Bibliotheken ein und legst das LCD mit der Adresse 0x27 und 20 Zeichen in 4 Zeilen an. Der Lautsprecher hängt an Pin 7.

Die vier Musikstücke stehen als char-Arrays im RTTTL-Format im Sketch. Vor dem ersten Doppelpunkt stehen Interpret und Titel, getrennt durch einen Schrägstrich. Unterstriche stehen dabei für Leerzeichen.

Der Kommentar „Pin des Kautsprechers“ meint den Lautsprecher. Bleibt das Display später leer, hat dein Modul möglicherweise die Adresse 0x3F statt 0x27.

Bibliotheken einbinden und Variablen definieren
#include "PlayRtttl.hpp"
#include "LiquidCrystal_I2C.h"
// Name des LCDs (lcd) festlegen
LiquidCrystal_I2C lcd(0x27, 20, 4);
// Pin des Kautsprechers
#define Lautsprecher  7
// Variable für die gedrückte Taste des Tastenpads
int GedrueckteTaste;
String TitelSong;
char TeDeum[] =
"Charpentier/Te_Deum:d=4,o=5,b=63:8c,8f,16f,16g,8a,8f,c6,8a,8a,8a#,16c6,16a#,16a,16a#,8c6,16g,16f,16g,16a,8g,8c,8f,16f,16g,8a,8f,c6,8a,8a,16a#,16c6,16a,16a#,g,16f,2f";
char FuerElise[] =
"Beethoven/Für_Elise:d=8,o=5,b=125:32p,e6,d#6,e6,d#6,e6,b,d6,c6,4a.,32p,c,e,a,4b.,32p,e,g#,b,4c.6,32p,e,e6,d#6,e6,d#6,e6,b,d6,c6,4a.,32p,c,e,a,4b.,32p,d,c6,b,2a";
char OdeandieFreude[] =
"Beethoven/Ode_an_die_Freude:d=4,o=6,b=100:a5,a5,a_5,c,c,a_5,a5,g5,f5,f5,g5,a5,a.5,8g5,2g5,";
char Bolero[] =
"Ravel/Bolero:d=4,o=5,b=80:c6,8c6,16b,16c6,16d6,16c6,16b,16a,8c6,16c6,16a,c6,8c6,16b,16c6,16a,16g,16e,16f,2g,16g,16f,16e,16d,16e,16f,16g,16a,g,g,";

Der setup-Teil

Im setup-Teil startest du das LCD und schaltest seine Hintergrundbeleuchtung ein.

Der setup-Teil
void setup()
{
  // LCD starten
  lcd.init();
  // Hintergrundbeleuchtung des LCDs einschalten
  lcd.backlight();
}

Das Tastenpad abfragen

Im loop-Teil fragst du mit analogRead ab, welche Taste des analogen Keyboards gedrückt ist. Das Tastenpad hängt am Eingang A0. Die analogen Eingänge liefern Werte zwischen 0 und 1023. Je nach gedrückter Taste ergeben sich die Werte aus dem Bild.

Eine switch-case-Abfrage weist jedem Wertebereich eine Aktion zu. Das erste Beispiel zeigt die Abfrage der linken Taste: case 0 ... 20 fragt den Wertebereich zwischen 0 und 20 ab. Die übrigen Wertebereiche weist du entsprechend zu. Beachte das Leerzeichen vor und hinter den drei Punkten!

Das zweite Beispiel zeigt den vollständigen loop-Teil. Die rechte äußere Taste zeigt ein Menü mit allen vier Titeln an.

Das erste Beispiel ruft ZeigeTitel(TitelSong) mit einem Argument auf. Die Funktion erwartet aber keins, richtig ist ZeigeTitel() wie im vollständigen loop-Teil.

Die Analogwerte der fünf Tasten des Tastenpads
Beispiel: Abfrage der linken Taste
// analogen Wert an A0 abfragen
int Analogwert = analogRead(A0);
switch (Analogwert)
{
  case 0 ... 20:
      // char-Array des Titels in String umwandeln
      TitelSong = String(TeDeum);
      // Funktion aufrufen, Interpret/Titel extrahieren
      ZeigeTitel(TitelSong);
      // Titel spielen
      playRtttlBlocking(Lautsprecher, TeDeum);
      break;
}
Der vollständige loop-Teil
void loop()
{
  // Tastenpad am Eingang A0 abfragen
  int Analogwert = analogRead(A0);
  switch (Analogwert)
  {
    // linke Taste;
    case 0 ... 20:
      // char-Array des Titels in String umwandeln
      TitelSong = String(TeDeum);
      // Funktion aufrufen, Interpret/Titel extrahieren
      ZeigeTitel();
      // Titel spielen
      playRtttlBlocking(Lautsprecher, TeDeum);
      break;
    // obere Taste
    case 30 ... 60:
      TitelSong = String(FuerElise);
      ZeigeTitel();
      playRtttlBlocking(Lautsprecher, FuerElise);
      break;
    // rechte Taste
    case 70 ... 120:
      TitelSong = String(OdeandieFreude);
      ZeigeTitel();
      playRtttlBlocking(Lautsprecher, OdeandieFreude);
      break;
    // untere Taste
    case 150 ... 200:
      TitelSong = String(Bolero);
      ZeigeTitel();
      playRtttlBlocking(Lautsprecher, Bolero);
      break;
    // rechte äußere Taste -> Menü anzeigen
    case 300 ... 400:
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("1: Te Deum");
      lcd.setCursor(0, 1);
      lcd.print("2: F\365r Elise");
      lcd.setCursor(0, 2);
      lcd.print("3: Ode an die Freude");
      lcd.setCursor(0, 3);
      lcd.print("4: Bolero");
      break;
  }
}

Die Funktion ZeigeTitel

Der loop-Teil ruft die Funktion ZeigeTitel auf. Sie zerlegt den String TitelSong in den Namen des Interpreten und den Namen des Titels:

  • TitelSong = TitelSong.substring(0, TitelSong.indexOf(":")); – indexOf sucht den ersten Doppelpunkt, substring schneidet den Teil vom ersten Zeichen (0) bis zum Doppelpunkt heraus.
  • TitelSong.replace("_", " "); – ersetzt alle Unterstriche durch Leerzeichen.
  • String Interpret = TitelSong.substring(0, TitelSong.indexOf("/")); – die Zeichen von 0 bis zum Schrägstrich enthalten den Namen des Interpreten.
  • String Titel = TitelSong.substring(TitelSong.indexOf("/") + 1, TitelSong.length()); – der zweite Teil beginnt mit dem Zeichen hinter dem Schrägstrich (+1) und endet mit der Länge des Strings (length). Er enthält den Titel.

Anschließend zeigt die Funktion „Spiele:“, den Interpreten und den Titel in den ersten drei Zeilen des LCDs an.

Die Funktion ZeigeTitel
void ZeigeTitel()
{
  // Teil des Strings bis zum ersten Doppelpunkt kürzen, enthält die Informationen zu Interpret und Titel
  TitelSong = TitelSong.substring(0, TitelSong.indexOf(":"));
  // _ durch leerzeichen ersetzen
  TitelSong.replace("_", " ");
  // erster Teil des Strings bis zum / -> Name des Interpreten
  String Interpret = TitelSong.substring(0, TitelSong.indexOf("/"));
  // zweiter Teil des Strings vom / + 1 bis zum Ende des Strings -> Name des Titels
  String Titel = TitelSong.substring(TitelSong.indexOf("/") + 1, TitelSong.length());
   // Titel auf dem LCD anzeigen
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Spiele:");
  lcd.setCursor(0, 1);
  lcd.print(Interpret);
  lcd.setCursor(0, 2);
  lcd.print(Titel);
}
Calificar la guía

Comentarios

Haz una pregunta o comparte tu experiencia

Schreib uns, wenn etwas nicht funktioniert. Nenne dabei dein Board und die Fehlermeldung.

Revisamos cada comentario antes de publicarlo. Tu dirección de correo electrónico permanece con nosotros.