Projekt DFMp3player Mini

Ja.
Hiermit, - basierend auf meinem ins blaue geschriebene von gestern, kannst Du mal anfangen.

Ganz langsam.
Du kommst schon noch dahin, das Dir noch mehr einfällt :wink:
[EDIT!]
Im elseZweig fehlte was - hab ich noch mit reinkopiert
[/EDIT!]

// Forensketch basiert auf https://forum.arduino.cc/t/projekt-dfmp3player-mini/904529/4
// Unter Berücksichtigung von https://forum.arduino.cc/t/projekt-dfmp3player-mini/904529 und 
// https://forum.arduino.cc/t/projekt-dfmp3player-mini/904529/3 sowie aktueller Kenntnisstand
// Ungetestet - kompiliert fehlerfrei
#include "SoftwareSerial.h"
#include "DFRobotDFPlayerMini.h"
//---------------------------------------------------
SoftwareSerial mysoftwareSerial(10, 11);
DFRobotDFPlayerMini myDFPlayer;
//===========================================================
void setup()
{
  pinMode(2, INPUT); pinMode(3, INPUT); pinMode(4, INPUT);
  pinMode(5, INPUT); pinMode(6, INPUT); pinMode(7, INPUT);
  pinMode(8, INPUT); pinMode(9, INPUT);
  pinMode(12, INPUT); pinMode(12, INPUT);
  //---------------------------------------------------
  mysoftwareSerial.begin(9600);
  Serial.begin(115200);
  Serial.println();
  Serial.println(F("DFRobot DFPlayer Mini Demo"));
  Serial.println(F("Initializing DFPlayer ... (May take 3~5 seconds)"));
  if (!myDFPlayer.begin(mysoftwareSerial))   //Use softwareSerial to communicate with mp3.
  {
    Serial.println(F("Unable to begin:"));
    Serial.println(F("1.Please recheck the connection!"));
    Serial.println(F("2.Please insert the SD card!"));
    while (true);
  }
  Serial.println(F("DFPlayer Mini online."));
  myDFPlayer.volume(15); //Set volume value. From 0 to 30
  myDFPlayer.pause(); //Play the first mp3
  myDFPlayer.EQ(DFPLAYER_EQ_POP);
}
//===========================================================
void loop()
{
  static bool tasteGedrueckt = false;
  if (tasteGedrueckt == false)
  {
    if (digitalRead(4) == HIGH)
    {
      tasteGedrueckt = true;
      myDFPlayer.play(1);
    }
    else if (digitalRead(5) == HIGH)
    {
      tasteGedrueckt = true;
      myDFPlayer.play(2);
    }
    else if (digitalRead(6) == HIGH)
    {
      tasteGedrueckt = true;
      myDFPlayer.play(3);
    }
    else if (digitalRead(7) == HIGH)
    {
      tasteGedrueckt = true;
      myDFPlayer.play(4);
    }
    else if (digitalRead(8) == HIGH)
    {
      tasteGedrueckt = true;
      myDFPlayer.play(5);
    }
    else if (digitalRead(9) == HIGH)
    {
      tasteGedrueckt = true;
      myDFPlayer.play(6);
    }
    else if (digitalRead(2) == HIGH)
    {
      tasteGedrueckt = true;
      myDFPlayer.play(7);
    }
    else if (digitalRead(3) == HIGH)
    {
      tasteGedrueckt = true;
      myDFPlayer.play(8);
    }
  }
  else
  {
    tasteGedrueckt = false;
    for (byte i = 2; i < 8; i++)
    {
      if (digitalRead(i) == HIGH)
        tasteGedrueckt = true;
    }
  }  if (digitalRead(13) == HIGH) myDFPlayer.volumeUp();
  else if (digitalRead(12) == HIGH) myDFPlayer.volumeDown();
  //---------------------------------------------------
}

Das geht besser, aber einem Mechaniker Bedingungen vorzulegen halte ich für Erfolg versprechend. :slight_smile:

1 Like

Der Geburtstag von meinem Sohn ist gerettet :-). Wärst du so freundlich mir Kommentare zu den Schritten einzufügen? Dann kann ich das Versuchen nachzuvollziehen.

Der Mechaniker ist besser im Bereich CNC und Zerspanung :slight_smile:

Vielen DAnk

Wärest Du bereit das wenigstens ein wenig runtergekürzt mitzulernen?

Ja klar, ich möchte hier lernen und besser werden

Las mir kurze Zeit. - ich bau mal was.

Hier klappt es nicht, alle anderen funktionieren

Ja, weil ich einen zuwenig abfrage.
Kommt im nachfolgenden Code.....

