Go Down

Topic: DFPlayer sometimes LOOPS wrong file (Read 3568 times) previous topic - next topic

Agatsuma

So I have encountered strange behaviour, sometimes if after PLAY command with one file there is a LOOP comand after a short while with another file DFPlayer loops the file it was playing in PLAY command, and not the one that was writen in LOOP command. Not always, but this does happen. Any ideas? Maybe I have missed something?


In my case it happens after SWING sound have been played and IDLE sound must be looped (at the end of the code).

Here is my code:

Code: [Select]
#include <DFPlayerMini_Fast.h>

#include <MPU6050.h>

#include <SoftwareSerial.h>

#include "Wire.h"

#include "BladeHacking.h"

SoftwareSerial ss(4,5);

const int MPU_ADDR = 0x68;

int16_t accel_x, accel_y, accel_z, gyro_x, gyro_y, gyro_z, temp;
float averageGyroX,averageGyroY,averageGyroZ;

MPU6050 MyGyro(MPU_ADDR);
DFPlayerMini_Fast myDFPlayer;
BladeHacking bladeHack;



#define Idle 1
#define Swing 2
#define Hit 3
#define Opening 4
#define Closing 5

#define SWITCH_PIN 10

void setup() {       
 
  pinMode(10,INPUT_PULLUP);
 
  Serial.begin(9600);
  ss.begin(9600);

 
  pinMode(6, OUTPUT);
  digitalWrite(6, HIGH);

  //delay(2000);
 
  pinMode(8, OUTPUT);
  digitalWrite(BLADE_DATA_PIN, SIG_IDLE);
  bladeHack.send_sig( SIG_CMD_OFF );
  delay(1000);

 
 
  Wire.begin();
 
  MyGyro.initialize();
  MyGyro.setFullScaleGyroRange(MPU6050_GYRO_FS_2000);
  MyGyro.setFullScaleAccelRange(MPU6050_ACCEL_FS_4);
  MyGyro.setAccelerometerPowerOnDelay(3);
  MyGyro.setInterruptMode(true);
  MyGyro.setInterruptLatch(0);
  MyGyro.setIntMotionEnabled(true);
  MyGyro.setDHPFMode(1);
  MyGyro.setMotionDetectionThreshold(3);
  MyGyro.setMotionDetectionDuration(40);

  attachInterrupt(0,DetectedMotion, RISING);
 
 
  bool connectedToPlayer = false;
  while(!connectedToPlayer){
    connectedToPlayer = myDFPlayer.begin(ss);
  }
  Serial.println("Connected to player");
 
  myDFPlayer.volume(30);

  delay(100);
}


void DetectedMotion(){

  Serial.println("Detected motion. Detaching interrupt");
  detachInterrupt(0);
 
}

float getGlobalAccel(){

  MyGyro.getAcceleration(&accel_x,&accel_y,&accel_z);
  float ax = 1.0*(accel_x+1820)/8196;
  float ay = 1.0*(accel_y+4450)/8196;
  float az = 1.0*(accel_z+250)/8196;

  return abs(sqrt(ax*ax+ay*ay+az*az) - 1.0);
 
}

float getGlobalRot(){

  MyGyro.getRotation(&gyro_x,&gyro_y,&gyro_z);
  float gx = 1.0*(gyro_x+45)/16.4;
  float gy = 1.0*(gyro_y+55)/16.4;
  float gz = 1.0*(gyro_z+40)/16.4;

  return sqrt(gx*gx+gy*gy+gz*gz);
 
}

bool bladeOn = false;
bool isOpening = false;
bool isClosing = false;
bool isSwing = false;
bool isHit = false;
bool isLooping = false;
bool moving=false;


float minD=100000;
float maxD = 0;

float zeroMotionTimer=0;

float soundTimer=0;
float startMillis=0;

int playingSound = Idle;

