DFPlayer startet von allein bei Spannungsversorgung

Hallo,

ich habe einen Lichteffekte-Sketch für den Arduino im Internet gefunden.
Dieser funktioniert auch ohne Probleme. Die Lichteffekte wollte ich nun
mit Sound kombinieren. Der DFPLayer funktioniert auch ohne Probleme.
Kombiniere ich aber beides im Sketch fängt das Problem an.

Beim Anlegen der Spannung wird der erste Teil des Skechtes abgespielt
(Disruptor-Effekt). Sowohl Lichteffekte als auch der entsprechende
Sound.

Danach funktioniert alles ganz normal. Es wird nur dann Sound abgespielt
(in Kombination mit den LED´s) wenn ich den Knopf drücke bzw. halte.

Habe Widerstände in TX RX. Spannungen sind in Ordnung, keine Lötfehler
auf den Boards zu sehen.

Nehme ich aus dem Loop die Soundfunktion wieder raus (aber im Setup Serial
drin), bleibt das Problem gleich, nur eben ohne Sound.

Daher meine Vermutung, dass entweder die Soundfunktion im Loop an der
falschen Stelle ist oder bereits im Setup oder bei den Variablen etwas
nicht stimmt (Problem mit Serial?)?!

Es ist ein Arduino-Nano-Clone mit CH340 Chip und DFPlayer mini.

Wie gesagt, beide Sketche (Licht und Sound) funktionieren für sich
einzeln ohne Probleme.

#include "Arduino.h"
#include "SoftwareSerial.h"
#include "DFRobotDFPlayerMini.h"

SoftwareSerial mySoftwareSerial(10, 11); // RX, TX
DFRobotDFPlayerMini myDFPlayer;
void printDetail(uint8_t type, int value);


// ===================== Variables =============================================================//
// -------  Declaring Pins ----------------------------------------------//
static byte disruptorPin = 9;
static byte enginePin = 6;
static byte pushButtonPin = 12;
static byte torpPin[] = { 2, 3 };

// -------  User Inputs ------------------------------------------------//
static unsigned long torpUpTime = 1750;
static unsigned long torpFlashTime = 200;
static unsigned long torpDownTime = 150;
static long double torpIdleBrightness = 10;
static long double torpMaxBrightness = 255;
static unsigned long engineFadePeriod = 3000;
static unsigned long disruptorFiringTime = 2600;

// -------  For the Button Pushing -------------------------------------//
unsigned long debounce = 30;
unsigned long holdTime = 1500;

// -------  Bookeeping ------------------------------------------------//
unsigned long currentMillis;
boolean buttonValue = false;
boolean buttonLast = false;
boolean ignoreUp = false;
unsigned long buttonUpTime;
unsigned long buttonDownTime;
unsigned int torpedoPushes = 0;
unsigned int disruptorPushes = 0;
unsigned long torpedoTime;
unsigned long disruptorTime;
unsigned long torpedoMillis;
unsigned long disruptorMillis;
unsigned long disruptorFlashTime;
boolean disruptorState = 0;
// ==================== End Variables ========================================================= //


// ===================== Setup ================================================================ //
void setup(){
  pinMode(disruptorPin,OUTPUT);
  pinMode(enginePin,OUTPUT);
  pinMode(pushButtonPin,INPUT_PULLUP);     // Enables internal pull-up resistor
  pinMode(torpPin[0],OUTPUT);
  pinMode(torpPin[1],OUTPUT);
  
  mySoftwareSerial.begin(9600);
  Serial.begin(115200);
  if (!myDFPlayer.begin(mySoftwareSerial)) {  //Use softwareSerial to communicate with mp3.
    while(true);
  }
  myDFPlayer.setTimeOut(500); //Set serial communictaion time out 500ms
  myDFPlayer.volume(10);  //Set volume value (0~30).
  myDFPlayer.EQ(DFPLAYER_EQ_NORMAL);
  myDFPlayer.outputDevice(DFPLAYER_DEVICE_SD);
  
}


// ===================== End Setup ============================================================ //



