As my final contribution here is a version for hardware serial. Read it carefully and make appropriate pin changes to suit your board, as this is for my MEGA2560, where it works correctly.
Good luck.
/*
Fri 29 Aug 2025; Revised for a board using hadware serial,
MEGA2560 in my case.
*/
#include <DFRobotDFPlayerMini.h> // download this library from Arduino IDE "Manage Libraries"
int pirPin = 3; // my edit
int ledPin = 13; //Arduino built-in LED, and a more visible one
int motionStatus = 0; // variable to store the PIR's current reading (high or low)
int pirState = 0; // variable to store the PIR's state change
int track = 1; // variable to store current track number
// Serial1: Rx=19 (to DFR Tx),Tx=18 (to 1k then DFR Rx)
DFRobotDFPlayerMini fxPlayer;
void setup()
{
pinMode(pirPin, INPUT); // set Arduino pin that PIR is connected to as an INPUT
pinMode(ledPin, OUTPUT); // my edit
Serial.begin(115200); // my preference
delay(200);
Serial1.begin(9600);
delay(200);
fxPlayer.begin(Serial1); // tells mp3 player to use Serial1 for communication
delay(1000); // my edit
fxPlayer.volume(15); // my edit // mp3 player volume (pick a value 10-30)
delay(8000); // my edit, allow say 8 secs for PIR sensor to settle
Serial.println("Setup ended");
}
void loop()
{
motionStatus = digitalRead(pirPin); // read the PIR pin's current output (is it HIGH or LOW?)
// if PIR pin output is HIGH:
if (motionStatus == HIGH)
{
if (pirState == LOW)
{
Serial.println("Motion Detected"); // print result to the serial monitor
digitalWrite(ledPin, LOW); // turn OFF built-in LED
pirState = HIGH; // update the previous PIR state to HIGH
fxPlayer.play(track); // play up to 3 s of current track
// delay(1000); // // my edit length in MILLIseconds of the current track
// delay(5000); // length in microseconds of the longest track
track++; // add 1 to the current track for the next loop
// if track number tries to exceed 5 (I have 5 total in my case)
if (track > 5)
{ // change this value to match your total # of tracks
track = 1; // reset track number to 1
}
}
}
// or else if PIR pin output is LOW:
else
{
// if (pirState == LOW)
if (pirState == HIGH)
{
Serial.println("Motion Ended"); //print result to the serial monitor
digitalWrite(ledPin, HIGH); // turn ON built-in LED
pirState = LOW; // update the previous PIR state to LOW
}
}
}