How to get this script to play the only mp3 file on the card every 20 minutes

Hi there.

This is my first project.

What do I need to add to this in order to repeat playing the first (and only) track on the sd card? It plays fine now every time I push the reset button, but I want to repeat the message over and over again every 20 minutes. TIA:

/*
 * Created by ArduinoGetStarted.com
 *
 * This example code is in the public domain
 *
 * Tutorial page: https://arduinogetstarted.com/tutorials/arduino-mp3-player
 */


#include <SoftwareSerial.h>

#define CMD_PLAY_NEXT 0x01
#define CMD_PLAY_PREV 0x02
#define CMD_PLAY_W_INDEX 0x03
#define CMD_SET_VOLUME 0x06
#define CMD_SEL_DEV 0x09
#define CMD_PLAY_W_VOL 0x22
#define CMD_PLAY 0x0D
#define CMD_PAUSE 0x0E
#define CMD_SINGLE_CYCLE 0x19

#define DEV_TF 0x02
#define SINGLE_CYCLE_ON 0x00
#define SINGLE_CYCLE_OFF 0x01

#define ARDUINO_RX 7  // Arduino Pin connected to the TX of the Serial MP3 Player module
#define ARDUINO_TX 6  // Arduino Pin connected to the RX of the Serial MP3 Player module

SoftwareSerial mp3(ARDUINO_RX, ARDUINO_TX);

void setup() {
  Serial.begin(9600);
  mp3.begin(9600);
  delay(500);  // wait chip initialization is complete

  mp3_command(CMD_SEL_DEV, DEV_TF);  // select the TF card
  delay(200);                        // wait for 200ms

  mp3_command(CMD_PLAY, 0x0000);       // Play mp3
  //mp3_command(CMD_PAUSE, 0x0000);      // Pause mp3
  //mp3_command(CMD_PLAY_NEXT, 0x0000);  // Play next mp3
  //mp3_command(CMD_PLAY_PREV, 0x0000);  // Play previous mp3
  //mp3_command(CMD_SET_VOLUME, 30);     // Change volume to 30
}

void loop() {
  
}

void mp3_command(int8_t command, int16_t dat) {
  int8_t frame[8] = { 0 };
  frame[0] = 0x7e;                // starting byte
  frame[1] = 0xff;                // version
  frame[2] = 0x06;                // the number of bytes of the command without starting byte and ending byte
  frame[3] = command;             //
  frame[4] = 0x00;                // 0x00 = no feedback, 0x01 = feedback
  frame[5] = (int8_t)(dat >> 8);  // data high byte
  frame[6] = (int8_t)(dat);       // data low byte
  frame[7] = 0xef;                // ending byte
  for (uint8_t i = 0; i < 8; i++) {
    mp3.write(frame[i]);
  }
}

Conceptually, when you exit setup, set up a 20-minute timer and replicate the appropriate code in the main loop. At the end of the loop, just set the timer again.

I have been trying something like that, but I can't make it work.
I add this at the very top and it still compiles:



unsigned long previousMillis = 0; // Stores the last time the action was performed
const long interval = 20 * 60 * 1000; // 20 minutes in milliseconds (20 * 60 seconds * 1000 milliseconds/second)

Then I do not know what to do. Anything I have tried will not compile.

Do you have any specific suggestions for a total newbbie?
Thanks.