// ===================== Main Loop ============================================================ //
void loop() {
  currentMillis = millis();         // get current time
  
 // ---------- Push Buttoon Code --------------------------------------------------------//

  buttonValue = digitalRead(pushButtonPin);
  
    // Record Time of Push
  if (buttonValue == LOW && buttonLast == HIGH && (millis() - buttonUpTime) > debounce){
    buttonDownTime = millis();
  }
  
  // Record Time of Release
  if (buttonValue == HIGH && buttonLast == LOW && (millis() - buttonDownTime) > debounce){
    buttonUpTime = millis();
    if (ignoreUp == false){
     disruptorTime = millis();        // If released early, fire disruptors!
     disruptorPushes++;
     myDFPlayer.playMp3Folder(2);
     }
     else{
       ignoreUp = false;
      }
   }

  // If push time is longer than threshold, fire Torpedos!
  if (buttonValue == LOW && (millis() - buttonDownTime) > long(holdTime)){
    buttonDownTime = millis();
    torpedoTime = millis();
    torpedoPushes++;
    ignoreUp = true;
    myDFPlayer.playMp3Folder(1);
   }
  
  // Record the button state for comparison in the next cycle
  buttonLast = buttonValue;    
 // -------------------------------------------------------------------------------------//
  
  
  
 // ---------- Torpedo Firing ----------------------------------------------------------//
 // Ramp Up Red LED, Flash White LED, then a Ramp Down of Red LED
  // Ramp Up
  
  if ((currentMillis-torpedoTime) < torpUpTime && torpedoPushes > 0){
    analogWrite(torpPin[1],torpIdleBrightness+(torpMaxBrightness-torpIdleBrightness)/torpUpTime*(currentMillis-torpedoTime));
    digitalWrite(torpPin[0], LOW);
    
  }  
  // Flash
  else if (((currentMillis-torpedoTime) > torpUpTime) && ((currentMillis-torpedoTime) < (torpUpTime+torpFlashTime)) && torpedoPushes > 0){
    analogWrite(torpPin[1], 0);
    digitalWrite(torpPin[0], HIGH);
    
  } 
  // Ramp Down
  else if (((currentMillis-torpedoTime) > (torpUpTime+torpFlashTime)) && ((currentMillis-torpedoTime) < (torpUpTime+torpFlashTime+torpDownTime)) && torpedoPushes > 0){
    analogWrite(torpPin[1],torpMaxBrightness+(torpIdleBrightness-torpMaxBrightness)/torpDownTime*((currentMillis-torpedoTime)-(torpUpTime+torpFlashTime)));
    digitalWrite(torpPin[0], LOW);
    
  }  
  // Idle
  else{
    analogWrite(torpPin[1], torpIdleBrightness);
    digitalWrite(torpPin[0], LOW);
    
  }

  
 // ---------- Engine Fading ----------------------------------------------------------- //
  // Slow Up and Down Fade with Shorter Pusations
  int fadeValue = int(127.0+127.0/2.0*(1+(0.75*sin(2*PI*currentMillis/engineFadePeriod)+0.25*cos(14*PI*currentMillis/engineFadePeriod))));
  analogWrite(enginePin,fadeValue);

 
 // ---------- Disruptor Firing -------------------------------------------------------- //
  // Get Random On or Off Time Using getRandom() Function Below
  disruptorFlashTime = fmod(getRandom(), 4000UL) + 60UL;
  if (((currentMillis - disruptorTime) < disruptorFiringTime) && (disruptorPushes > 0)){
    if(currentMillis - disruptorMillis > disruptorFlashTime) {
      disruptorMillis = currentMillis;  
      digitalWrite(disruptorPin, disruptorState = !disruptorState);
      } 
   }
   else{
     analogWrite(disruptorPin,5);
 
    }
 // ------------------------------------------------------------------------------------ //


}
// ===================== End Main Loop ======================================================== //




// ===================== Pseduo-Random Generator ============================================== //
// Found This Online. I Take No Credit for It.
unsigned long m_w = 1;
unsigned long m_z = 2; 

unsigned long getRandom()
{
    m_z = 36969L * (m_z & 65535L) + (m_z >> 16);
    m_w = 18000L * (m_w & 65535L) + (m_w >> 16);
    return (m_z << 16) + m_w;  /* 32-bit result */
}
// ===================== End Pseduo-Random Generator ========================================== //

Du solltest mit dem seriellen Monitor mal die Zustände deines Tasters prüfen.
Ich vermute, der bekommt gleich beim Start einen falschen Zustand geliefert.

Etwas unübersichtlich ist es auch, da du die Variablen mit HIGH oder LOW abfragst, obwohl sie als Boolean definiert sind.
Das funktioniert zwar ist aber irreführend.

Hallo Dieter,

danke für deine schnelle Antwort.

Wie gesagt, den Sketch habe ich so im Internet gefunden, daher kann ich dir leider nicht sagen, wieso dies oder jenes so geschrieben wurde.

Was für einen Befehl müsste ich denn eingeben, um über den seriellen Monitor den Zustand des Tasters abzufragen? Habe leider noch nicht mit Println oder so gearbeitet.

Das mit dem Zustand dachte ich mir auch schon. Darum ist ja beim Taster ist der interne Pullup aktiviert. Hatte den auch mal rausgenommen und einen echten PullUp Widerstand genommen. Gleiches Ergebnis.

Ohne den seriellen Teil des Sketches (also nur die LED-Effekte), habe ich mit dem Taster keine Probleme.

Gruß Björn

