Clock freezes in 2nd hour

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

}

I haven't seen a left shift like this before. Did you get any compiler warnings?

Maybe it is the operator priority makes it OK.

EDIT
I've just looked and the expression appears OK. The compound bitwise assignment operator |= is ranked lower than the ? (ternary conditional operator).

I don't have got any compiling error. the clock is running normal, but the problem is when it powered on for more then 1 hour continuously, then in starting of 2nd hour it hangs on until it being restarted. I don't know why this issue occur...

This line of code

    //Serial.println("Getting DateTime now ...");
    //printStringWithShift("  Getting DateTime now", 15);

    DateTime now();
    //Serial.println("DateTime now loaded");

introduces a declaration of a function *now* returning a *DateTime* object.

There is no function now in your code, but it does not matter because you do not attempt to call the function. Anywhere.

So not an error, just prolly not doing what you thought, unless you intended to waste ink with statements that have absolutely no effect.

I'll not guess what you were going for with that line. I do say careful when you fix it. Be aware of the roll scope plays in variable use in C/C++.

It may not have anything to do with you real problem. I suggest placing serial print statements liberally about the code to see what is in key variables and how they are informing flow through the code.

Don't forget to uncomment this if you do any serial printing at all:

//  Serial.begin(115200);

a7

1 Like

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