Metronom mit Display und Speicher

Hallo zusammen,

Im Forum habe ich bisher noch keinen passenden Thread gefunden, deswegen hoffe ich hier richtig zu sein:

Ich bin ein absoluter Arduino-Neuling und möchte mir gerne für den Live-Einsatz am Schlagzeug ein Metronom bauen, da es leider kein Gerät gibt, dass meinen Anforderungen zu 100% entspricht.
Vllt könnt ihr mir Tipps geben, ob sich das ganze überhaupt realisieren lässt und ob ich das als Rookie hinbekomme.

Die Anforderungen sind folgende:

  • Metronom mit Klinkenausgang + Lautstärkeregler

  • Speicherbare Tempi mit Songtitel

  • Display, welches Tempo + Songtitel anzeigt

  • Play Button + Vor- und Zurückbutton

Tabfunktion, blinkende LEDs und weitere Funktionen sind nicht zwingend notwendig und würde ich später ergänzen, wenn ich mit der Kernlösung klar gekommen bin...

Würde mich über Tipps und Anregungen freuen :slight_smile:

Liebe Grüße und danke im Voraus,
Dionys

Das "Schwierigste" ist der Läutstärkeregler. Und, wenn du schon darauf Wert legst, der Klang des Metronom-Ticks. Und dann willst du sicher mehrere, damit das Metronom mindestens "ping - pok - pok -pok" sagen kann.

Unklar ist mir

  • Speicherbare Tempi mit Songtitel:
    Wie willst du den Songtitel speichern? Arduino neu programmieren / PC - Anschluss / Smartphone / ...

Was gehört zu einem Song? : Tempo / Takt / Dauer / Wechsel innerhalb des Songs ...

  • Play Button + Vor- und Zurückbutton:
    Vor/Zurück im Song (wenn zu einem Song mehr gehört als "72 BPM"), oder zum nächsten/vorigen Titel der Playlist?

Hallo Michael,

Vielen Dank für die schnelle Antwort!

Der Klang des Metronoms spielt natürlich eine Rolle, wobei ich keine „unterschiedlichen“ Sounds benötige, also ein Sound reicht. Verzeih mir die naive Frage, kann ich meinen Wunschsound als mp3 einspeichern?

Zu deinen Fragen:

1 ich würde das Metronom gerne als Standalone nutzen, also die Informationen im Gerät speichern und würde den PC / das Smartphone nur hinzu ziehen, wenn ein neuer Titel mit neuem Tempo hinzugefügt wird

2 zu einem Song gehören wirklich nur ein Tempo und der Songtitel, es gibt also keine bestimmte Dauer bzw Tempowechsel

3 die Buttons Vor und Zurück benötige ich lediglich zum Wechseln der Songs.

Lieben Gruß,
Dionys

Bei meinem MP3-Player habe ich die Songtitel von einer SD-Karte nachgeladen, weil sonst der Arduino-Speicher nicht reicht. Den SD-Karteninhalt kann man schön am PC bearbeiten, was Flexibilität bringt.

Dionys:
... kann ich meinen Wunschsound als mp3 einspeichern?

Nur mit einem zusätzlichen MP3-Player. Ob der verlinkte speziell für Dich geeignet ist, wäre noch zu klären.

Wenn ich das richtig sehe, geht es hier doch nicht darum einen längeren MP3-Sound abzuspielen. Bei einem Metronom muss ein sehr kurzer Soundschnipsel immer wieder im exakten Zeitraster ausgelöst werden. Ist wahrscheinlich eher so, wie der Glockensound bei meinem Bahnübergang, der bem Senken der Schranken regelmäßig ausgelöst wird. Da reicht ein mini-Soundmodul, wo die Sounds direkt auf dem Modul gespeichert sind. Da dürften auch die Zeitverzögerungen zwischen Auslöseimpuls und Abspielen des Sound wesentlch kleiner sein, was für ein Metronom ja wichtig ist.
Z.B. sowas in der Art. Ich denke mal HiFi Sound ist da nicht gefordert?
Das verlinkte Modul könnte sogar mehrere Schnipsel abspielen, die man dann entsprechend dem Takt auslösen könnte. Es gibt aber auch einfachere, dir nur einen Sound können.

Danke euch für die Antworten!

@MicroBahner, genau, es handelt sich nur um den kurzen Schnipsel, deswegen wird nicht zwingend ein großer Speicher benötigt, wobei die SD-Karten-Lösung von agmue zum Erstellen neuer Songs/Tempi am PC interessant sein könnte.