Try the example sketch File/Example/Digital/blink without delay (or may be slightly different on your system.

The blink without delay will give you an example that blinks the LED every second or so. You should simply increase the interval to the number of milliseconds in 20 minutes. Verify the led blinks (start with 1 minute for ease of testing).

Now add the lines to play your mp3 file.

const long interval = 1000;  // interval at which to blink (milliseconds)
1 Like

That will work, but I was thinking of an actual timer. There are lot's of examples. Timers are different depending on the hardware. Since you didn't say just do a search of EXAMPLE nano AND timer example sketch.

Like a hardware timer? I think it will be difficult to get a hardware timer clock slow enough for 20 minutes (but I've not tried).

This is similar to what I have tried. I used the example and cut/pasted

Then I get this error:
Compilation error: 'mp3_command' was not declared in this scope

This is how my code looks now:


/*
 * Created by ArduinoGetStarted.com
 *
 * This example code is in the public domain
 *
 * Tutorial page: https://arduinogetstarted.com/tutorials/arduino-mp3-player
 */
// Generally, you should use "unsigned long" for variables that hold time
// The value will quickly become too large for an int to store
unsigned long previousMillis = 0;  // will store last time LED was updated

// constants won't change:
const long interval = 1000;  // interval at which to blink (milliseconds)

#include <SoftwareSerial.h>

#define CMD_PLAY_NEXT 0x01
#define CMD_PLAY_PREV 0x02
#define CMD_PLAY_W_INDEX 0x03
#define CMD_SET_VOLUME 0x06
#define CMD_SEL_DEV 0x09
#define CMD_PLAY_W_VOL 0x22
#define CMD_PLAY 0x0D
#define CMD_PAUSE 0x0E
#define CMD_SINGLE_CYCLE 0x19

#define DEV_TF 0x02
#define SINGLE_CYCLE_ON 0x00
#define SINGLE_CYCLE_OFF 0x01

#define ARDUINO_RX 7  // Arduino Pin connected to the TX of the Serial MP3 Player module
#define ARDUINO_TX 6  // Arduino Pin connected to the RX of the Serial MP3 Player module

SoftwareSerial mp3(ARDUINO_RX, ARDUINO_TX);

void setup() {
  Serial.begin(9600);
  mp3.begin(9600);
  delay(500);  // wait chip initialization is complete

  mp3_command(CMD_SEL_DEV, DEV_TF);  // select the TF card
  delay(200);                        // wait for 200ms

  mp3_command(CMD_PLAY, 0x0000);       // Play mp3
  //mp3_command(CMD_PAUSE, 0x0000);      // Pause mp3
  //mp3_command(CMD_PLAY_NEXT, 0x0000);  // Play next mp3
  //mp3_command(CMD_PLAY_PREV, 0x0000);  // Play previous mp3
  //mp3_command(CMD_SET_VOLUME, 30);     // Change volume to 30
}

void loop() {
  
}
// check to see if it's time to blink the LED; that is, if the difference
  // between the current time and last time you blinked the LED is bigger than
  // the interval at which you want to blink the LED.
  unsigned long currentMillis = millis();

  if (currentMillis - previousMillis >= interval) {
    // save the last time you blinked the LED
    previousMillis = currentMillis;
void mp3_command(int8_t command, int16_t dat) {
  int8_t frame[8] = { 0 };
  frame[0] = 0x7e;                // starting byte
  frame[1] = 0xff;                // version
  frame[2] = 0x06;                // the number of bytes of the command without starting byte and ending byte
  frame[3] = command;             //
  frame[4] = 0x00;                // 0x00 = no feedback, 0x01 = feedback
  frame[5] = (int8_t)(dat >> 8);  // data high byte
  frame[6] = (int8_t)(dat);       // data low byte
  frame[7] = 0xef;                // ending byte
  for (uint8_t i = 0; i < 8; i++) {
    mp3.write(frame[i]);
  }
}

What on earth does that mean? A hardware timer can run anywhere from 1 second or even less to 24 hours or even more.
Did you try to google the answer?

I can see several errors. I still don't know what platform. Post your complete verbose error log in code tags.

Sorry, I thought it was a running list of past errors and only the last line was current:

C:\Users\Home Desktop\Documents\Arduino\100\100.ino: In function 'void setup()':
C:\Users\Home Desktop\Documents\Arduino\100\100.ino:41:3: error: 'mp3_command' was not declared in this scope
   mp3_command(CMD_SEL_DEV, DEV_TF);  // select the TF card
   ^~~~~~~~~~~
C:\Users\Home Desktop\Documents\Arduino\100\100.ino: At global scope:
C:\Users\Home Desktop\Documents\Arduino\100\100.ino:59:3: error: expected unqualified-id before 'if'
   if (currentMillis - previousMillis >= interval) {
   ^~
exit status 1

Compilation error: 'mp3_command' was not declared in this scope

I understand you might be rattled a bit. Look at your code maybe do a Tools / Auto Format so perhaps you can see one huge error. Another more subtle error is you have 3 variables that are to do with a single concept. At the moment it will work but when you extend to 20 mins it will fail. That is a clue.

You have 2 errors in that log, they are quite easy to understand and fix. Have you reformatted the code yet? If you still can't see one of them, start folding and it should be obvious.

After you reformat your code, hopefully you can fix one of the errors. When you do post it again.

Thanks, I am looking. I'm old and have to change my thought process so it takes longer, but I like to stay as current as I can with technology,....

I am 83, are you older?

Still waiting to know what board (it makes a BIG difference) and to see at least consistently formatted code. Anyone can do those two things.

Does anyone see a problem here?

Here is a clue for you.

A millis()

Returns the number of milliseconds passed since the Arduino board began running the current program. This number will overflow (go back to zero), after approximately 50 days.

Yep, that's one problem.

My gast was well and truly flabbered after that. If only there was a tool that would make basic errors easier to see...

I'm just going to throw this out there for whatever good it might do someone.

#define SECONDS 1000ul;
#define MINUTES 60ul * SECONDS;
#define HOURS 60ul * MINUTES;

unsigned long lastTime;
const unsigned long interval = 20 * MINUTES;

void setup() {
   Serial.begin(115200);
   lastTime = millis();
}

void loop() {
   if( millis() - lastTime > interval ) {
      lastTime = millis();
      do_something();
   }
}

void do_something() {
   Serial.println("Hello, world!");
}
1 Like