Help with code for DS3132 and dfplayer mini combo on Elegoo Uno r3

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.

Any help or insight would be appreciated!

Thanks!

You should use pins other than 0 and 1 for your software serial port as these pins are used by the hardware serial port.

2 Likes

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().

@anon26492357

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.
:slightly_smiling_face:

#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
  }
}

Ok, thank you! Which pins should I use rather?

Did you not see or try the corrected code I sent you three hours ago?

It gave me this:

exit status 1
'randomTrackNumber' was not declared in this scope

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.

@anon26492357

To whom are you replying, me or Paul?

As I said in post #4, my code gives no compile error and runs fine.

That was a mistake you made and not related to any of my suggestions.

Understood. I'm just here for help to decipher this issue, I'm aware it is my mistake, just not sure how to fix it.

I told you how to fix it!

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.