Da meine aktuelle Erfahrung mit Arduino 0% beträgt, bin ich am überlegen, ob ich mir ein Starter Kit zulege, und mich erst mal etwas in die Materie einarbeite, da ich noch überhaupt kein Gefühl dafür besitze, was da auf mich zukommt

Auch wenn dies das Arduino-Forum ist, so möchte ich die Möglichkeit eines Analog Digital Converters nicht unerwähnt lassen, wie ihn beispielsweise Teensys eingebaut haben. Teensy Audio Library Die Teensys lassen sich mit der Arduino-IDE programmieren.

Im Beispiel SamplePlayer sehe ich die Möglichkeit, in h-Dateien gewandelte wav-Dateien abzuspielen. Der Konverter wav2sketch wird mitgeliefert. Ich habe meinen Teensy 3.2 aus dem Keller geholt und das Beispiel mit sechs Sounds probiert. Hört sich ganz brauchbar an. Natürlich habe ich nicht die Ohren eines Musikers, aber für ein Geräusch des Metronoms sollte es genügen.

Dionys:
... ob ich mir ein Starter Kit zulege ...

Da ist zu viel Kram dabei, den Du nie benötigen wirst. Ein individuell zusammengestelltes Starter Kit wäre aber eine gute Idee.

Dionys:
... und mich erst mal etwas in die Materie einarbeite ...

Das ist die zweite gute Idee!

Nachtrag: Gerade habe ich was von "Smartphone" gelesen, da wäre der DAC des ESP32 möglicherweise eine gute Wahl, da man da gleich Blauzahn nutzen kann. Damit habe ich aber noch keine Erfahrung und dürfte für einen Anfänger auch ein dickes Brett sein.

agmue:
Da ist zu viel Kram dabei, den Du nie benötigen wirst. Ein individuell zusammengestelltes Starter Kit wäre aber eine gute Idee.

Doch, zum Lernen. Wenn mann das Lernen zu einseitig nach einem späteren Ziel ausrichtet, bleiben manche Erkenntnisse auf der Strecke, die man später doch noch braucht.

Gruß Tommy

Das schwierigste sehe ich da am Mensch-Maschine Interface.

Wie viele Songtitel willst du verwalten und wie willst du diese dann im konkreten Auswählen?

Nachdem du die Beispiele in der IDE durchgemacht hast, würde ich wie folgt weitermachen:

  • Tonausgabe mit zwei unterschiedlichen tone() für tik tok tok tok tik
  • Auswahl von Takt und Tempo mit einem Push-Encoder
  • Ausgabe von Text auf einem I2C LCD

und wenn das alles tut was es soll, dann mit den Songtitel und "schönem" Sound rummachen.

Richtig.
Erstmal erkennen, dass es mehrere Projekte sind, und klein anfangen.

Mein Vorschlag zum allerersten Start (nach Blink) :


Serial Kommunikation

Eingabe:
0 - Stop
1 - Start

    • schneller
    • langsamer

Ausgabe: nur beim Start und als Antwort auf ein Kommando : aktuelle Geschwindigkeit ( "72" )

Nach Start LED im gewünschten Takt aufblitzen lassen.


Dann kannst du schauen, wie es weiter gehen soll:

wahlweise und unabhängig voneinander

A) Sound auf den Klinkenstecker
B) Taster / Encoder
C) LCD-Anzeige

Ich danke euch für euren Input und starte mal mit Arduino. Wenn es zum Projekt kommt, werde ich hier etwas dokumentieren, wie ich voran komme.
Viele Grüße
Dio

Wenn Du Dich mit Texten beschäftigst, vermeide String, verwende stattdessen Felder vom Typ char, also char text[]={"blabla"};

Dann kommst Du auch nicht um die Verwendung von Zeigern herum. In C finde ich das recht umständlich gelöst, ist aber halt so.

Wenn Du Dich mit SD-Karten beschäftigst, verwende anstelle der Bibliothek SD mit 8.3-Konvention besser SdFat.

Nur so Tipps :slight_smile:

Da es mich gereizt hat, den Analog Digital Converter des Teensys 3.2 zusammen mit Tönen zu nutzen, habe ich mit dem Programm wav2sketch eine WAV-Datei mit Klickgeräusch konvertiert1) und einen kleinen Metronom-Sketch geschrieben. Das 20x4 LC-Display mit I2C-Schnittstelle (5 V) ist direkt mit dem Teensy (3,3 V) verbunden, was zumindest bei mir funktioniert. Besser wäre ein I2C-Levelshifter zu verwenden. Der Kopfhörer ist über einen Kondensator (10 µF) mit dem DAC-Pin verbunden. Mit zwei Tastern kann aus einem Feld die Taktgeschwindigkeit in BPM (Beats per minute) gewählt werden.