Hab ich mal gemacht. Schon ein weinig umgebaut.
Alle Kommentare im Code.
Bitte einmal durch und versuchen zu verstehen, warum das so ist.
Frage, wenn Du Fragen hast.
Bitte nicht alle einzeln :wink:

Wenn Du das durch hast und mir sagst, wo Du eine Möglichkeit vermutest durch einfaches zählen abzukürzen, kommt eine verkürzte Variante.
:wink:

#include "SoftwareSerial.h"
#include "DFRobotDFPlayerMini.h"
//---------------------------------------------------
SoftwareSerial mysoftwareSerial(10, 11);
DFRobotDFPlayerMini myDFPlayer;

// InputPins unbedingt bezeichnen - wie die heissen ist egal,
// es sollte aus dem Namen herauszulesen sein, was der Pin macht
// Jeder Pin soll eine Funktion ausführen, so ist das relativ einfach:
// Ein PIN kann sich nicht verändern. Darum wird er const!
// Ein byte ist die kleinste Größe wo eine PinNummer rein passt
// Wenn Du jetzt den PIN änderst, ist er im ganzenProgramm geändert
// Du brauchst also nicht weiter suchen.... - Vergleiche mit Deinem Code ;)
const byte titel1Pin = 4;  // Hier ist sortiert nach den Titeln
const byte titel2Pin = 5;
const byte titel3Pin = 6;
const byte titel4Pin = 7;
const byte titel5Pin = 8;
const byte titel6Pin = 9;
const byte titel7Pin = 2;
const byte titel8Pin = 3;

const byte volumeUpPin = 12;  // das sollte klar sein
const byte volumeDownPin = 13;

// Das geht eindeutig besser - wenn Du das durch hast und verstanden,
// mach ich das kürzer - aber erstmal Grundlagen.

void setup()
{
  // Hier siehst Du, wie die Variablen verwendet werden
  // Das ist aber aufwendig und schreibintensiv
  // inkl. Fehlermöglichkeiten.
  pinMode(titel1Pin, INPUT); pinMode(titel2Pin, INPUT); pinMode(titel3Pin, INPUT);
  pinMode(titel4Pin, INPUT); pinMode(titel5Pin, INPUT); pinMode(titel6Pin, INPUT);
  pinMode(titel7Pin, INPUT); pinMode(titel8Pin, INPUT);
  pinMode(volumeUpPin, INPUT); pinMode(volumeDownPin, INPUT);
  //---------------------------------------------------
  mysoftwareSerial.begin(9600);
  Serial.begin(115200);
  Serial.println();
  Serial.println(F("DFRobot DFPlayer Mini Demo"));
  Serial.println(F("Initializing DFPlayer ... (May take 3~5 seconds)"));
  if (!myDFPlayer.begin(mysoftwareSerial))   //Use softwareSerial to communicate with mp3.
  {
    Serial.println(F("Unable to begin:"));
    Serial.println(F("1.Please recheck the connection!"));
    Serial.println(F("2.Please insert the SD card!"));
    while (true);
  }
  Serial.println(F("DFPlayer Mini online."));
  myDFPlayer.volume(15); //Set volume value. From 0 to 30
  myDFPlayer.pause(); //Play the first mp3
  myDFPlayer.EQ(DFPLAYER_EQ_POP);
}
//===========================================================
void loop()
{
  // Die Variable tasteGedrueckt ist ein Merker, ob ein Tastendruck ausgelöst wurde
  // static bedeutet, das der Inhalt der Variable erhalten bleibt,
  // bis die Funktion erneut aufgerufen wird
  static bool tasteGedrueckt = false;
  if (tasteGedrueckt == false)                     // Wenn MERKER nicht ausgelöst ...
  {
    if (digitalRead(titel1Pin) == HIGH)            // frage jede einzelne Taste ab
    {
      tasteGedrueckt = true;                       // wenn Taste gedrückt merke es
      myDFPlayer.play(1);                          // und spiele den Titel
    }
    else if (digitalRead(titel2Pin) == HIGH)       // - das geht jetzt so weiter
    {
      tasteGedrueckt = true;
      myDFPlayer.play(2);
    }
    else if (digitalRead(titel3Pin) == HIGH)
    {
      tasteGedrueckt = true;
      myDFPlayer.play(3);
    }
    else if (digitalRead(titel4Pin) == HIGH)
    {
      tasteGedrueckt = true;
      myDFPlayer.play(4);
    }
    else if (digitalRead(titel5Pin) == HIGH)
    {
      tasteGedrueckt = true;
      myDFPlayer.play(5);
    }
    else if (digitalRead(titel6Pin) == HIGH)
    {
      tasteGedrueckt = true;
      myDFPlayer.play(6);
    }
    else if (digitalRead(titel7Pin) == HIGH)
    {
      tasteGedrueckt = true;
      myDFPlayer.play(7);
    }
    else if (digitalRead(titel8Pin) == HIGH)
    {
      tasteGedrueckt = true;
      myDFPlayer.play(8);
    }
  }
  else                                                // ... MERKER ausgelöst (siehe oben!)
  {
    tasteGedrueckt = false;                           // dann initialisiere erstmal mit false
    for (byte i = titel7Pin; i < titel6Pin; i++)      // frage alle Tasten durch (Achtung! FALLE - das erklär ich später)
    {
      if (digitalRead(i) == HIGH)                     // Wenn eine der Tasten gedrückt ist
        tasteGedrueckt = true;                        // wird der Merker wieder gesetzt
    }
  }
  // Hier habe ich schon mal getauscht.
  // Grund: Wenn DOWN gedrückt ist, wird UP nicht mehr abgefragt
  // Wenn beide Tasten gedrückt sind, wird es IMMER leiser - nie lauter
  if (digitalRead(volumeDownPin) == HIGH) myDFPlayer.volumeDown();
    else if (digitalRead(volumeUpPin) == HIGH) myDFPlayer.volumeUp();
}
1 Like

