Rhythmus mit Arduino

Wenn es in der Musik um gegeneinander (oder miteinander) laufende Rhythmen geht (Polyrhythmik), dann tuen sich etlichen Menschen hart, den einzelnen Rhythmen zu folgen. Die folgende Schaltung und Programmierung soll eine kleine Hilfestellung sein für zwei oder mehrere gleichzeitig laufende Rhythmen ein Gefühl zu bekommen.

Verwendete Bauteile

(Hier richtet sich N nach der Anzahl der gebauten Rhythmus-Module)

Aufbau

Im folgenden Schaltplan ist ein sog. Rhythmus-Modul verbaut, welches aus einem Mikrotaster mit Pulldown-Widerstand, einer LED mit Vorwiderstand und einem Piezo-Buzzer besteht. Für Polyrhythmik werden mindestens zwei dieser Rhythmus-Module benötigt. Hierbei ist nur darauf zu achten, dass die Piezo-Buzzer an einem Pin mit PWM anzuschließen sind.
Zusätzlich ist noch ein Potentiometer verbaut, welches die Gesamtgeschwindigkeit regelt.

Schaltplan mit einem Rhythmus-Modul
Abb.: Schaltplan mit Arduino einem exemplarischen Rhythmus-Modul.

Für das praktische Beispiel im Folgenden habe ich drei Rhythmus-Module verwendet mit jeweils unterschiedlich farbigen LEDs.

Aufbau mit drei Modulen auf dem Breadboard
Abb.: Aufbau mit drei Modulen auf dem Breadboard.

Programmierung

Im folgenden Arduino-Sketch werden die (hier: drei) Rhythmus-Module an verschiedenen Pins angeschlossen und mit unterschiedlichen Rhythmen programmiert. Das baseDelay gibt die Pausenzeit in Millisekunden zwischen den Schlägen des Rhythmus an. Will man also eine 2-zu-3-Rhythmik einstellen, so wählt man 20ms und 30ms. Natürlich können auch Vielfache dieser Werte gewählt werden. Durch das Drehen am Potentiometer werden diese Delays multipliziert (1× bis 30×).
Durch das Drücken der jeweiligen Mikrotaster wird der entsprechende Rhythmus an- bzw. ausgeschaltet. So kann man auch selbst kombinieren.

#define NUM_MODULES 3
#define POTENTIOMETER_PIN  A5
#define lmillis() ((long)millis())
#define DEBOUNCE_TIME 100 // in milliseconds

struct RhythmModule {
   byte isEnabled;
   byte pinLed;
   byte pinPiezo;
   byte pinButton;
   long lastAction;
   unsigned int baseDelay;  // in milliseconds
   unsigned int pauseDelay; // in milliseconds
};

RhythmModule modules[] = {
   {true, A0,  9, 5, 0, 20, 0},
   {true, A1, 10, 6, 0, 30, 0},
   {true, A2, 11, 7, 0, 50, 0}
};

void setup()
{
   for (byte i = 0; i < NUM_MODULES; i++) {
      pinMode(modules[i].pinLed, OUTPUT);
      digitalWrite(modules[i].pinLed, LOW);
      pinMode(modules[i].pinPiezo, OUTPUT);
   }
}

void loop()
{
   for (byte i = 0; i < NUM_MODULES; i++) {
      byte multiplier = map(analogRead(POTENTIOMETER_PIN), 0, 1024, 1, 30);
      modules[i].pauseDelay = modules[i].baseDelay * multiplier;

      if (buttonPressed(modules[i].pinButton)) {
         modules[i].isEnabled = !modules[i].isEnabled;
      }

      if (lmillis() - modules[i].lastAction >= 0) {
         if (modules[i].isEnabled) {
            digitalWrite(modules[i].pinLed, !digitalRead(modules[i].pinLed));
            tone(modules[i].pinPiezo, 440);
            delay(1);
            noTone(modules[i].pinPiezo);
         } else {
            digitalWrite(modules[i].pinLed, LOW);
            noTone(modules[i].pinPiezo);
         }
         modules[i].lastAction += modules[i].pauseDelay;
      }
   }
}

byte buttonPressed(byte pin)
{
   static long lastButtonClick = 0;
   if ((lmillis() - lastButtonClick) < DEBOUNCE_TIME) {
      return false;
   }
   lastButtonClick = lmillis();
   return (digitalRead(pin) == HIGH);
}

Resultat

Demo des 3fach-Polyrhythmik-Programms (4,5MB).
zurück