I made a clock using esp8266 nodemcu and Df player mini with DS1307 rtc , I took the code from internet which originally made for wifi clock, my modified code works fine as expected, plays hourly chime but after powering it up it works perfectly for 1st hour but in the 2nd hour it frizzes. If I power it up in 5:00 pm it plays hourly chime in 6:00 pm perfectly but when it about to reach at 6:59 then it fezzes until it restart it. I tried with watchdog function but no changes seen.
max7219.h (2.9 KB)
fonts.h (11.3 KB)
#include "Arduino.h"
#include <Wire.h>
#include "RTClib.h"
#include <RTClib.h>
#include <SoftwareSerial.h>
#include <DFRobotDFPlayerMini.h>
RTC_DS1307 RTC;
SoftwareSerial mySoftwareSerial(0, 2); // RX, TX
DFRobotDFPlayerMini myDFPlayer;
//String date;
#define NUM_MAX 4
#define LINE_WIDTH 16
#define ROTATE 90
// for NodeMCU 1.0
#define DIN_PIN 15 // D8
#define CS_PIN 13 // D7
#define CLK_PIN 12 // D6
#include "max7219.h"
#include "fonts.h"
static uint8_t last_second = 0;
int hour2;
const int buttonHourPin = 3; // RX(GPIO3)
const int buttonMinutePin = 14; // D5
int lastButtonHourState = HIGH; // Assuming HIGH when not pressed
int lastButtonMinuteState = HIGH; // Assuming HIGH when not pressed
// =======================================================================
// CHANGE YOUR CONFIG HERE:
// =======================================================================
void setup() {
Wire.begin();
RTC.begin();
//RTC.adjust(DateTime(F(__DATE__), F(__TIME__)));
mySoftwareSerial.begin(9600);
myDFPlayer.begin(mySoftwareSerial);
myDFPlayer.volume(6);
// Serial.begin(115200);
initMAX7219();
sendCmdAll(CMD_SHUTDOWN, 1);
pinMode(buttonHourPin, INPUT_PULLUP);
pinMode(buttonMinutePin, INPUT_PULLUP);
//Serial.print("Connected to RTC module.");
}
// =======================================================================
#define MAX_DIGITS 16
byte dig[MAX_DIGITS] = { 0 };
byte digold[MAX_DIGITS] = { 0 };
byte digtrans[MAX_DIGITS] = { 0 };
int updCnt = 0;
int dots = 0;
long dotTime = 0;
long clkTime = 0;
int dx = 0;
int dy = 0;
byte del = 0;
int h, m, s;
long localEpoc = 0;
long localMillisAtUpdate = 0;
// =======================================================================
void loop() {
yield(); // Prevent watchdog reset
DateTime now = RTC.now();
h = now.hour();
m = now.minute();
s = now.second();
if (last_second != now.second()) {
if ((now.minute() == 59) && (now.second() == 58)) {
hour2 = now.hour();
hour2++;
chime();
}
last_second = now.second();
}
if (updCnt <= 0) { // every 10 scrolls, ~450s=7.5m
updCnt = 10;
//Serial.println("Getting DateTime now ...");
//printStringWithShift(" Getting DateTime now", 15);
DateTime now();
//Serial.println("DateTime now loaded");
clkTime = millis();
}
if (millis() - clkTime > 20000 && !del && dots) { // clock for 15s, then scrolls for about 30s
//printStringWithShift(date.c_str(), 40);
//delay(7000);
updCnt--;
clkTime = millis();
}
if (millis() - dotTime > 500) {
dotTime = millis();
dots = !dots;
}
updateTime();
showAnimClock();
handleButtons();
// Adjusting LED intensity.
// 12am to 6am, lowest intensity 0
//if ((h == 0) || ((h >= 1) && (h <= 6))) sendCmdAll(CMD_INTENSITY, 3);
// 6pm to 11pm, intensity = 2
//else if ((h >= 18) && (h <= 23)) sendCmdAll(CMD_INTENSITY, 3);
// max brightness during bright daylight
sendCmdAll(CMD_INTENSITY, 3);
}
void handleButtons() {
int buttonHourState = digitalRead(buttonHourPin);
int buttonMinuteState = digitalRead(buttonMinutePin);
if (buttonHourState == LOW && lastButtonHourState == HIGH) {
delay(100);
h = (h + 1) % 24;
updateRTC();
}
if (buttonMinuteState == LOW && lastButtonMinuteState == HIGH) {
delay(100);
m = (m + 1) % 60;
updateRTC();
}
lastButtonHourState = buttonHourState;
lastButtonMinuteState = buttonMinuteState;
}
void updateRTC() {
DateTime now = RTC.now();
RTC.adjust(DateTime(now.year(), now.month(), now.day(), h, m, now.second()));
}
bool chimeTimeout(int chimeHour) {
unsigned long start = millis();
myDFPlayer.play(chimeHour);
while (!myDFPlayer.available()) {
if (millis() - start > 2000) return false; // 2-second timeout
}
return true;
}
void chime() {
yield(); // Allow ESP to reset watchdog before risky code
int chimeHour = hour2 % 12;
if (chimeHour == 0) chimeHour = 12;
if (!chimeTimeout(chimeHour)) {
Serial.println("DFPlayer timeout! Reset might be needed.");
// Optional: reset DFPlayer or ignore
}
yield(); // Again after DFPlayer call
}
// =======================================================================
void showSimpleClock() {
dx = dy = 0;
clr();
// Convert hours to 12-hour format and set AM/PM
// Convert hours to 12-hour format and set AM/PM
int displayHour = h % 12;
int isPM = h >= 12;
if (!displayHour) displayHour = 12;
showDigit(displayHour / 10, 4, dig6x8);
showDigit(displayHour % 10, 12, dig6x8);
showDigit(m / 10, 21, dig6x8);
showDigit(m % 10, 29, dig6x8);
showDigit(s / 10, 38, dig6x8);
showDigit(s % 10, 46, dig6x8);
setCol(19, dots ? B00100100 : 0);
setCol(36, dots ? B00100100 : 0);
refreshAll();
}
void showAnimClock() {
byte digPos[4] = { 1, 8, 17, 25 };
int digHt = 12;
int num = 4;
int i;
if (del == 0) {
del = digHt;
for (i = 0; i < num; i++) digold[i] = dig[i];
int temp = h % 12;
if (!temp) temp = 12;
dig[0] = temp / 10 ? temp / 10 : 10;
dig[1] = temp % 10;
dig[2] = m / 10;
dig[3] = m % 10;
for (i = 0; i < num; i++) digtrans[i] = (dig[i] == digold[i]) ? 0 : digHt;
} else
del--;
clr();
for (i = 0; i < num; i++) {
if (digtrans[i] == 0) {
dy = 0;
showDigit(dig[i], digPos[i], dig6x8);
} else {
dy = digHt - digtrans[i];
showDigit(digold[i], digPos[i], dig6x8);
dy = -digtrans[i];
showDigit(dig[i], digPos[i], dig6x8);
digtrans[i]--;
}
}
dy = 0;
setCol(15, dots ? B00100100 : 0);
refreshAll();
delay(60);
}
// =======================================================================
void showDigit(char ch, int col, const uint8_t *font) {
if (dy < -8 || dy > 8) return;
int len = pgm_read_byte(font);
int w = pgm_read_byte(font + 1 + ch * len);
col += dx;
for (int i = 0; i < w; i++)
if (col + i >= 0 && col + i < 8 * NUM_MAX) {
byte v = pgm_read_byte(font + 1 + ch * len + 1 + i);
if (!dy) scr[col + i] = v;
else scr[col + i] |= dy > 0 ? v >> dy : v << -dy;
}
}
// =======================================================================
void setCol(int col, byte v) {
if (dy < -8 || dy > 8) return;
col += dx;
if (col >= 0 && col < 8 * NUM_MAX)
if (!dy) scr[col] = v;
else scr[col] |= dy > 0 ? v >> dy : v << -dy;
}
// =======================================================================
int showChar(char ch, const uint8_t *font) {
int len = pgm_read_byte(font);
int i, w = pgm_read_byte(font + 1 + ch * len);
for (i = 0; i < w; i++)
scr[NUM_MAX * 8 + i] = pgm_read_byte(font + 1 + ch * len + 1 + i);
scr[NUM_MAX * 8 + i] = 0;
return w;
}
// =======================================================================
void printCharWithShift(unsigned char c, int shiftDelay) {
if (c < ' ' || c > '~' + 25) return;
c -= 32;
int w = showChar(c, font);
for (int i = 0; i < w + 1; i++) {
delay(shiftDelay);
scrollLeft();
refreshAll();
}
}
// =======================================================================
void printStringWithShift(const char *s, int shiftDelay) {
while (*s) {
printCharWithShift(*s, shiftDelay);
s++;
}
}
// =======================================================================
void updateTime() {
}