Problems merging 2 codes (blinking light and dfplayer)

Hi People. - its me newbie again :smiley:

Need help with this - I need to activate a sound file from dfplayer mini and fast blinking (strobelight-look) led, by a PIR sensor.

I have seached everything, and copied lines forward and backwards, but cant seem to find the magic solution. (Maybe because im brand new to this and my english is not really good, so its hard to understand some command/lines), so hope you can help.

My two codes works perfect seperated, but when "merged", the sound works fine, but the LED only flash once when PIR activated.

Can you guide me in some direction?
Thanks :slight_smile:

merged codes:

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

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

#define SENSORPIN 9
#define PAUSETIME 6000
int led = 2;                 // LED pin
int sensor = 9;              // PIR sensor pin
int state = LOW;             // by default, no motion detected
int val = 0;                 // variable for sensor value


void setup() {
  mySoftwareSerial.begin(9600);
  Serial.begin(115200);
  pinMode(SENSORPIN, INPUT);
    pinMode(led, OUTPUT);      // set led pin as output
  

  Serial.println();
  Serial.println(F("Initializing DFPlayer..."));

  //Use softwareSerial to communicate with MP3
  if (!myDFPlayer.begin(mySoftwareSerial)) {
    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."));

  //Set volume value (From 0 to 30)
  myDFPlayer.volume(5);
}

void sensorActivated() {
  int pirSensor = digitalRead(SENSORPIN);
  if(pirSensor == HIGH)
  {
    Serial.println("Sensor Activated");
    Serial.println("DFPlayer Working...");
    myDFPlayer.play(1);
  }
  return;
}

void loop() {
  sensorActivated();
  delay(PAUSETIME);
    val = digitalRead(sensor);  // read sensor value
  if (val == HIGH) {
   digitalWrite(led, HIGH); // turn the LED on (HIGH is the voltage level)
   delay(100);            // wait for a second 
   digitalWrite(led, LOW);  // turn the LED off by making the voltage LOW
   delay(75);            // wait for a second 
    
    if (state == LOW) {
      state = HIGH;
    }
  } 
  else {
      digitalWrite(led, LOW); // turn LED OFF
      delay(1000);             // delay in milliseconds
      
      if (state == HIGH){
        state = LOW;
      }
  }}

The two
#define SENSORPIN 9
#define PAUSETIME 6000 -is from the dfplayer mini code

and

int led = 2;
int sensor = 9;
int state = LOW;
int val = 0; - is from the blinking LED code - dont know if its the right way with both define and int when merged?

In copying and pasting the code, do you understand and know why every line of code is in there ?

I understand some of it - but my english is not so good, so not all. tried googling a lot of it, but something is hard to understand when only using it for this project :slight_smile: (maybe more in the future if people can help with it :slight_smile: )

ok, to get yu started, see if you can get rid of the delays (especially the long ones),
Then put some Serial.prints in there to see what’s holding things up.

As you evolve, you’ll become familiar with some new tricks to make things ‘appear’ to happen concurrently.

Thanks for taking you time to answer - the serial prints only tells me the mp3 is playing - I have been looking at this the last 14 days, so my time is almost up before I give up.

this is the two codes i have that works seprately:

code 1 (led strobe blink)

int led = 2;                 // LED pin
int sensor = 9;              // PIR sensor pin
int state = LOW;             // by default, no motion detected
int val = 0;                 // variable for sensor value

void setup() {
  pinMode(led, OUTPUT);      // set led pin as output
  pinMode(sensor, INPUT);    // set sensor pin as input
}

void loop(){
  val = digitalRead(sensor);  // read sensor value
  if (val == HIGH) {
   digitalWrite(led, HIGH); // turn the LED on (HIGH is the voltage level)
   delay(100);            // wait for a second 
   digitalWrite(led, LOW);  // turn the LED off by making the voltage LOW
   delay(75);            // wait for a second 
    
    if (state == LOW) {
      state = HIGH;
    }
  } 
  else {
      digitalWrite(led, LOW); // turn LED OFF
      delay(1000);             // delay in milliseconds
      
      if (state == HIGH){
        state = LOW;
    }
  }
}

Code 2, play mp3 file:

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

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

#define SENSORPIN 9
#define PAUSETIME 6000

void setup() {
  mySoftwareSerial.begin(9600);
  Serial.begin(115200);
  pinMode(SENSORPIN, INPUT);

  Serial.println();
  Serial.println(F("Initializing DFPlayer..."));

  //Use softwareSerial to communicate with MP3
  if (!myDFPlayer.begin(mySoftwareSerial)) {
    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."));

  //Set volume value (From 0 to 30)
  myDFPlayer.volume(5);
}

void sensorActivated() {
  int pirSensor = digitalRead(SENSORPIN);
  if(pirSensor == HIGH)
  {
    Serial.println("Sensor Activated");
    Serial.println("DFPlayer Working...");
    myDFPlayer.play(1);
  }
  return;
}

void loop() {
  sensorActivated();
  delay(PAUSETIME);
}

Does play start the sound and move on or does it wait until the whole file has been completed?

If the PIR is set to max time then it keeps starting the mp3 over again and led blinks one time at everytime the mp3 starts... the mp3 is about 6seconds long.

My plan is it should play for 6seconds while the LED blinks fast for same time. Its used for at jumpscare where its playing a scream and the led light up a skullhead when PIR is activated.

What do you see in the serial monitor?

it says:
15:25:12.335 ->
15:25:12.335 -> Initializing DFPlayer...
15:25:13.089 -> DFPlayer Mini online.
15:26:01.276 -> Sensor Activated
15:26:01.276 -> DFPlayer Working...
15:26:07.467 -> Sensor Activated
15:26:07.467 -> DFPlayer Working...
15:26:13.617 -> Sensor Activated
15:26:13.617 -> DFPlayer Working...

So sensor to dfplayer react as it should, but not to blink the LED - mayber there is a simpler way to make the code..?

Thanks for your time.

That helps, although @lastchancename already nailed it. That delay for pausetime is preventing the led flashing code from getting an opportunity to do its job.

Thanks. Appreciate your time.
But how do I resolve it? (I actual dont know where that "pausetime" does... I tried remove the both "pausetime" lines, but then it doesnt work.

I expect that what is happening now is that loop is calling the play function repeatedly and restarting the track before it actuallyproduced anything audible. Previously, the delay was avoiding that, but at the cost of stopping the LEDs working.

I can see two ways to fix it. The right way is probably to have a look at your library and find something that you can use to check whether the device is playing something. If it is, don't kick it off again. There is no obvious IsPlaying function, but you may be able to get something from readStatus that will tell you what you need to know.

The other way is a bit of a hack - you can use millis for timing and because you know how long your track is, you can ensure that six seconds have passed before checking the PIR again.

This latter method is illustrated by the Blink without delay example that comes with the IDE. There's also a long post about it in the tutorials section called " Using millis() for timing. A beginners guide"

Something like this should get you going... You have to keep track of which state you are in (waiting for the PIR to trigger or blinking)

const byte led = 2;                 // LED pin
const byte sensor = 9;              // PIR sensor pin
bool isActivated = false;

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

SoftwareSerial mySoftwareSerial(10, 11); // RX, TX
DFRobotDFPlayerMini myDFPlayer;

const unsigned long pauseTime = 6000;   // how long between PIR detections
const unsigned long blinkTime = 100;    // how fast to blink led

unsigned long startTime; // time PIR triggered
unsigned long lastTime; // last time we toggled led

void setup() {
  pinMode(led, OUTPUT);      // set led pin as output
  pinMode(sensor, INPUT);    // set sensor pin as input

  mySoftwareSerial.begin(9600);
  Serial.begin(115200);

  Serial.println(F("\nInitializing DFPlayer..."));

  //Use softwareSerial to communicate with MP3
  if (!myDFPlayer.begin(mySoftwareSerial)) {
    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."));

  //Set volume value (From 0 to 30)
  myDFPlayer.volume(5);
}

void loop() {
  if ( isActivated ) {
    // blink led
    if ( millis() - lastTime >= blinkTime ) {
      lastTime = millis();
      digitalWrite(led, !digitalRead(led));
    }

    // check if we have been active long enough
    if ( millis() - startTime >= pauseTime ) {
      isActivated = false; // force PIR to trigger again or not
    }
  }

  if ( isActivated == false ) {
    // check PIR
    int pirSensor = digitalRead(sensor);
    if (pirSensor == HIGH) {
      isActivated = true;
      startTime = millis();
      Serial.println("Sensor Activated");
      Serial.println("DFPlayer Working...");
      myDFPlayer.play(1);
    }
  }
}
1 Like

Youre a HERO!
It works that way!!
Think I have to read up at the new code to see what differences there is - THANK YOU SO MUCH!!!!
Now the kids can be scared for halloween :smiley:

Do you know how the code should look if using an distance sensor (HC-SR04) instead of the PIR?
I tried several days and night, but can't figure it out.
I can activate an LED with distance, but cant figure out how to activate it for only 6 second for example, when the sensor is still triggered.

Please post your best effort at what you have tried and people will assist.

This is my wild guess for the code, it can verify/upload but nothing happends:

const byte led = 2;                 // LED pin
const byte sensor = 9;              // PIR sensor pin
bool isActivated = false;

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

SoftwareSerial mySoftwareSerial(10, 11); // RX, TX
DFRobotDFPlayerMini myDFPlayer;

const unsigned long pauseTime = 6000;   // how long between PIR detections
const unsigned long blinkTime = 100;    // how fast to blink led

unsigned long startTime; // time PIR triggered
unsigned long lastTime; // last time we toggled led

void setup() {
  delay (5000);
  pinMode(led, OUTPUT);      // set led pin as output
  pinMode(sensor, INPUT);    // set sensor pin as input

  mySoftwareSerial.begin(9600);
  Serial.begin(115200);

  Serial.println(F("\nInitializing DFPlayer..."));

  //Use softwareSerial to communicate with MP3
  if (!myDFPlayer.begin(mySoftwareSerial)) {
    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."));

  //Set volume value (From 0 to 30)
  myDFPlayer.volume(30);
}

void loop() {
  if ( isActivated ) {
    // blink led
    if ( millis() - lastTime >= blinkTime ) {
      lastTime = millis();
      digitalWrite(led, !digitalRead(led));
    }

    // check if we have been active long enough
    if ( millis() - startTime >= pauseTime ) {
      isActivated = false; // force PIR to trigger again or not
    }
  }

  if ( isActivated == false ) {
    // check PIR
    int pirSensor = digitalRead(sensor);
    if (pirSensor == HIGH) {
      isActivated = true;
      startTime = millis();
      Serial.println("Sensor Activated");
      Serial.println("DFPlayer Working...");
      myDFPlayer.play(1);
    }
  }
}

Its copied from this working code where an led lights up when distance is <30cm

#include <PCM.h>

#define MIN_DISTANCE 30

int echo = 5; // Pin to echo                          
int trigger = 6; // Pin for trigger
int led1 = 13; // led onboard for test
unsigned long responsetime;
unsigned long distance;



void setup ()
{
  pinMode (trigger, OUTPUT);                     
  pinMode (echo, INPUT); 
  pinMode (led1, OUTPUT);

}

void loop ()
{
  digitalWrite (trigger, HIGH); // We send a 10 microsecond pulse
  delayMicroseconds (10);                        
  digitalWrite (trigger, LOW);                   
  responsetime = pulseIn (echo, HIGH); // And we wait for a pulse back
  distance = responsetime / 58; // Distance calculation in cm

  if (distance <MIN_DISTANCE) {
    digitalWrite (led1, HIGH);        
    delay (35);
    digitalWrite (led1, LOW);

  } 
}

I appreciate your time - im still trying to learn the different styles of coding, but im really lost when its not working :slight_smile:

You need to know what the distance is. For now, just print it to serial when you have it.

Add this line to loop:

distance = responsetime / 58; // Distance calculation in cm

When you compile it, the compiler will complain about those variables, so add the code that declared them and does anything with them. Then other variables will be missing. Rinse and repeat until you get a clean compile. Post what you have then when it doesn't work.

That is not 1 sketch. It is your original PIR sketch and then a different sketch which measures distance. You need to combine them. Copy all the code inside setup() and add it to your original setup() code. Do the same for loop but then instead of the PIR trigger setting isActive, it would be distance.