I came across this post from back in March of 2014, “Demonstration code for several things at the same time.” by Robin2. I have been able to modify the code to accomplish most of what I would like to do. Unfortunately, my programming skills are severely lacking. I used to program in C++ about 25 years ago in college. I have done zero programing since then.
This is for a Pennywise Halloween prop I have been working on. When no one is close to Pennywise there is creepy background music playing. The fog machine kicks off every few minutes as well as the strobe light for a fraction of a second. This helps draw attention to Pennywise. Once people get close and the PIR goes HIGH the background music stops, a fog machine runs, and the strobe light runs for a few seconds then turns off. Finally a couple spotlights turn on to light up Pennywise as an mp3 of Pennywise talking plays, ( the party where he asks Georgy if he would like a balloon). It really freaked some people out last year, but I think I can do a little better because the program was lacking greatly.
Hardware I am using:
Arduino Uno R3
4 Relay Module
PIR Sensor HC-SR501
DFPlayer mini
I would like to play a background MP3 track on repeat while the PIR is LOW, When the PIR goes HIGH a different MP3 track will play. This is the part I am having issues with. I have been able to get the DFPlayer to play music. However, I start playing the background mp3 track in the loop. Obviously, this keeps restarting the mp3 track over and over again.
I could time how long both mp3 tracks are and then create a separate timer function for each track. Like how Robin2 did it. Not sure if that is the best approach, thou.
Thank you for any time you can give me.
Chris
#include <SoftwareSerial.h>
#include <DFRobotDFPlayerMini.h>
// ----CONSTANTS (won't change)
SoftwareSerial mySoftwareSerial(10, 11);
DFRobotDFPlayerMini myDFPlayer;
const int Strobe = A3; //strobe relay
const int Smoke = A1; //smoke relay
const int Spot = A2; //spot relay
const int pirSensor = 8; //PIR sensor to PIN 8
const int Strobe_Interval = 10000; // number of millisecs between Strobe lights
const int Smoke_Interval = 1000; // number of millisecs between fog blasts
const int Spot_Interval = 500; // number of millisecs between spot flashes
const int StrobeDuration = 1000; // number of millisecs that Strobe light is on
const int SmokeDuration = 1000; // number of millisecs that the fog machines is on
const int SpotDuration = 5000; // number of millisecs that the spot is on
//------- VARIABLES (will change)
byte Strobe_State = LOW; // LOW = off
byte Smoke_State = LOW;
byte Spot_State = LOW;
int reading; //to read PIR output
unsigned long currentMillis = 0; // stores the value of millis() in each iteration of loop()
unsigned long previousStrobe_Millis = 0; // will store last time the strobe was flashed
unsigned long previousSmoke_Millis = 0; // will store last time the smoke machine ran
unsigned long previousSpot_Millis = 0; // will store last time the smoke machine ran
//========
void setup() {
Serial.begin(9600);
Serial.println("Starting SeveralThingsAtTheSameTimeRev1.ino"); // so we know what sketch is running
mySoftwareSerial.begin(9600);
myDFPlayer.begin(mySoftwareSerial);
myDFPlayer.setTimeOut(500);
pinMode(pirSensor, INPUT);
pinMode(Strobe, OUTPUT);
pinMode(Smoke, OUTPUT);
pinMode(Spot, OUTPUT);
myDFPlayer.volume(30);
myDFPlayer.EQ(DFPLAYER_EQ_BASS);
myDFPlayer.outputDevice(DFPLAYER_DEVICE_SD);
}
//=======
void loop() {
currentMillis = millis(); // capture the latest value of millis()
// this is equivalent to noting the time from a clock
// use the same time for all LED flashes to keep them synchronized
reading = digitalRead(pirSensor); //read PIR output
if (reading == HIGH) { //PRI is HIGH when there is motion
Serial.println("Motion");
Serial.print("Strobe State = ");
Serial.println(Strobe_State);
Serial.print("Spot State = ");
Serial.println(Spot_State);
Serial.print("Smoke State = ");
Serial.println(Smoke_State);
Serial.print("PIR State = ");
Serial.println(reading);
Strobe_State = HIGH;
Smoke_State = HIGH;
Spot_State = HIGH;
digitalWrite(Strobe, Strobe_State);
digitalWrite(Spot, Spot_State);
digitalWrite(Smoke, Smoke_State);
} else {
Serial.print("pirSensor is - "); //PRI is LOW when there is no motion
Serial.println(reading);
myDFPlayer.enableLoopAll(); //play background music
updateStrobe_State();
updateSpot_State();
updateSmoke_State();
switchState();
}
}
//========
void updateStrobe_State() {
if (Strobe_State == LOW) {
if (currentMillis - previousStrobe_Millis >= Strobe_Interval) {
Strobe_State = HIGH;
previousStrobe_Millis += Strobe_Interval;
}
}
else {
if (currentMillis - previousStrobe_Millis >= StrobeDuration) {
Strobe_State = LOW;
previousStrobe_Millis += StrobeDuration;
}
}
}
//========
void updateSpot_State() {
if (Spot_State == LOW) {
if (currentMillis - previousSpot_Millis >= Spot_Interval) {
Spot_State = HIGH;
previousSpot_Millis += Spot_Interval;
}
}
else {
if (currentMillis - previousSpot_Millis >= SpotDuration) {
Spot_State = LOW;
previousSpot_Millis += SpotDuration;
}
}
}
//=======
void updateSmoke_State() {
if (Smoke_State == LOW) {
if (currentMillis - previousSmoke_Millis >= Smoke_Interval) {
Smoke_State = HIGH;
previousSmoke_Millis += Smoke_Interval;
}
}
else {
if (currentMillis - previousSmoke_Millis >= SmokeDuration) {
Smoke_State = LOW;
previousSmoke_Millis += SmokeDuration;
}
}
}
//========
void switchState() {
// this is the code that actually switches things on and off
digitalWrite(Strobe, Strobe_State);
digitalWrite(Spot, Spot_State);
digitalWrite(Smoke, Smoke_State);
}
//=====END
SeveralThingsAtTheSameTimeRev1.ino (6.3 KB)