Execute a looping function out of the main loop

I am having trouble with part of my code.

I am working on a program, that using a sensor and a dfplayer, should play a track and while the track is being played, a LED should be turned on with a fade effect, until the track stops playing.

I have the function sensorActivated() that is executed on the main loop.

When the condition from sensorActivated() is given (pirSensor == HIGH && myDFPlayer.isPlaying()!=1) , the function fadingLED() is called.

The problem I have is I want fadingLED() to execute a loop that makes a fade effect on the LED, and I don't know how to achieve that.

Since sensorActivated() is executed all the time, while (pirSensor == HIGH && myDFPlayer.isPlaying()!=1) is true, the part where fadingLED() turns on the LED is executed all the time , but the part where the led should be fading it is not executed.

Let's look at sensorActivated() , the function that is executed at the main loop, that also calls to fadingLED().

void sensorActivated() {

// DFPlayerMini_Fast.h has a built-in function, "player.isPlaying()", that returns a boolean based on if the module is playing a song currently or not.

  int pirSensor = digitalRead(SENSORPIN);
 
    if(pirSensor == HIGH && myDFPlayer.isPlaying()!=1)
  {

    Serial.println("DFplayer status: ");
    Serial.println(myDFPlayer.isPlaying());
    Serial.println("Sensor Activated");
    Serial.println("DFPlayer Working...");
      Serial.println("Random track being played: ");
    randomInt = random(3, 8);
    Serial.println(randomInt);
    myDFPlayer.play(randomInt);
    
**fadingLED();**





  }

if(pirSensor == LOW && myDFPlayer.isPlaying()==0)

  {


    analogWrite(LED, LOW); // apaga led
    Serial.println("Led OFF, player status: ");
    
    Serial.println(myDFPlayer.isPlaying());

  }

  
  
  return;  
  }

Let's look now take a look at fadingLED(), where my troubles are. Of course like that it is not looping in order to get the dim effect, that's what I don't know how to achieve.

void fadingLED() {

  analogWrite(LED, brightness);


// change the brightness for next time through the loop:
  brightness = brightness + fadeAmount;

  // reverse the direction of the fading at the ends of the fade:
  if (brightness == 20 || brightness >= 100) {
    fadeAmount = -fadeAmount;
  }
  // wait for 30 milliseconds to see the dimming effect
  delay(40);


}  

The code only turns on the led with analogWrite(LED, brightness). If I just wanted to have the led on while isPlaying()!=1, it would be fine as it is.

void fadingLED() {

  analogWrite(LED, brightness);

} 

This part, I don't know how to execute it, in order to get the fading effect while isPlaying()!=1.

// change the brightness for next time through the loop:
  brightness = brightness + fadeAmount;

  // reverse the direction of the fading at the ends of the fade:
  if (brightness == 20 || brightness >= 50) {
    fadeAmount = -fadeAmount;
  }
  // wait for 30 milliseconds to see the dimming effect
  delay(30);

If I execute only fadingLED() on the main loop the LEd dims as it should.

PD: Also, I don't know why I have to use the condition isPlaying()!=1 instead of isPlaying()==1, if I use isPlaying()==1, it doesn't work.

I asume it has something to do with how the library DFPlayerMini_Fast works.

/*!
	 @brief  Determine if a track is currently playing.
	 @return True if a track is currently playing, false if not, -1 if error.
 */
 /**************************************************************************/
bool DFPlayerMini_Fast::isPlaying()
{
	int16_t result = query(dfplayer::GET_STATUS_);

	if (result != -1)
		return (result & 1);

	return 0;
}

Here is all my code:

#include "SoftwareSerial.h"
#include "DFPlayerMini_Fast.h"

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

#define SENSORPIN 8
#define PAUSETIME 500
int randomInt;

#define LED 9     //  led a pin 9



int brightness = 20;  // how bright the LED is
int fadeAmount = 5;  // how many points to fade the LED by



void setup() {
  mySoftwareSerial.begin(9600);
  Serial.begin(115200);
  pinMode(SENSORPIN, INPUT);
  pinMode(LED, 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(25);
}

void fadingLED() {
//Lo del led
  analogWrite(LED, brightness);


// change the brightness for next time through the loop:
  brightness = brightness + fadeAmount;

  // reverse the direction of the fading at the ends of the fade:
  if (brightness == 20 || brightness >= 50) {
    fadeAmount = -fadeAmount;
  }
  // wait for 30 milliseconds to see the dimming effect
  delay(30);


}  


void sensorActivated() {

// DFPlayerMini_Fast.h has a built-in function, "player.isPlaying()", that returns a boolean based on if the module is playing a song currently or not.
  int pirSensor = digitalRead(SENSORPIN);
 
    if(pirSensor == HIGH && myDFPlayer.isPlaying()!=1)
  {

    Serial.println("DFplayer status: ");
    Serial.println(myDFPlayer.isPlaying());
    Serial.println("Sensor Activated");
    Serial.println("DFPlayer Working...");
      Serial.println("Random track being played: ");
    randomInt = random(3, 8);
    Serial.println(randomInt);
    myDFPlayer.play(randomInt);
    
fadingLED();





  }

if(pirSensor == LOW && myDFPlayer.isPlaying()==0)

  {

//hay diferencia entre digitalwrite y analogwrite
    analogWrite(LED, LOW); // apaga led
    Serial.println("Led OFF, player status: ");
    //Looks like player status 1 means playback is finished.
    Serial.println(myDFPlayer.isPlaying());

  }

  
  
  return;  
  }




void loop() {

  sensorActivated();
 delay(PAUSETIME);
  //fadingLED();
}

The problem is that you are calling fadingLED() only once when the playing begins. You need to call it repeatedly while the playing is happening. You have:

  if (there is motion AND the player is not already playing)
    start the playing.

  if (there is no motion AND the playing has stopped)
    turn off the LED

What you need is:

  if (the player is playing)
    fadingLED();
  else
    if (there is motion)
      start playing
   else
     turn off LED
}
1 Like

Thanks. You where right, the problem was there.

There is something I'm not sure I understand totally, perhaps you can help me with that.

About myDFPlayer.isPlaying() status:
Wont it be
myDFPlayer.isPlaying() != 1

and isPlaying()==0

the same thing?

If status is equal to 0, status is different than 1, so it would give the same result, right?

Thank you so much!

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.