Franzis Adventskalender für Arduino – Tag 24

In diesem Beitrag möchte ich mit dir das vierundzwanzigste und damit letzte Türchen des Franzis Adventskalender für Arduino öffnen.

Franzis Adventskalender für Arduino – Tag 24
Franzis Adventskalender für Arduino – Tag 24

Wenn wir nun das Türchen öffnen, finden wir einen Piezo Summer.

Mit diesem Bauelement können wir einfache Töne und sogar Lieder abspielen. Du findest mit einer einfachen Google Suche viele verschiedene Lieder, welche mit diesem gespielt / programmiert werden können.

In meinem Weihnachtsevent 2019 im JFZ Schöningen – „Löten eines Weihnachtsbaums mit Sound“ habe ich eine kleine Platine mit LEDs & Piezo Buzzer vorgestellt.

PCB Weihnachtsbaum
PCB Weihnachtsbaum

An diesen Beitrag möchte ich anknüpfen und dir zeigen, wie du das Lied Jingle Bells mit dem Piezo Summer am Arduino Nano programmierst und dabei die LEDs im Takt blinken lässt.

Aufbau der Schaltung

Für die heutige Schaltung benötigen wir vier LEDs mit Vorwiderstand, eine kleine Drahtbrücke sowie den Piezo Summer welcher sich hinter dem heutigen Türchen versteckte.

Programmieren

Zunächst möchte ich dir zeigen wie du einen Ton erzeugst.

Hier benötigen wir die Funktion tone aus der Arduino Referenz, diese gibt es in zwei Varianten.

Zum einen mit zwei Parameter:

tone(<Pin>, <Frequenz>)

und mit drei Parameter:

tone(<Pin>, <Frequenz>, <Dauer>)

Wobei bei der Funktion mit zwei Parameter wir den Ton mit der Funktion noTone selber abschalten / deaktivieren müssen. Die Funktion noTone hat nur einen Pin, welcher den Anschluss des Piezo Summers repräsentiert.

noTone(<Pin>)

Wollen wir jetzt mit einem kleinen Beispiel beginnen und einfach einige Töne über den Piezo Summer ausgeben.

//Piezo Summer am digitalen Pin D3 angeschlossen
#define piezoSummer 3

void setup() {
  //definieren das der Pin des angeschlossenen
  // Piezo Summer als Ausgang dient
  pinMode(piezoSummer, OUTPUT);
}

void loop() {
  //Eine Schleife von 400 Hz bis 1500 Hz
  for (int freq = 400; freq < 1500; freq++) {
    //Ausgeben eines Tones
    tone(piezoSummer, freq);
    //eine Pause von 50ms.
    delay(50);
    //Stoppen der Ausgabe des Tones
    noTone(piezoSummer);
    //eine Pause von 50ms.
    delay(50);

    //vereinfacht kann man diese 4 Zeilen schreiben:
    //tone(piezoSummer, freq, 50);
  }
}

Wenn wir nun diesen Code auf den Mikrocontroller überspielen und den Piezo Summer am Pin D3 angeschlossen haben, sollte eine Tonfolge zu hören sein.

Abspielen eines Liedes auf dem Piezo Summer

Wie erwähnt, können wir einfache Lieder auf den kleinen Piezo Summer abspielen. Dabei hat jeder Ton seine eigene Frequenz.

//gruene LED am digitalen Pin D2 angeschlossen
#define LED1 2
//rote LED am digitalen Pin D4 angeschlossen
#define LED2 4
//gelbe LED am digitalen Pin D6 angeschlossen
#define LED3 6
//orangfarbene LED am digitalen Pin D8 angeschlossen
#define LED4 8

//Array mit den LEDs sowie dem Status der LED
int leds[4][2] = { { LED1, LOW }, { LED2, LOW }, { LED3, LOW }, { LED4, LOW } };
//Intervall zum ändern eines Status der LED
//Wenn die LEDs öffters / schneller blinken sollen muss diese Variable kleiner werden ansonsten größer.
const int LED_ACTION_INTERVALL = 750;
//Variable zum speichern der letzten Ausführung.
long lastLedAction = 0;