Hallo,
das wäre jetzt mein Vorschlag. Das mit dem einen Merker muss ich zurück nehmen , ein Array solle es aber tun :wink:

nicht getestet.

#include "SoftwareSerial.h"
#include "DFRobotDFPlayerMini.h"
//---------------------------------------------------
SoftwareSerial mysoftwareSerial(10, 11);
DFRobotDFPlayerMini myDFPlayer;

const byte btnpin[] {2, 3, 4, 5, 6, 7, 8, 9};
const byte btnvolup = 12;
const byte btnvoldown = 13;
const byte max = sizeof(btnpin) / sizeof(btnpin[0]);
bool merker[max];
//===========================================================
void setup() {
  for ( byte i = 0; i < max; i++) {
    pinMode(btnpin[i], INPUT);
  }
  pinMode(btnvolup, INPUT);
  pinMode(btnvoldown, INPUT);
  //---------------------------------------------------
  mysoftwareSerial.begin(9600);
  Serial.begin(115200);

  Serial.println();
  Serial.println(F("DFRobot DFPlayer Mini Demo"));
  Serial.println(F("Initializing DFPlayer ... (May take 3~5 seconds)"));

  if (!myDFPlayer.begin(mysoftwareSerial)) { //Use softwareSerial to communicate with mp3.
    Serial.println(F("Unable to begin:"));
    Serial.println(F("1.Please recheck the connection!"));
    Serial.println(F("2.Please insert the SD card!"));
    while (true);
  }
  Serial.println(F("DFPlayer Mini online."));

  myDFPlayer.volume(15); //Set volume value. From 0 to 30
  myDFPlayer.pause(); //Play the first mp3
  myDFPlayer.EQ(DFPLAYER_EQ_POP);
}
//===========================================================
void loop()
{

  for (byte i = 0; i < max; i++) {
    if (digitalRead(btnpin[i]) == HIGH && merker[i] == false) {
      merker[i] = true;
      myDFPlayer.play(i + 1);
      Serial.print("play Titel ");Serial.println(i);
    }
  }
  for (byte i = 0; i < max; i++) { //reset merker 
    if (digitalRead(btnpin[i]) == LOW) merker[i] = false;
  }



  if (digitalRead(btnvolup) == HIGH) myDFPlayer.volumeUp();
  if (digitalRead(btnvoldown) == HIGH) myDFPlayer.volumeDown();

  //---------------------------------------------------

}
1 Like

Ich danke dir und werde jetzt Schritt für Schritt lesen und versuchen alles nachzuvollziehen. Deine Hilfsbereitschaft ist wirklich super. Ich gebe dir Morgen ein Feedback in wie weit ich alles verstanden habe.

Schönen Abend

Auch dein Sketch werde ich testen

so'n bissl vorgegriffen :wink:

Warum?
Es reicht doch zu wissen das keine oder eine Taste gedrückt ist :wink:

Hallo,
das das stimmt , das war auch mein erster Ansatz. Allerdings hab ich mir dann einen abgebrochen den einen Merker in der zweiten Schleife wieder zurück zu setzten. Das ist dann mit den andren Eingängen nicht verundet. Da schien mir das dann einfacher. Man müsste noch mal drüber nachdenken :sweat:

wahrscheinlich muss man die if Bedingung mit dem && auseiander nehmen.
Gruß Heinz

Wäre bitSet() eine Idee? Dann hast Du alle Bits in einer Variablen.

Ja, aber überflüssig :wink:
Ich brauche nur ein bit. Grundlage ist #16
@Rentner war schon sehr gut bei. Wir sind nicht weit auseinander :wink:

Hallo,

ja , sowas hatte ich auch überlegt , so ist das halt mit Rom :wink: und dem Weg dahin.

Gruß Heinz

Der Bereich ist für mich gut nachzuvollziehen. Struktur macht einem definitiv das Programmieren leichter.

Hier verstehe ich nicht genau was im Sketch passiert.

Das ist gut.
Damit ist das abgehakt :wink:

Ok. Ich versuch es mal zu erklären. Ich hatte ja schon im Kommentar drin, das das eine Falle ist.

ICH habe erkannt, das Du von DigitalPin 2 bis DigitalPin 9 jeden Pin benutzt um einen Titel auszuwählen.
Dabei ist titel7Pin der digitale Pin 2 und titel6Pin der digitale Pin 9
(Sobald auch nur ein PIN eine andere Funktion hätte, würde das nicht mehr funktionieren)
Was passiert jetzt im else-Zweig?
Ich setzte die Variable tasteGedrueckt auf false.
Danach zähle ich alle Pins (von 2 bis 9) durch und lese jeden einzelnen Pin digital aus und frage ab, ob er gesetzt ist:
if (digitalRead(i) == HIGH)
Sobald ein einziger Pin HIGH ist, wird die Variable tasteGedrueckt ebenfalls gesetzt.
tasteGedrueckt = true;

Nehmen wir an, Pin 2 wäre HIGH. Damit ist tasteGedrueckt bereits hier true.
Die Schleife fragt alle weiteren Pins ab. Wenn ein Pin LOW ist, ändert sich nichts. Wenn ein (weiterer) Pin HIGH ist, ändert sich eigentlich auch nichts. Der Zustand ist true.