void loop() {
 
  bladeHack.red_breath();
 
//  rot thres 350
//  accel thres 0.3-0.35

  if(digitalRead(SWITCH_PIN) == LOW && !bladeOn && playingSound != Opening)
  {
    //bladeOn=true;
    myDFPlayer.play(1);
    playingSound = Opening;
    soundTimer = 1826;
    startMillis = millis();
  }
 
  if(digitalRead(SWITCH_PIN) == HIGH && bladeOn)
  {
    bladeOn=false;
    myDFPlayer.play(2);
  }

  if(playingSound == Opening && millis()-startMillis > soundTimer){

    myDFPlayer.loop(3);
    playingSound = Idle;
    soundTimer = 300;
    startMillis = millis();
    bladeOn = true;
  }
 
  if(bladeOn)
  {
    float globalAcc = getGlobalAccel();
    //Serial.println(globalAcc);
    if(globalAcc>3.1 && playingSound != Hit){
      myDFPlayer.play(5);
      playingSound = Hit;
      soundTimer = 543;
      startMillis = millis();
    }
    else if(playingSound == Idle &&(getGlobalRot()>350 || globalAcc>0.33))
    {
      myDFPlayer.play(4);
      playingSound = Swing;
      soundTimer = 633;
      startMillis = millis();
    }
    else if(millis()-startMillis > soundTimer && playingSound != Idle)
    {
      myDFPlayer.loop(3);
      playingSound = Idle;
      soundTimer = 300;
      startMillis = millis();
    }
  }
}

Agatsuma

#1
Dec 01, 2019, 06:46 pm Last Edit: Dec 01, 2019, 06:49 pm by Agatsuma
According to DFPlayer manual (http://www.picaxe.com/docs/spe033.pdf) 0x08 register ses playback mode and as a parameter expects playback mode number. But both DFRobot's and Power_Broker's Fast libraries send as a parameter Track number. Maybe thats the reason? Maybe send 0x03 register with File and then 0x08 with a repeat one playback mode or something like that?

Agatsuma

Strange. Tried code from example here to send commands dirrectly and not through libraries, and it seems that 0x08 indeed uses parameter to select track to loop, because I sent 02 to 0x08 register and instead of selecting Repeat one playback mode it looped track number 2. But that contradicts to datasheet info?

Power_Broker

#3
Dec 01, 2019, 08:56 pm Last Edit: Dec 01, 2019, 08:58 pm by Power_Broker
The documentation for the DFPlayerMini is very poorly written, misleading, and sometimes flat out wrong. 0x08 is not a register, it's simply a command description.

You're correct, command 0x08 can be used for "looping" a track - that's how my library does it (I think you're familiar with it, lol).
"The desire that guides me in all I do is the desire to harness the forces of nature to the service of mankind."
   - Nikola Tesla

Agatsuma

The documentation for the DFPlayerMini is very poorly written, misleading, and sometimes flat out wrong. 0x08 is not a register, it's simply a command description.

You're correct, command 0x08 can be used for "looping" a track - that's how my library does it (I think you're familiar with it, lol).
yeah, its a command, sorry.

Here what it says in datasheet:

0x08 Specify playback mode (0/1/2/3) Repeat/folder repeat/single repeat/ random

Is there a real command to specify playback mode? So I could start playing a file and then send a command to loop it?

Agatsuma

Im wondering, can it be happening because of Im powering DFPlayer from 3 AA battaries that is 4.6v and it needs 3.2v?

Power_Broker

All I can say is that the documentation is terrible and sending command 0x08 with the track number as the payload is how you can loop tracks.

Also, you should be powering the DFPlayerMini with 5V just to be sure it has enough juice (even though the datasheet says 3.2V-5V - again, I don't trust the documentation)
"The desire that guides me in all I do is the desire to harness the forces of nature to the service of mankind."
   - Nikola Tesla

Agatsuma

Another thought. It uses 3.3v uart communication signals, right? So I have 1KOhm resistor on TX-RX from arduino. But I have measured voltage under load and it drops to 4.26v. Maybe communication voltage is to low with resistor in place and that causes it to execute command with errors? Will try removing resistor today.

Power_Broker

Yeah, that's a good catch - might try using a voltage divider to be sure...
"The desire that guides me in all I do is the desire to harness the forces of nature to the service of mankind."
   - Nikola Tesla

Go Up