Cannot shows 12pm as 12:00

i have make a clock based on max7219 display and ds1307 rtc to shows tome in 12hr format. it works but when it reach on 12pm it shows 0:00 . i want to make it 12:00 . in midnight 12am it shows 0:00 that's no problem but in noon 12 if it showing 0:00 it is problematic. can any one help me?

#include "Arduino.h"
#include <Wire.h>
#include "RTClib.h"
RTC_DS1307 RTC;

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"

// =======================================================================
// CHANGE YOUR CONFIG HERE:
// =======================================================================

void setup() {
  Wire.begin();
  RTC.begin();
  //RTC.adjust(DateTime(F(__DATE__), F(__TIME__)));

  Serial.begin(115200);
  initMAX7219();
  sendCmdAll(CMD_SHUTDOWN, 1);

  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() {
  DateTime now = RTC.now();
  h = now.hour();
  m = now.minute();
  s = 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();

  // Adjusting LED intensity.
  // 12am to 6am, lowest intensity 0
  if ((h == 0) || ((h >= 1) && (h <= 6))) sendCmdAll(CMD_INTENSITY, 4);
  // 6pm to 11pm, intensity = 2
  else if ((h >= 18) && (h <= 23)) sendCmdAll(CMD_INTENSITY, 4);
  // max brightness during bright daylight
  else sendCmdAll(CMD_INTENSITY, 4);
}

// =======================================================================
void showSimpleClock() {
  dx = dy = 0;
  clr();

  // Convert hours to 12-hour format and set AM/PM
  int displayHour = h % 12;
  int isPM = h >= 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];
    dig[0] = (h % 12) / 10 ? (h % 12) / 10 : 10;
    dig[1] = (h % 12) % 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(30);
}

// =======================================================================

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

} 


fonts.h (11.3 KB)
max7219.h (2.9 KB)

I have not looked at all the code but it seems you say that you don't want to treat 12:00 to 12:59 as being the afternoon and subtract 12 so may be you can change

into

  bool isPM = h > 12;

(change the type as well, since it's a truth value)

EDIT - seems you don't use isPM....

the math is done when you do the modulo 12

    dig[0] = (h % 12) / 10 ? (h % 12) / 10 : 10;
    dig[1] = (h % 12) % 10;

that's what you need to change because 12 % 12 is 0

Change this:

to this:

  // Convert hours to 12-hour format and set AM/PM
  int displayHour = h % 12;
  int isPM = h >= 12;
  if ( !displayHour ) displayHour = 12;

do the same inside showAnimClock()

    int temp = h % 12;
    if ( !temp ) temp = 12;
    dig[0] = temp / 10;
    dig[1] = temp % 10;
    ...
1 Like

i tried but not working. showing 12noon as 0:00

I tried but not working. showing 12noon as 0:00

post the modified code

you should not take % 12 otherwise 12 will definitely become 0

just do something like this

byte displayHour = h;
if (displayHour >= 13) displayHour -= 12;

why not just format a string

    char s [80];
    sprintf (s, " %2d:%02d - ", h, m);
    Serial.print (s);

i think some of your math is wrong for determining the individual digits. i get the following when i print dig [0] ... dig [3]

  7:50 -  10 6 4 0
  8:00 -  10 6 4 0
  8:10 -  10 6 4 0
  8:20 -  10 6 4 0
  8:30 -  10 6 4 0
  8:40 -  10 6 4 0
  8:50 -  10 8 5 0
  9:00 -  10 8 5 0
  9:10 -  10 8 5 0
  9:20 -  10 8 5 0
  9:30 -  10 8 5 0
  9:40 -  10 8 5 0
  9:50 -  10 8 5 0
 10:00 -  10 8 5 0
 10:10 -  10 8 5 0
 10:20 -  10 8 5 0
 10:30 -  10 8 5 0
 10:40 -  10 8 5 0
 10:50 -  10 8 5 0
 11:00 -  1 1 0 0
 11:10 -  1 1 0 0
 11:20 -  1 1 0 0
 11:30 -  1 1 0 0
 11:40 -  1 1 0 0
 11:50 -  1 1 0 0
 12:00 -  1 1 0 0
 12:10 -  1 1 0 0
 12:20 -  1 1 0 0
 12:30 -  1 1 0 0
 12:40 -  1 1 0 0
 12:50 -  1 1 0 0
 13:00 -  1 1 0 0
 13:10 -  10 1 1 0
 13:20 -  10 1 1 0
 13:30 -  10 1 1 0
 13:40 -  10 1 1 0

Not Possible to show 12pm as 12:00. till it shows 12pm as 0:00. my modified code with your suggestion.

#include "Arduino.h"
#include <Wire.h>
#include "RTClib.h"
RTC_DS1307 RTC;

String date;

#define NUM_MAX 4
#define LINE_WIDTH 16
#define ROTATE 90

// for NodeMCU 1.0
#define DIN_PIN 11  // D8
#define CS_PIN 10   // D7
#define CLK_PIN 13  // D6

#include "max7219.h"
#include "fonts.h"

// =======================================================================
// CHANGE YOUR CONFIG HERE:
// =======================================================================

void setup() {
  Wire.begin();
  RTC.begin();
  //RTC.adjust(DateTime(F(__DATE__), F(__TIME__)));

  Serial.begin(115200);
  initMAX7219();
  sendCmdAll(CMD_SHUTDOWN, 1);

  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() {
  DateTime now = RTC.now();
  h = now.hour();
  m = now.minute();
  s = 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();

  // Adjusting LED intensity.
  // 12am to 6am, lowest intensity 0
  if ((h == 0) || ((h >= 1) && (h <= 6))) sendCmdAll(CMD_INTENSITY, 4);
  // 6pm to 11pm, intensity = 2
  else if ((h >= 18) && (h <= 23)) sendCmdAll(CMD_INTENSITY, 4);
  // max brightness during bright daylight
  else sendCmdAll(CMD_INTENSITY, 4);
}

// =======================================================================
void showSimpleClock() {
  dx = dy = 0;
  clr();

  // Convert hours to 12-hour format and set AM/PM

  byte displayHour = h;
  if (displayHour >= 13) 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];
    dig[0] = (h % 12) / 10 ? (h % 12) / 10 : 10;
    dig[1] = (h % 12) % 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(30);
}

// =======================================================================

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

Add another fix?

  if (displayHour == 0) displayHour = 12;
  if (displayHour >= 13) displayHour -= 12;

a7

Where is the code displaying 12 as zero.?


This is useless


Why not just h <= 6 ?


I thought he said showing midnight as 0 was fine (eg 0:45am)

yes showing midnight 0 was fine. but noon 0 not. it must be 12.

I don’t see how it would not be 12 with


byte displayHour = h;
  if (displayHour >= 13) displayHour -= 12;

As long as h is within 0 … 23

1 Like

I'm just confused, that is all. I fixed, maybe, the thing that was not broken.

I read this code lines

  byte displayHour = h;
  if (displayHour >= 13) displayHour -= 12;
  showDigit(displayHour / 10, 4, dig6x8);
  showDigit(displayHour % 10, 12, dig6x8);

as displaying 0..12 all by itself, then 1..11 because it's 13:00 to 23:59 fixed by subtraxt 12 or 1:00 to 11:00.

a7

i tried but till it shows 12:00 to 12:59 pm as 0:00 to 0:59. i am also confused. by the way is this related to this part of code ? is there any problem in this part?

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];
    dig[0] = (h % 12) / 10 ? (h % 12) / 10 : 10;
    dig[1] = (h % 12) % 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--;

Sure if you still have h modulo 12 in the code you are doomed

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