In der Arduino-Referenz hier kannst du nachlesen, wie das mit den Anweisungen funktioniert.
Da kannst du dir jeden Inhalt der Variablen anzeigen lassen.

Hi

Ich habe noch nicht Mal das eigentliche Problem erkannt - irgendwie verstehe ich

Danach funktioniert alles ganz normal. Es wird nur dann Sound abgespielt
(in Kombination mit den LED´s) wenn ich den Knopf drücke bzw. halte.

nicht als Fehlerbeschreibung.

Wenn Du mir sagen könntest, WAS Du WANN erwartest, aber WAS, Du dafür bekommst?

MfG

Erwartung:

Zustand 1:
Wenn Spannung anliegt, sollte nur die Engine LED (Pin 6) leuchten (bzw. flackern), sowie die Torpedo LED (Pin 3) schwach leuchten. Mehr passiert in diesem Zustand nicht.

Zustand 2:
Wird nun der Taster (Pin 12) kurz gedrückt, fadet die LED Pin 3 auf, geht dann bei höchster Helligkeit aus, während LED (Pin 2) kurz aufblitzt und danach LED Pin 3 wieder runterfadet. Währenddessen wird die Sounddatei (1) abgespielt. Danach fällt der Arduino und DFPlayer wieder in Zustand 1 zurück

Zustand 3:
Beim Halten des Tasters (Pin 12) blinkt die Disruptor LED (Pin 9) in zufälliger Folge für 2600ms, während die Sounddatei (2) abgespielt wird. Danach fällt der Arduino und DFPlayer wieder in Zustand 1 zurück.

Problem:
Seit der Erweiterung um die Befehle für den DFPlayer, habe ich das Phänomen, dass beim Anlegen der Spannung der Zustand 2 ausgeführt wird ohne das der Taster gedrückt wurde. Sobald Zustand 2 ausgeführt wurde, herrscht wieder Zustand 1 und ich kann nun (wie gewollt) Zustand 2 und 3 ausschließlich per Tastendruck ausführen.

Es wird also beim Anlegen der Spannung Zustand 2 einmal ausgeführt, ohne den Taster gedrückt zu haben.

Hab grad mit dem seriellen Monitor herausgefunden, dass der Taster einen Zustand liefert, sobald Spannung angelegt wird. Komischerweise tatsächlich nur beim “Hochfahren” des Arduinos. Ist der Arduino online, wird nur dann ein Zustand des Tasters ausgegeben, wenn ich diesen auch drücke.

Hi

Versuche Mal
boolean buttonLast=true;
bei der Deklaration - habe zwar kaum Hoffnung, daß Das was bringt - dann hätte Es vorher ebenfalls nicht klappen dürfen - aber als Strohhalm fällt mir nichts Besseres ein/auf.

MfG

PS: Einen 'Zustand' sollte der Taster bei jeder Abfrage liefern

postmaster-ino:
Hi

Versuche Mal
boolean buttonLast=true;
bei der Deklaration - habe zwar kaum Hoffnung, daß Das was bringt - dann hätte Es vorher ebenfalls nicht klappen dürfen - aber als Strohhalm fällt mir nichts Besseres ein/auf.

MfG

PS: Einen 'Zustand' sollte der Taster bei jeder Abfrage liefern

Ich werd verrückt! DANKE! Boolean buttonLast auf true setzen hat funktioniert! Wenn du mir jetzt noch erklären könntest warum, bzw. warum es vorher schon hätte nicht klappen dürfen, würde sich der Schleier von kleinen gemeinen Arduino-Gizmos lüften :smiley:

MfG

PS: klar, ein Schalter hat immer Zustand high oder low.....wollte damit nur sagen, dass der Zustand low beim Einschalten ausgeben wird, obwohl der Schalter nicht gegen Gnd geschaltet ist

Hi

Die Prüfung ist auf 'Taster gedrückt und vorher nicht gedrückt' - wir haben quasi nur das 'vorher nicht gedrückt' in 'vorher gedrückt' getauscht, somit greift diese Prüfung in der ersten Runde nicht.
Danach ist der Alt-Status des Taster eh in dieser Variable gespeichert.

Und deshalb hätte Das vorher auch schief gehen müssen, da ja auch dort die Prüfung hätte greifen müssen - warum Sie Das nicht tat ... jo, gute Frage.

MfG

Hi,

achso, dann wurde also die Prüfung ´Taster gedrückt und vorher nicht gedrückt´ als Input fehlinterpretiert oder? Aber ja, dann ergibt das tatsächlich keinen Sinn, weil wir ja dann jetzt sagen ´gedrückt und vorher gedrückt´.

Komisch, das soll mal einer verstehen :smiley:

Danke nochmal!

Es ist immer besser die Variablen entsprechend vorzubelegen.
Das Problem mit Boolean hatte ich ja schon geschrieben, die Auswirkung dahin aber nicht vorher gesehen.