Hello. I am trying to make a simple device that will randomly play up to 5 short mp3 files at random times during weekdays between 7am-4pm with a random delay of one hour up to 4 hours. It is for a harmless workplace prank.
Using DS3132 RTC module and dfplayer mini mp3 player
Here is my code so far:
#include <Wire.h>
#include <RTClib.h>
#include <DFRobotDFPlayerMini.h>
#include <SoftwareSerial.h>
static const uint8_t PIN_MP3_RX = 0; // Connect MP3 TX to Uno's RX (pin 0)
static const uint8_t PIN_MP3_TX = 1; // Connect MP3 RX to Uno's TX (pin 1)
SoftwareSerial softwareSerial(PIN_MP3_RX, PIN_MP3_TX);
DFRobotDFPlayerMini player;
RTC_DS3231 rtc;
const int trackCount = 5;
const int tracks[] = {1, 2, 3, 4, 5}; // Replace with your actual track numbers
void setup() {
Serial.begin(9600);
softwareSerial.begin(9600);
if (!rtc.begin()) {
Serial.println("Couldn't find RTC");
while (1);
}
if (rtc.lostPower()) {
Serial.println("RTC lost power, let's set the time!");
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
}
if (player.begin(softwareSerial)) {
Serial.println("MP3 Player OK");
} else {
Serial.println("MP3 Player FAIL!");
}
player.volume(30);
}
void loop() {
// Check if it's a weekday and within the specified time frame
DateTime now = rtc.now();
if (now.dayOfTheWeek() >= 1 && now.dayOfTheWeek() <= 5 && now.hour() >= 7 && now.hour() <= 16) {
// Generate a random time delay between 1 and 4 hours (3600 seconds per hour)
int randomDelay = random(3600, 4 * 3600 + 1);
delay(randomDelay * 1000); // Convert seconds to milliseconds
// Randomly select a track from the array
int randomTrackIndex = random(0, trackCount);
int randomTrackNumber = tracks[randomTrackIndex];
// Play the randomly selected track
player.play(randomTrackNumber);
}
}
If wired correctly, is this feasible? I'm brand new at coding.
This function often causes problems. It probably won't play the tracks you expect it to.
Instead, use
player.playMp3Folder(randomTrackNumber);
and place all your tracks into a folder called MP3 on the SD card.
I also wonder if you are making the code more complex than it needs to be. Do you plan to put more tracks on the SD card than will be randomly chosen? For example do you plan to put 30 tracks on the card, but select only 5 of them to play randomly, and the other 25 will never be played? Or will you put only 5 tracks on the card and any of them will be played, randomly.
If you plan to put only 5 tracks on the card and play any of them randomly, then your tracks[] array is not needed, and it doesn't matter if you use player.play() or player.playMp3Folder().
The following runs OK on my Nano. Check my comments to see why yours didn't.
P.S. I kept your names, but I always prefer to get the string 'my' in there somewhere.
#include <Wire.h>
#include <RTClib.h>
#include <DFRobotDFPlayerMini.h>
#include <SoftwareSerial.h>
static const uint8_t PIN_MP3_RX = 8; // for my breadboard
// static const uint8_t PIN_MP3_RX = 0; // Connect MP3 TX to Uno's RX (pin 0)
static const uint8_t PIN_MP3_TX = 9; // for my breadboard
// static const uint8_t PIN_MP3_TX = 1; // Connect MP3 RX to Uno's TX (pin 1)
SoftwareSerial softwareSerial(PIN_MP3_RX, PIN_MP3_TX);
DFRobotDFPlayerMini player; // I'd have preferred 'myDFPlayer'
RTC_DS3231 rtc;
// Array not necessary? I'd just play the randomly chosen track
// (But consider seeding randomTrackNumber, for example with
// randomSeed(analogRead(0) or similar)
//const int trackCount = 5;
//const int tracks[] = {1, 2, 3, 4, 5}; // Replace with your actual track numbers
void setup()
{
Serial.begin(115200);
delay(200);
softwareSerial.begin(9600);
rtc.begin(); // Missing from original
// So not initialised.
// Not sure about this if(), as no compile error with yours
if (!rtc.begin())
{
Serial.println("Couldn't find RTC");
while (1);
}
if (rtc.lostPower())
{
Serial.println("RTC lost power, let's set the time!");
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
}
player.begin(softwareSerial); // Start communication with DFPlayer
delay(1000); // Often proves necessary
// Yours below reported 'MP3 Player FAIL' consistently.
// So I've replaced with my usual equivalent conditionals.
// (I often omit altogether.)
// if (player.begin(softwareSerial))
// {
// Serial.println("MP3 Player OK");
// }
// else
// {
// Serial.println("MP3 Player FAIL!");
// }
if (!player.begin(softwareSerial, 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 online."));
player.setTimeOut(1000);
//----Set volume----
player.volume(20); // BTW, 30 can cause voltage drop
// issue in some circuits; have not seen yours.
delay(500);
Serial.println("end setup"); // No crash so far
}
void loop()
{
// Check if it's a weekday and within the specified time frame
// Me: It's Friday here; I've not tested weekend.
DateTime now = rtc.now();
if (now.dayOfTheWeek() >= 1 && now.dayOfTheWeek() <= 5 && now.hour() >= 7 && now.hour() <= 16)
{
// Generate a random time delay between 1 and 4 hours (3600 seconds per hour)
int randomDelay = random(2000, 11000); // 2 to 10 s for testing
// int randomDelay = random(3600, 4 * 3600 + 1);
// delay(randomDelay * 1000); // Convert seconds to milliseconds
// Randomly select a track from the array; see above
// int randomTrackIndex = random(0, trackCount);
int randomTrackNumber = random(1, 6); // 1 to 5
// int randomTrackNumber = tracks[randomTrackIndex];
// Play the randomly selected track
player.play(randomTrackNumber);
delay(randomDelay); // Original had none
}
}
It now uses the alternative function I suggested. But because of the other changes you made, that change was no longer needed. I explained that in my previous post.