// getestet mit Teensy 3.2 und LCD 20x4
#include <Wire.h>
#include <hd44780.h> // include hd44780 library header file
#include <hd44780ioClass/hd44780_I2Cexp.h> // i/o expander/backpack class
hd44780_I2Cexp lcd; // auto detect backpack and pin mappings
#include <Audio.h>
#include "AudioSampleMetrobar1.h" // Metronome sounds https://www.rncbc.org/drupal/node/566 konvertiert mit wav2sketch
// Create the Audio components.  These should be created in the order data flows, inputs/sources -> processing -> outputs
AudioPlayMemory    sound0;
AudioOutputAnalog  dac;     // play to on-chip DAC
// Create Audio connections between the components
AudioConnection c1(sound0, 0, dac, 0);
const unsigned long debounceDelay = 50;

struct Beats {
  uint16_t bpm;
  char titel[21];
};

Beats beats[] = {
  //     12345678901234567890
  { 80, "Slow 80"},
  {100, "Fox 100"},
  {120, "Salsa 120"},
  {160, "Fast 120"}
};
const byte anzahlBeats = sizeof(beats) / sizeof(beats[0]);
uint32_t jetzt = millis();
byte startIndex = 1;

class Taster                            // Struktur mit Konstanten, Variablen und Methoden
{   const byte pin;
    const int8_t veraenderung;
    bool aktZustand, altZustand;
    unsigned long vorhin;
  public:
    Taster(const byte pin, const int8_t veraenderung): pin(pin), veraenderung(veraenderung), aktZustand(0), altZustand(0), vorhin(0) {}

    void init()
    { pinMode(pin, INPUT_PULLUP);
      aktZustand = digitalRead(pin);
      altZustand = aktZustand;
      vorhin = jetzt;
    }

    void run(byte &index)
    { altZustand = aktZustand;
      if (jetzt - vorhin >= debounceDelay)    // Entprellen
      { aktZustand = digitalRead(pin);        // Tasterzustände aktualisieren
        if (altZustand != aktZustand) vorhin = jetzt;
      }
      if (altZustand && !aktZustand)          // fallende Flanke
      { index++;
        index += veraenderung;
        if (index < 1) index = 1;
        if (index > anzahlBeats) index = anzahlBeats;
        index--;
      }
    }
};

Taster taster[]
{ // Taster-Pin, Veränderung
  {20, -1},
  {21, 1}
};

void anzeige(byte index)
{ if (index < anzahlBeats)
  { lcd.setCursor(0, 2);
    lcd.print(F("                    "));
    lcd.setCursor(0, 2);
    lcd.print(beats[index].bpm);
    lcd.print(F(" BPM"));
    lcd.setCursor(0, 3);
    lcd.print(F("                    "));
    lcd.setCursor(0, 3);
    lcd.print(beats[index].titel);
  }
}

void click(uint16_t bpm) {
  static uint32_t vorher = jetzt;
  if (bpm && (jetzt - vorher >= 60000UL / bpm)) {
    digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
    vorher = jetzt;
    sound0.play(AudioSampleMetrobar1);
  }
}

void loop() {
  static byte aktIndex = startIndex;
  byte altIndex = aktIndex;
  jetzt = millis();
  for (Taster &t : taster) t.run(aktIndex);
  if (altIndex != aktIndex) anzeige(aktIndex);
  click(beats[aktIndex].bpm);
}

void setup() {
  pinMode (LED_BUILTIN, OUTPUT);
  for (Taster &t : taster) t.init();
  AudioMemory(1);  // Audio connections require memory to work.  For more detailed information, see the MemoryAndCpuUsage example
  //dac.analogReference(INTERNAL);  // by default the Teensy 3.1 DAC uses 3.3Vp-p output if your 3.3V power has noise, switching to the internal 1.2V reference can give you a clean signal
  lcd.begin(20, 4);
  lcd.setCursor(0, 0);
  lcd.print(F("Metronom"));
  lcd.setCursor(0, 1);
  lcd.print(F("Viel Erfolg!"));
  anzeige(startIndex);
}

Anm.:

  1. siehe Anhang

AudioSampleMetrobar1.cpp (25.2 KB)

AudioSampleMetrobar1.h (110 Bytes)