//RTC Clock(date, time) + serial epoch time input + yx5300 - mp3 player
#include <TimeAlarms.h>
#include <TimeLib.h>
#include <TM1637Display.h>
#include <Wire.h>
#include <DS3231RTC.h>
// Module connection pins (Digital Pins)
#define CLK 11
#define DIO 12
/* Include DigitLedDisplay Library */
#include "DigitLedDisplay.h"
// yx5300
#include <SoftwareSerial.h>
#define ARDUINO_RX 3 //should connect to TX of the Serial MP3 Player module
#define ARDUINO_TX 4 //connect to RX of the module
SoftwareSerial mp3(ARDUINO_RX, ARDUINO_TX);
String mp3Answer; // Answer from the MP3.
static int8_t Send_buf[8] = {0}; // Buffer for Send commands. // BETTER LOCALLY
static uint8_t ansbuf[10] = {0}; // Buffer for the answers. // BETTER LOCALLY
DigitLedDisplay ld = DigitLedDisplay(5, 6, 7); //din, cs, clk
TM1637Display display(CLK, DIO);
bool tick = false;
bool isMP3Playing = false;
// button
const int buttonPin = 10;
int buttonState = 0;
#define DEBUG 0
/************ Command byte **************************/
#define CMD_NEXT_SONG 0X01 // Play next song.
#define CMD_PREV_SONG 0X02 // Play previous song.
#define CMD_PLAY_W_INDEX 0X03
#define CMD_VOLUME_UP 0X04
#define CMD_VOLUME_DOWN 0X05
#define CMD_SET_VOLUME 0X06
#define CMD_SNG_CYCL_PLAY 0X08 // Single Cycle Play.
#define CMD_SEL_DEV 0X09
#define CMD_SLEEP_MODE 0X0A
#define CMD_WAKE_UP 0X0B
#define CMD_RESET 0X0C
#define CMD_PLAY 0X0D
#define CMD_PAUSE 0X0E
#define CMD_PLAY_FOLDER_FILE 0X0F
#define CMD_STOP_PLAY 0X16
#define CMD_FOLDER_CYCLE 0X17
#define CMD_SHUFFLE_PLAY 0x18 //
#define CMD_SET_SNGL_CYCL 0X19 // Set single cycle.
#define CMD_SET_DAC 0X1A
#define DAC_ON 0X00
#define DAC_OFF 0X01
#define CMD_PLAY_W_VOL 0X22
#define CMD_PLAYING_N 0x4C
#define CMD_QUERY_STATUS 0x42
#define CMD_QUERY_VOLUME 0x43
#define CMD_QUERY_FLDR_TRACKS 0x4e
#define CMD_QUERY_TOT_TRACKS 0x48
#define CMD_QUERY_FLDR_COUNT 0x4f
/************ Opitons **************************/
#define DEV_TF 0X02
/*********************************************************************/
void setup() {
ld.setBright(1);
ld.setDigitLimit(8);
display.setBrightness(3);
Serial.begin(9600);
while (!Serial) ; // wait until Arduino Serial Monitor opens
mp3.begin(9600);
setSyncProvider(RTC.get); // the function to get the time from the RTC
setSyncInterval(600);
if (timeStatus() != timeSet)
Serial.println("Unable to sync with the RTC");
else
Serial.println("RTC has set the system time");
Serial.print("Temp : ");
Serial.println(RTC.getTemp() - 2); //compensate
sendCommand(CMD_SEL_DEV, DEV_TF);
delay(500);
Alarm.alarmRepeat(23, 59, 0, MorningAlarm);
pinMode(buttonPin, INPUT);
}
void loop() {
if (Serial.available()) {
time_t t = processSyncMessage();
if (t != 0) {
RTC.set(t); // set the RTC and the system time to the received value
setTime(t);
Serial.println(t);
}
}
//------------ tick tock flashing
if (tick == true) {
display.showNumberDecEx(hour() * 100 + minute(), (0x80 >> 1), true);
} else {
display.showNumberDecEx(hour() * 100 + minute(), 0, true);
}
tick = !tick;
ld.printDigit(year(), 4);
ld.printDigit(month(), 2);
ld.printDigit(day(), 0);
Alarm.delay(500);
//if (!isMP3Playing) MorningAlarm();
buttonState = digitalRead(buttonPin);
if (buttonState == HIGH && isMP3Playing) {
sendCommand(CMD_STOP_PLAY, 0);
}
// Check for the mp3 answer.
if (mp3.available()) Serial.println(decodeMP3Answer());
}
// functions to be called when an alarm triggers:
void MorningAlarm() {
Serial.println("Alarm: - actions here");
sendCommand(CMD_PLAY, 0);
sendCommand(CMD_SET_VOLUME, 5);
sendCommand(CMD_FOLDER_CYCLE, 0x0101);
isMP3Playing = true;
}
/* code to process time sync messages from the serial port */
#define TIME_HEADER "T" // Header tag for serial time sync message
unsigned long processSyncMessage() {
unsigned long pctime = 0L;
const unsigned long DEFAULT_TIME = 1357041600; // Jan 1 2013
if (Serial.find(TIME_HEADER)) {
pctime = Serial.parseInt();
return pctime;
if ( pctime < DEFAULT_TIME) { // check the value is a valid time (greater than Jan 1 2013)
pctime = 0L; // return 0 to indicate that the time is not valid
}
}
return pctime;
}
/********************************************************************************/
/*Function decodeMP3Answer: Decode MP3 answer. */
/*Parameter:-void */
/*Return: The */
String decodeMP3Answer() {
String decodedMP3Answer = "";
decodedMP3Answer += sanswer();
switch (ansbuf[3]) {
case 0x3A:
decodedMP3Answer += " -> Memory card inserted.";
break;
case 0x3D:
decodedMP3Answer += " -> Completed play num " + String(ansbuf[6], DEC);
break;
case 0x40:
decodedMP3Answer += " -> Error";
break;
case 0x41:
decodedMP3Answer += " -> Data recived correctly. ";
break;
case 0x42:
decodedMP3Answer += " -> Status playing: " + String(ansbuf[6], DEC);
break;
case 0x48:
decodedMP3Answer += " -> File count: " + String(ansbuf[6], DEC);
break;
case 0x4C:
decodedMP3Answer += " -> Playing: " + String(ansbuf[6], DEC);
break;
case 0x4E:
decodedMP3Answer += " -> Folder file count: " + String(ansbuf[6], DEC);
break;
case 0x4F:
decodedMP3Answer += " -> Folder count: " + String(ansbuf[6], DEC);
break;
}
return decodedMP3Answer;
}
/********************************************************************************/
/*Function: Send command to the MP3 */
/*Parameter:-int8_t command */
/*Parameter:-int16_ dat parameter for the command */
void sendCommand(int8_t command, int16_t dat)
{
delay(20);
Send_buf[0] = 0x7e; //
Send_buf[1] = 0xff; //
Send_buf[2] = 0x06; // Len
Send_buf[3] = command;//
Send_buf[4] = 0x01; // 0x00 NO, 0x01 feedback
Send_buf[5] = (int8_t)(dat >> 8); //datah
Send_buf[6] = (int8_t)(dat); //datal
Send_buf[7] = 0xef; //
Serial.print("Sending: ");
for (uint8_t i = 0; i < 8; i++)
{
mp3.write(Send_buf[i]) ;
Serial.print(sbyte2hex(Send_buf[i]));
}
Serial.println();
}
/********************************************************************************/
/*Function: sbyte2hex. Returns a byte data in HEX format. */
/*Parameter:- uint8_t b. Byte to convert to HEX. */
/*Return: String */
String sbyte2hex(uint8_t b)
{
String shex;
shex = "0X";
if (b < 16) shex += "0";
shex += String(b, HEX);
shex += " ";
return shex;
}
/********************************************************************************/
/*Function: sanswer. Returns a String answer from mp3 UART module. */
/*Parameter:- uint8_t b. void. */
/*Return: String. If the answer is well formated answer. */
String sanswer(void)
{
uint8_t i = 0;
String mp3answer = "";
// Get only 10 Bytes
while (mp3.available() && (i < 10))
{
uint8_t b = mp3.read();
ansbuf[i] = b;
i++;
mp3answer += sbyte2hex(b);
}
// if the answer format is correct.
if ((ansbuf[0] == 0x7E) && (ansbuf[9] == 0xEF))
{
return mp3answer;
}
return "???: " + mp3answer;
}