I saw your newer comments and I played around with this today using an UNO and this PIR.
The code below, while lacking any semblance of elegance, does work. When it starts, it sets the volume and then waits for activation of the motion detector. It then plays a "random" track while pulsing the LED. The LED is pulsing only while a track is playing and is extinguished when no track is playing. Note how I am using ".isPlaying()".
Hope it helps.
#include <DFPlayerMini_Fast.h>
#include <SoftwareSerial.h>
SoftwareSerial MySerial(10, 11); // RX, TX
DFPlayerMini_Fast MyMP3;
#define PIR 8 // PIR input pin
#define LED 9 // led pin
#define pulseDelay 5 // milliseconds between LED change
int brightness = 0; // PWM level for LED
int fadeAmount = 5; // how many points to fade the LED by
int volume = 25; // Player initial volume
int nFiles = 15; // number of mp3 files on sd card
void setup() {
analogWrite(LED, brightness);
randomSeed(analogRead(5));
Serial.begin(9600);
MySerial.begin(9600);
MyMP3.begin(MySerial, false);
MyMP3.stop();
Serial.print("Setting volume to ");
Serial.println(volume);
MyMP3.volume(volume);
}
void loop() {
sensorActivated();
fadingLED();
}
void fadingLED() {
static unsigned long timer = millis();
if (MyMP3.isPlaying()) {
if (millis() - timer > pulseDelay) {
timer = millis();
analogWrite(LED, brightness);
brightness = brightness + fadeAmount;
if (brightness == 0 || brightness >= 255) {
fadeAmount = -fadeAmount;
}
}
}
}
void sensorActivated() {
if ( (digitalRead(PIR) == HIGH) && (!MyMP3.isPlaying()) )
{
Serial.println("Sensor Activated");
Serial.print("Random track being played: ");
int randomInt = random(1, nFiles + 1);
Serial.println(randomInt);
MyMP3.play(randomInt);
}
else {
if (!MyMP3.isPlaying())
{
if (brightness) {
brightness = 0;
analogWrite(LED, brightness);
}
}
}
}
==================
You can make this a bit easier if you clearly say what you want the effect to be.
For example, when the DFP is NOT playing (the track is finished) pulse the LED UNTIL there is motion which causes another track to play.
Or maybe, pulse the LED as long as the the DFP is playing and turn the LED off when the DFP is not playing.
What you have written is:
*I want to execute fadingLED(); only with the condition:
if(pirSensor == HIGH && myDFPlayer.isPlaying()!=1)
I know my code is wrong. What would be the best approach to execute fadingLED() with the condition (pirSensor == HIGH && myDFPlayer.isPlaying()!=1) ???*
The problem that I see is that when the condition,
if(pirSensor == HIGH && myDFPlayer.isPlaying()!=1) is true, you execute code to randomly select another track and start playing again. This would occur very quickly, so, myDFPlayer.isPlaying() will change and you will never be able to see the the pulsing LED.
I think you have it written incorrectly.
I will ASSUME that when the PIR sensor is LOW, it indicates motion and when myDFP.isPlaying()!=1 indicates that it is NOT playing.
When you detect motion AND the DFP is not playing, you want to start another track playing.
So, change the line in sensorActivated() to
if(pirSensor == LOW && myDFPlayer.isPlaying()!=1)
Note: if I have the PIR sensor output wrong, then leave it as
if(pirSensor == HIGH && myDFPlayer.isPlaying()!=1)
but read the rest, so you see what I am getting at because you can't use that same conditional test in the fadingLED() functions.
Now, when it is not playing and you detect motion, another track will start playing.
Replace "fadingLED();" in sensorActivated to:
brightness=20;
analogWrite(LED, brightness);
It becomes:
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);
brightness = 20;
analogWrite(LED, brightness);
// you may need to wait here until myDFPlayer.isPlaying() changes values
}
}
Now while it is playing, the LED is dim (it can be modified to be off later);
Modify fadingLED to this:
void fadingLED() {
static unsigned long timer = millis();
if (myDFPlayer.isPlaying() != 1)) {
if (millis() - timer > pulseDelay) {
timer = millis();
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;
}
}
}
}
This function does not need a blocking call (e.g., delay() which sits there until the time has elapsed). Now, whenever the DFP is NOT playing, the LED will be pulsing.
In the beginning of the code use:
#define LED 9 // led a pin 9
#define pulseDelay 60 // millis
int brightness = 20; // how bright the LED is
int fadeAmount = 5; // how many points to fade the LED by
Notice that I added pulseDelay and defined it as 60, which is the millisecond delay you had been using.
Finally, use:
void loop() {
sensorActivated();
fadingLED();
}
Additionally, you're using analog write values from 20-100. Remember, this is not a percentage. The range is 0-255. You can modify this easily.
Even if you want it flashing while playing, there is, hopefully, enough in the answer that you might find helpful
It only works if I call fadingLED()
... what does that mean? ... how is it failing?when certain conditions are given
... list the conditions insteadDFplayer status:
and so on printed?