Hi Terrypin, thanks for your reply, two points, while I’m in testing mode, I’m using a simple button, in reality it is a PIR sensor, active low when triggered, the four mp3 tracks are various warnings, should an intruder trigger the PIR. I would prefer a completely random selection of the four mp3 tracks while in operation.
Taking in all the ideas and help I’ve gratefully received here, has inspired me to rethink my sketch. I think I can simplify much of the original code, going forward, taking the snippets posted. Jevray
Thanks, you’ve provided some great tips, I’m going to rethink my current sketch, which can become much simpler, so moving forward I will do more testing, taking in your ideas. Just to recap again, the project hinges around an intruder alarm using a PIR (active low) I’m using a button switch during tests, the active low delay time can be preset by the PIR, and I guess the active low may be in the order of 500ms > 1 sec. Thanks again for all your help and support. Will post back results. Jevray
Thanks, that’s helpful. Another important factor might be the length of your four tracks? Timing is important from my recollection of my last PIR project (involving a fox, a lamp, and a video camera, if you’re curious). The active signal after first being triggered was surprisingly long, maybe 5 s; I’ll check my files.
So if you base detection of an intruder on when the PIR signal becomes active, if he/she/they move in and out of sensor range quickly it won’t re-trigger. Are you perhaps over-thinking the testing issue of pressing the button while a track is playing? Does it really matter if the intruder only gets to hear “You are trespassing!” Before making a hasty retreat without waiting for “Police have been alerted!”?
EDIT
I would test with the PIR, not a button.
DFPlayer Mini allows you to connect buttons directly to it.
You don't need an Arduino to do such simple things.
You do need to know that the order you load tracks on the microSD makes the order 1, 2, 3,.... but the player can be run standalone just fine.
Such intruder code needs more smarts than just DFPlayer buttons.
It needs to be able to figure out if the trespasser has left long enough to next time start with track one or play the next, etc.
It needs to be able to alert people and it should also start and stop DV recording as well as keep a log of activations to make security review faster and easier.
Hi Terrypin, a couple of tracks are dog barks, the DFPlayer feeds into a 20watt power amplifier, and nobody hangs about with a dog barking, but if the pin is retriggered while a barking dog can be heard, it sounds like it has hiccups. pin 16 of the DFPlayer has a busy pin (active low), I intend to use it to block the button pin somehow, regardless of the number of presses are made during play mode. (For test purposes only I call it the button pin). Thanks for coming back. Jevray
Very true, the DFPlayer can be triggered by a single pin, providing the trigger pulse is not to long! The problem I have found, that in some cases they don't always trigger using that method, in fact I have one module that will only work in serial mode. Quality is not always that good either, smt issues with some and one had a vcc short to ground, in tern the nano 5v regulator also decided to go short to the Vin putting 12 volts onto the 5 volt lines! In this project arduino it will cover two areas, and monitor when each PIR has been triggered, but thats not for now. But thanks bringing it to my attention. Regards Jevray
It's writing code that I'm not good at, but thanks to those who have posted their technical assistance and guidance, showing the best way forward using examples, helps me tremendously. I remain extremely greatful for their help. Regards jevray
As I asked in post 23, how long is it, and how long are your tracks?
Did you understand what I meant in post 23 by instead detecting
"... when the PIR signal becomes active" ?
And the implication that to use it you would need to add two states?
Or do you want to play track 1 (Dog.mp3) for
a) the exact duration of the low PIR (or test button) signal?
b) longer?
I think there remain several specification decisions like those before you can confidently edit your code and seek further help with it.
I think there’s some confusion, if you trigger pin 9 of the DFPlayer IO-1 the player plays, if you hold it low for to long it reduces the volume, for this project I’ve opted to use serial communication. As previously mentioned, for the purpose of prototype bread board testing, I use a button. The button press (active low) only needs a short duration press before play is activated.. no issues with timing the pulse. Should I make a second press while the track is playing, the program loops back and repeats playing, I’m looking for an action in software to prevent this happening, I.e. blocking the button. Pin 16 is a busy pin and goes low while a track is playing, I can use this feature in the sketch. The only other feature is to be able to select another track after the current one ends, the length of each tracks playing, isn’t a problem using the busy pin. There is also a random track feature within the library, once I can figure out how to include it. Sketch samples have been posted, from which I am looking at. Jevray
OK, I’ll wait for your edited code.
Why not grab the same file?
I'm working on it now.
Test Sketch using " myDFPlayer.randomAll();" from the library. This works, there's a but! It loops a few times, then crashes without returning to the beginning. I noticed the TX led on the nano stays on while the program is running correctly, but is extinguished when the code stops looping. The serial print also shows no loop. Is there a problem with my sketch?
// 05/09/2024
//Boris_ basic test sketch
#include "Arduino.h"
#include "SoftwareSerial.h"
#include "DFRobotDFPlayerMini.h"
#define sensor_f_PIN 12 // Connect buttton to Arduino D12 (PIR)
int BUSY_Pin = 9;
SoftwareSerial mySoftwareSerial(10, 11); // RX, TX
DFRobotDFPlayerMini myDFPlayer;
void setup() {
pinMode(sensor_f_PIN, INPUT); // button pin used for test only ( high 10k to 5v)
pinMode(BUSY_Pin, INPUT); // from pin 16 of DFPlayer
mySoftwareSerial.begin(9600);
Serial.begin(9600);
if (!myDFPlayer.begin(mySoftwareSerial)) //{ //Use softwareSerial to communicate with mp3.
myDFPlayer.volume(4); // set test speaker to low volume
}
void loop() {
Serial.println(F("looped_ready:")); // print loop returned to begining
if (digitalRead(sensor_f_PIN) == LOW) { // low to start playback
delay(20);
myDFPlayer.volume(4); //Set volume value. From 0 to 30
myDFPlayer.randomAll(); //Random play all the mp3.
myDFPlayer.next();
delay(1000);
}
}
Will study on Sunday if not sorted by then. Meanwhile, for a start, try the state change triggering I suggested.
Hi TerryPin, thanks for your feedback, I couldn’t find where you mentioned state change, but I understand what you mean. Yes I’ll look at that, Jevray
That was post 29.
Are you sure about playing random tracks?
Here's the first 20 tracks randomly chosen from a set of say four. (No seeding.)
r = 4
r = 2
r = 2
r = 3
r = 3
r = 1
r = 1
r = 3
r = 4
r = 2
r = 1
r = 2
r = 1
r = 3
r = 4
r = 4
r = 4
r = 2
r = 1
r = 1
Seeding could quickly improve that, of course, but shuffling etc would be more complex and mean accepting 'copy/paste mode' for a while.
It's your project, but I'd personally want to plan exactly what an intruder was hearing, in a specific sequence.
Before I leave in an hour or so I'll breadboard something, no states, no BUSY, that you can experiment with. Back at my PC Sunday evening but meanwhile using iPhone.
Also adding a condition that the same track cannot be played twice in a row.
Tom...
OK, sketch to play with below. Connections straightforward. Photo of breadboard with Nano.
/*
Keep as much of @jevray's original 5 Sep sketch as possible,
such as count method.
Fri 6 Sep 2024; circuit suggestion; NOT yet using
- states
- the DFR BUSY pin
- randomness.
Triggered eventually by low going PIR sensor, but here with a
test button. Brief debouncing delay in loop().
Pending more info, assume a set of at least 4 tracks on the DFR
module's SD card. Mine are all 10 s long: "One, one ,one...",
"Two, two, two", etc, from a set I've previously used.
SETUP: As a check, four LEDs are lit successively. Then all LEDs are
switched off.
LOOP:
On detection, the first ten-second track is played, and its
corrresponding LED lit; a print msg is also sent to the monitor.
If a trigger is received while a track is still playing, it is
ignored. When that track ends nothing happens unti another
trigger received - hopefully from intruder reversing direction?
*/
#include <SoftwareSerial.h>
#include <DFRobotDFPlayerMini.h>
#define RX_PIN 10 // Connect DFPlayer Mini TX pin to Arduino D10
#define TX_PIN 11 // Connect DFPlayer Mini RX pin to Arduino D11
#define sensor_f_PIN 12 // Connect front sensor to Arduino D12
int count = 0;
int busyPin = 9;
byte myLEDpin;
byte redLEDpin = 8;
byte blueLEDpin = 7;
byte grnLEDpin = 6;
byte yelLEDpin = 5;
SoftwareSerial mySerial(RX_PIN, TX_PIN); // RX, TX
DFRobotDFPlayerMini myDFPlayer;
void setup()
{
Serial.begin(115200);
delay(200);
// For later identification, show just sketch file name, not path.
#define __FILENAME__ (strrchr(__FILE__, '\\') ? strrchr(__FILE__, '\\') + 1 : __FILE__)
Serial.println(__FILENAME__);
mySerial.begin(9600);
// if (!myDFPlayer.begin(mySerial)) // extra param removes noise
if (!myDFPlayer.begin(mySerial, true, false))
{
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 initialised OK"));
myDFPlayer.volume(25); // Set volume (0 to 30)
pinMode(sensor_f_PIN, INPUT_PULLUP);
pinMode(busyPin, INPUT);
// Test 4 LEds in succession (8, 7, 6, 5)
for (myLEDpin = 8; myLEDpin >= 5; myLEDpin--)
{
pinMode(myLEDpin, OUTPUT);
}
// Switch then on in succession (8, 7, 6, 5)
for (myLEDpin = 8; myLEDpin >= 5; myLEDpin--)
{
digitalWrite(myLEDpin, HIGH);
delay(500);
}
// Switch them off
for (myLEDpin = 8; myLEDpin >= 5; myLEDpin--)
{
digitalWrite(myLEDpin, LOW);
}
Serial.print(F("setup ended"));
}
//////////////////////////////////////////////////////
void loop()
{
bool sensorReading = digitalRead(sensor_f_PIN); // frequent reads
if (sensorReading == LOW)
{
count++;
if (count == 1)
{
digitalWrite(redLEDpin, HIGH);
Serial.println(F("playing track 1"));
myDFPlayer.play(1);
delay(10000);
}
//--------------------
if (count == 2)
{
digitalWrite(blueLEDpin, HIGH);
Serial.println(F("playing track 2"));
myDFPlayer.play(2);
delay(10000);
}
//--------------------
if (count == 3)
{
digitalWrite(grnLEDpin, HIGH);
Serial.println(F("playing track 3"));
myDFPlayer.play(3);
delay(10000);
}
//--------------------
if (count == 4)
{
digitalWrite(yelLEDpin, HIGH);
Serial.println(F("playing track 4"));
myDFPlayer.play(4);
delay(10000);
count = 0; // reset
}
}
delay(50); // For any bouncing of button to settle; trial/error.
}
Yes, that would be a relatively easy improvement.