//Piezo Buzzer am digitalen PWM Pin 3 angeschlossen
#define BUZZER 3

//Definieren der Töne
#define C 2100
#define D 1870
#define E 1670
#define f 1580
#define G 1400
#define R 0  //reset

//Melodie von Jingle Bells
const int jingleBellsMelody[] = { E, E, E, R, E, E, E, R, E, G, C, D, E, R, f, f, f, f, f, E, E, 
  E, E, D, D, E, D, R, G, R, E, E, E, R, E, E, E, R, E, G, C, D, E, R, f, f, f, f, f, E, E, E, G, G, f, D, C, R };
//Berechnen der Anzahl der Töne in der Melodie
const int MAX_COUNT = sizeof(jingleBellsMelody) / 2;
const int beat = 50;
const long tempo = 10000;
int rest_count = 100;
int pause = 1000;

void setup() {
  //Initialisieren der LEDs als Ausgänge und mit dem Status LOW (AUS)
  for (int i = 0; i < 4; i++) {
    pinMode(leds[i][0], OUTPUT);
    digitalWrite(leds[i][0], leds[i][1]);
  }

  //Setzen des Buzzer Pins als Ausgang
  pinMode(BUZZER, OUTPUT);
}

/**
 * Spielt die Melodie ab.
 */
void playTone(int tone_, long duration) {
  long elapsed_time = 0;
  //Wenn der Ton kein Reset ist dann...
  if (tone_ > 0) {
    //Prüfen ob die Zeit vom letzten ausführen eines LED blinkens kleiner als
    //die aktuelle Zeit + dem Intervall ist.
    if (lastLedAction < (millis() + LED_ACTION_INTERVALL)) {
      //speichern der aktuellen Zeit
      lastLedAction = millis();
      //erzeugen einer Zufallszahl von 0 bis 4
      int randomValue = random(4);
      //lesen des Status aus dem Array mit den LEDs
      int status = leds[randomValue][1];
      //Wenn der Status LOW / AUS ist dann soll er auf HIGH gewechselt werden.
      if (status == LOW) {
        leds[randomValue][1] = HIGH;
      } else {
        //Wenn der Status HIGH / AN ist dann soll auf LOW gewehcselt werden.
        leds[randomValue][1] = LOW;
      }
      //neues Auslesen des Status aus dem Array
      status = leds[randomValue][1];

      //Setzen der LED mit dem neuen Status
      digitalWrite(leds[randomValue][0], status);
    }

    //Abspielen der Melodie
    while (elapsed_time < duration) {
      //Buzzer an
      digitalWrite(BUZZER, HIGH);
      //Pause von der länge des Tones durch 2
      delayMicroseconds(tone_ / 2);
      // DOWN
      //Buzzer aus
      digitalWrite(BUZZER, LOW);
      //Pause von der länge des Tones durch 2
      delayMicroseconds(tone_ / 2);
      //Speichern wielange der Ton dauerte
      elapsed_time += (tone_);
    }
  } else {  // Reset
    for (int j = 0; j < rest_count; j++) {
      delayMicroseconds(duration);
    }
  }
}

void loop() {
  long duration = beat * tempo;  // Set up timing
  //Für jede Note aus der Melodie....
  for (int i = 0; i < MAX_COUNT; i++) {
    //lesen der Note i aus dem Array der Melodie
    playTone(jingleBellsMelody[i], duration);
    //Wenn die Melodie schneller abgespielt werden soll dann muss
    //die Variable für den beat sowie die pause angepasst werden.
    delayMicroseconds(pause);  // eine kleine Pause zwischen den Noten....
  }

  delay(500);
}

Wenn wir den Code auf den Mikrocontroller überspielen und ausführen, dann sollte das Lied Jingle Bells abgespielt werden und zusätzlich im Takt die LEDs leuchten.

Kommentar hinterlassen

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