I'd like to put together a gift for a friend that is a musical clock that plays a custom mp3/wav audio clip on-the-hour. Each hour a different clip.
A few ideas come to mind but I'm not sure if I'm on the right path.
I've never used the RTC module but assuming I could create a if/then statement in reference to the real time which would send a serial command to maybe a DFPlayer module to play a specific track/file?
I made a clock using a Wemos Mini, DFPlayer mini, speaker and a 60-led ws2812 circle. I can post the code later if you think it would help. Did not use an RTC, the Wemos gets time from NTC over WiFi, but it does use the Time library, which I expect you will also be using, so some of the code should be useful to you.
I'm trying to wrap my head around alarms and if I'm able to send separate commands to the DFPlayer.
Did you use a DFPlayer library? Did you use serial CMD commands to choose track, etc..?
This is a battery project and trying to reduce the power consumption, having the ability to use the SHDN pin on the DFPlayer to toggle the unit on an off. Maybe have a alarm start 5 seconds before the top of the hour, and then shut down after.
I made a clock using a Wemos Mini, DFPlayer mini, speaker and a 60-led ws2812 circle. I can post the code later if you think it would help. Did not use an RTC, the Wemos gets time from NTC over WiFi, but it does use the Time library, which I expect you will also be using, so some of the code should be useful to you.
Paul's code will get you most of the way there. I would use a DS3231 RTC using Jack Christensen's DS3232.h library. It is available through the library manager. It is designed to be integrated with the Time Library and becomes a synchronization source for the internal clock.
I’m not sure how to set the specific time(s) for each if/then statements.
#include "Arduino.h"
#include <TimeLib.h>
#include "DFRobotDFPlayerMini.h"
#include <DS3232RTC.h>
DFRobotDFPlayerMini myDFPlayer;
void setup()
{
Serial.begin(9600);
setSyncProvider(RTC.get); // the function to get the time from the RTC
//----Set DFPlayer Defualts----
myDFPlayer.volume(10); //Set volume value (0~30).
myDFPlayer.outputDevice(DFPLAYER_DEVICE_SD);
void loop()
if (t != 0) {
RTC.set(t); // set the RTC and the system time to the received value
setTime(t);
{
if(hour() != lastHour) { //do something
myDFPlayer.playFolder(1, 1); //play specific mp3 in SD:/1/001.mp3; Folder Name(1~99); File Name(1~255)
}
}
#include "Arduino.h"
#include <TimeLib.h>
#include "DFRobotDFPlayerMini.h"
#include <DS3232RTC.h>
DFRobotDFPlayerMini myDFPlayer;
byte lastHour;
void setup()
{
Serial.begin(9600);
setSyncProvider(RTC.get); // the function to get the time from the RTC
//----Set DFPlayer Defualts----
myDFPlayer.volume(10); //Set volume value (0~30).
myDFPlayer.outputDevice(DFPLAYER_DEVICE_SD);
lastHour = hour();
}
void loop()
{
//if (t != 0) {
// RTC.set(t); // set the RTC and the system time to the received value
// setTime(t);
//{
if (hour() != lastHour) //do something
{
lastHour = hour();
myDFPlayer.playFolder(1, 1); //play specific mp3 in SD:/1/001.mp3; Folder Name(1~99); File Name(1~255)
}
}
I’m not sure how to set the specific time(s) for each if/then statements.
myDFPlayer.playFolder(1, 1);
What if one of the parameters for the DFPlayer was hour()?
hour() is a time library function which returns the current hour. lastHour is a variable which you set in order to determine when the value returned by the hour() function has changed-- that is, the hour has advanced to the next hour. The comparison of a variable with its last value is the standard way of detecting a change.
I would be worth your time to study the Time Library, and what the functions are.
Fo example, if I wanted to play a song at the top of every hour every day
When hour() is not equal to lastHour, you know that you are at the top of a new hour. Its the equivalent to the minute changing from 59 to 0.
would the code be close to this?
No.
I think the best thing to do is set up 23 tracks/files in a DFPlayer folder, and if the hour changes you play the file with the hour number.
I worked a bit on some code last night using an alarm function to see if the basics would work.
Although I can trigger a LED to light as a alarm, I can’t get the DFPlayer to play the file.
If willing, would you all take a look at this code? Thank you!
#include <DS3231.h>
#include "DFRobotDFPlayerMini.h"
// Init the DS3231 using the hardware interface
DS3231 rtc(SDA, SCL);
// Init a Time-data structure
Time t;
int ledPin = 13; // select the pin for the LED
DFRobotDFPlayerMini myDFPlayer;
void setup()
{
// Setup Serial connection
Serial.begin(115200);
// Uncomment the next line if you are using an Arduino Leonardo
//while (!Serial) {}
// Initialize the rtc object
rtc.begin();
// The following lines can be uncommented to set the date and time
//rtc.setDOW(SUNDAY); // Set Day-of-Week to SUNDAY
//rtc.setTime(12, 0, 0); // Set the time to 12:00:00 (24hr format)
//rtc.setDate(1, 1, 2016); // Set the date to DD/MM/YYYY
pinMode(LED_BUILTIN, OUTPUT);
}
void loop()
{
t = rtc.getTime(); // Get data from the DS3231
// Send date over serial connection
Serial.print("Date: ");
Serial.print(t.date, DEC);
Serial.print("/");
Serial.print(t.mon, DEC);
Serial.print("/");
Serial.print(t.year, DEC);
Serial.println();
// Send Day-of-Week and time
Serial.print("Day of Week: ");
Serial.print(t.dow, DEC);
Serial.println();
Serial.print("Time: ");
Serial.print(t.hour, DEC);
Serial.print(":");
Serial.print(t.min, DEC);
Serial.print(":");
Serial.print(t.sec, DEC);
Serial.println();
Serial.println("--------------------------------");
delay(1000); //Delay is for displaying the time in 1 second interval.
if (t.hour == 18 && t.min == 52 && t.sec == 25)
//Setting alarm/timer at every 2:32:53pm,
//in other words you can insert t.dow for every Thursday?, t.date for specific date?
//{ digitalWrite(99, HIGH); delay(5000);
//{
//digitalWrite (ledPin, HIGH); delay(5000);
// }
//else
//{
//digitalWrite (ledPin, LOW);
//delay(10);
//}
{
myDFPlayer.playFolder(1, 1); //play specific mp3 in SD:/1/001.mp3; Folder Name(1~99); File Name(1~255)
}
//Lets say that your component is wired to pin 99 and be switched on for 5 seconds,
//whatever you want to do with it
}
Currently I have the TX/RX of the Uno connected to the RX/TX of the DFPlayer.
Yet, you’re correct…_I forgot to add the serial info.
How does this look?
#include "DFRobotDFPlayerMini.h"
#include "SoftwareSerial.h"
#include <DS3231.h>
// Init the DS3231 using the hardware interface
DS3231 rtc(SDA, SCL);
// Init a Time-data structure
Time t;
int ledPin = 13; // select the pin for the LED
SoftwareSerial mySoftwareSerial(10, 11); // RX, TX
DFRobotDFPlayerMini myDFPlayer;
void setup()
{
// Setup Serial connection
Serial.begin(9600);
// Uncomment the next line if you are using an Arduino Leonardo
//while (!Serial) {}
// Initialize the rtc object
rtc.begin();
// The following lines can be uncommented to set the date and time
//rtc.setDOW(SUNDAY); // Set Day-of-Week to SUNDAY
//rtc.setTime(12, 0, 0); // Set the time to 12:00:00 (24hr format)
//rtc.setDate(1, 1, 2016); // Set the date to DD/MM/YYYY
pinMode(LED_BUILTIN, OUTPUT);
}
void loop()
{
t = rtc.getTime(); // Get data from the DS3231
// Send date over serial connection
Serial.print("Date: ");
Serial.print(t.date, DEC);
Serial.print("/");
Serial.print(t.mon, DEC);
Serial.print("/");
Serial.print(t.year, DEC);
Serial.println();
// Send Day-of-Week and time
Serial.print("Day of Week: ");
Serial.print(t.dow, DEC);
Serial.println();
Serial.print("Time: ");
Serial.print(t.hour, DEC);
Serial.print(":");
Serial.print(t.min, DEC);
Serial.print(":");
Serial.print(t.sec, DEC);
Serial.println();
Serial.println("--------------------------------");
delay(1000); //Delay is for displaying the time in 1 second interval.
if (t.hour == 18 && t.min == 52 && t.sec == 25)
//Setting alarm/timer at every 2:32:53pm,
//in other words you can insert t.dow for every Thursday?, t.date for specific date?
//{ digitalWrite(99, HIGH); delay(5000);
//{
//digitalWrite (ledPin, HIGH); delay(5000);
// }
//else
//{
//digitalWrite (ledPin, LOW);
//delay(10);
//}
{
myDFPlayer.playFolder(1, 1); //play specific mp3 in SD:/1/001.mp3; Folder Name(1~99); File Name(1~255)
}
//Lets say that your component is wired to pin 99 and be switched on for 5 seconds,
//whatever you want to do with it
}
Moving forward, if I wanted to have a different audio track every hour, would I simply add a bunch of IF statements?
Or do I need a ELSE after each?
#include <DFPlayerMini_Fast.h>
#include <SoftwareSerial.h>
#include <avr/sleep.h>
#include <DS3231.h>
// Init the DS3231 using the hardware interface
DS3231 rtc(SDA, SCL);
// Init a Time-data structure
Time t;
SoftwareSerial mySerial(10, 11); // RX, TX
DFPlayerMini_Fast myDFPlayer;
void setup()
{
// Setup Serial connection
Serial.begin(115200);
mySerial.begin(9600);
myDFPlayer.begin(mySerial);
// Uncomment the next line if you are using an Arduino Leonardo
//while (!Serial) {}
// Initialize the rtc object
rtc.begin();
// The following lines can be uncommented to set the date and time
//rtc.setDOW(SUNDAY); // Set Day-of-Week to SUNDAY
//rtc.setTime(12, 0, 0); // Set the time to 12:00:00 (24hr format)
//rtc.setDate(1, 1, 2016); // Set the date to DD/MM/YYYY
//set_sleep_mode (SLEEP_MODE_PWR_DOWN);
//sleep_enable();
//sleep_cpu ();
}
void loop()
{
t = rtc.getTime(); // Get data from the DS3231
// Send date over serial connection
Serial.print("Date: ");
Serial.print(t.date, DEC);
Serial.print("/");
Serial.print(t.mon, DEC);
Serial.print("/");
Serial.print(t.year, DEC);
Serial.println();
// Send Day-of-Week and time
Serial.print("Day of Week: ");
Serial.print(t.dow, DEC);
Serial.println();
Serial.print("Time: ");
Serial.print(t.hour, DEC);
Serial.print(":");
Serial.print(t.min, DEC);
Serial.print(":");
Serial.print(t.sec, DEC);
Serial.println();
Serial.println("--------------------------------");
delay(1000); //Delay is for displaying the time in 1 second interval.
if (t.hour == 0 && t.min == 0 && t.sec == 30)
{
myDFPlayer.play(1); //play mp3 file with leading identifier "0001"
}
}
Moving forward, if I wanted to have a different audio track every hour, would I simply add a bunch of IF statements?
Or do I need a ELSE after each?
It is better practice to use the else if but in your case it probably does not matter if you use if or else if before each conditional. The processor time to execute the additional comparisons which are not going to run will be small.