Jetzt das Ganze, wenn Pin 8 HIGH ist.
Es ist das gleiche Prinzip.
Die For-Schleife läuft bis Pin 7 durch. Bis dahin ist keine gedrueckte Taste erkannt - das ändert sich mit Pin 8.
Also sobald auch nur einmal erkannt wird, das eine Taste gedrückt ist, passiert eigentlich nichts.
Erst wenn ALLE Taste durchlaufen ohne gedrückt zu sein, bleibt der Merker im Zustand "nicht ausgelöst" und erst damit (!) kann hier wieder ein neuer Auslöser gesetzt werden.

  if (tasteGedrueckt == false)                     // Wenn MERKER nicht ausgelöst ...
  {

Der wichtige Punkt ist, das Du verstehst, das Deine Durchnumerierung der Variablen eigentlich kontraproduktiv ist, weil die PIN-Nummern Dein Zählmedium ist.

Wenn Du kein durchgehendes Zählmedium hast, musst Du Dir eines schaffen.
Das zeige ich Dir, wenn Du den Zusammenhang zwischen der Pin-Nummer und dem davon lösgelösten VariablenNamen erkannt hast.

Hallo, wenn meine Pin´s das Zählmedium sind kann ich diese Schleife also nur nutzen wenn die Pins immer die selbe Art an Funktion ausführen sollen. Ich könnte z.B. nicht mit Pin 5 eine LED ansteuern. Ich muss mir also Variablen schaffen die ich als Zählmedium verwende.

Liege ich damit richtig?

Bin jetzt zwei Tage auf Geschäftsreise, melde mich so gut es geht....

ja!
Damit bist Du dann an dem Punkt, wo Du Dich mit Arrays beschäftigen kannst.
Ein Array ist nichts weiter als eine Aneinanderreihung.
Der Zugriff auf den einzelnen Inhalt erfolgt über seine Position.
Diese Position wird als Index bezeichnet.

Dann hört aber auch schon meine Erklärung auf, weil ich glaube, das Du Dir das selbst erarbeiten kannst und damit eindeutig besser fährst, als würde ich das vorkauen.

Aus Deinem Code gemacht:

// Basiert auf https://forum.arduino.cc/t/projekt-dfmp3player-mini/904529/16?u=my_xy_projekt
// ungetestet und ohne Funktionsgarantie
// kompiliert fehlerfrei

#include "SoftwareSerial.h"
#include "DFRobotDFPlayerMini.h"
//---------------------------------------------------
SoftwareSerial mysoftwareSerial(10, 11);
DFRobotDFPlayerMini myDFPlayer;

/*
  // alt:
  const byte titel1Pin = 4;  // Hier ist sortiert nach den Titeln
  const byte titel2Pin = 5;
  const byte titel3Pin = 6;
  const byte titel4Pin = 7;
  const byte titel5Pin = 8;
  const byte titel6Pin = 9;
  const byte titel7Pin = 2;
  const byte titel8Pin = 3;
*/

// Ich verwende ein Array, indem jeder PIN einzeln abgelegt ist
// Die Reihenfolge der PIN oder gar Unterbrechungen der Reihenfolge ist egal
// Der Index des Array wird mein Zählmedium
const byte titelPin[] = {4, 5, 6, 7, 8, 9, 2, 3}; // noch immer sortiert nach Titel

const byte volumeUpPin = 12;  // das sollte klar sein
const byte volumeDownPin = 13;

void setup()
{
  // Hier siehst Du, wie die Variablen verwendet werden
  // Das ist aber aufwendig und schreibintensiv
  // inkl. Fehlermöglichkeiten.
  /*
    pinMode(titel1Pin, INPUT); pinMode(titel2Pin, INPUT); pinMode(titel3Pin, INPUT);
    pinMode(titel4Pin, INPUT); pinMode(titel5Pin, INPUT); pinMode(titel6Pin, INPUT);
    pinMode(titel7Pin, INPUT); pinMode(titel8Pin, INPUT);
  */
  // Also Kurzweg basierend auf Zeile 26:
  for (byte b = 0; b < sizeof(titelPin); b++)
  {
    pinMode(titelPin[b], INPUT);
  }
  pinMode(volumeUpPin, INPUT); pinMode(volumeDownPin, INPUT);
  //---------------------------------------------------
  mysoftwareSerial.begin(9600);
  Serial.begin(115200);
  Serial.println();
  Serial.println(F("DFRobot DFPlayer Mini Demo"));
  Serial.println(F("Initializing DFPlayer ... (May take 3~5 seconds)"));
  if (!myDFPlayer.begin(mysoftwareSerial))   //Use softwareSerial to communicate with mp3.
  {
    Serial.println(F("Unable to begin:"));
    Serial.println(F("1.Please recheck the connection!"));
    Serial.println(F("2.Please insert the SD card!"));
    while (true);
  }
  Serial.println(F("DFPlayer Mini online."));
  myDFPlayer.volume(15); //Set volume value. From 0 to 30
  myDFPlayer.pause(); //Play the first mp3
  myDFPlayer.EQ(DFPLAYER_EQ_POP);
}
//===========================================================
void loop()
{
  // Die Variable tasteGedrueckt ist ein Merker, ob ein Tastendruck ausgelöst wurde
  // static bedeutet, das der Inhalt der Variable erhalten bleibt,
  // bis die Funktion erneut aufgerufen wird
  static bool tasteGedrueckt = false;
  if (tasteGedrueckt == false)                     // Wenn MERKER nicht ausgelöst ...
  {
    for (byte b = 0; b < sizeof(titelPin); b++)    // gezaehlt wird über das array
    {
      if (digitalRead(titelPin[b]) == HIGH)        // frage jede einzelne Taste ab
      {
        tasteGedrueckt = true;                     // wenn Taste gedrückt merke es
        myDFPlayer.play(b + 1);                    // und spiele den Titel
      }
    }
  }
  else                                             // ... Merker ist ausgelöst
  {
    tasteGedrueckt = false;                        // dann initialisiere erstmal mit false
    for (byte b = 0; b < sizeof(titelPin); b++)    // frage alle Tasten durch
    {
      if (digitalRead(b) == HIGH)                  // wenn eine der Tasten gedrückt ist
        tasteGedrueckt = true;                     // wird der Merker wieder ausgelöst
    }
  }
  // Wenn DOWN gedrückt ist, wird UP nicht mehr abgefragt
  // Wenn beide Tasten gedrückt sind, wird es IMMER leiser - nie lauter
  if (digitalRead(volumeDownPin) == HIGH) myDFPlayer.volumeDown();
  else if (digitalRead(volumeUpPin) == HIGH) myDFPlayer.volumeUp();
}

So und weil es so schön ist, eine Nachtliteratur für Dich: Code ausfüren wen 2 Bedinungen erfült sind(if) - #14 by my_xy_projekt
dort das .pdf am Ende des Beitrages runterladen und jeden Abend ein wenig lesen.
Nicht auswendig lernen.
Nur wissen, wo es steht.
Aber alles einmal durch - nicht nur sequentiell. Das geht :wink:

Na dann...