Leading zeros on a 4-digit 7-segment display

Hi everybody,

I was playing around with some parts and wanted to use an Arduino Mega2560 R3 in combination with a 74HC595 IC and a DS1307 Real-Time-Clock module to display the time on a 5641AS 4-digit 7-segment display.

All in all the code (see below) is working but I couldn't figure out how to reliably show leading zeros without messing up the time display when there are not needed.
I.e.: 3:05 PM is currently shown as 15 5 instead of 1505.

Here's the code. I'm still pretty new to this whole thing and it is rather frankenstein'ed together from different sources, so bear with me:

#include <Wire.h>
#include <DS3231.h>

DS3231 clock;
RTCDateTime dt;

int latch = 3;    //74HC595  pin 9 STCP
int clocksh = 4;  //74HC595  pin 10 SHCP
int data = 2;     //74HC595  pin 8 DS

unsigned char table[] = { 0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f, 0x77, 0x7c, 0x39, 0x5e, 0x79, 0x71, 0x00 };  //Display  digital data

const int nbrDigits = 4;  // the number of digits in the LED display
                          //dig 0 1 2 3
const int digitPins[nbrDigits] = { 5, 6, 7, 8 };


void setup() {

  clock.begin();
  clock.setDateTime(__DATE__, __TIME__);

  //Configuring  output pins for the 74HC595
  pinMode(latch, OUTPUT);
  pinMode(clocksh, OUTPUT);
  pinMode(data, OUTPUT);

  //Configuring output pins for common cathod of  each 7 segment digit
  for (int i = 0; i < nbrDigits; i++) {
    pinMode(digitPins[i], OUTPUT);
    digitalWrite(digitPins[i], HIGH);
  }
}

void loop() {

  dt = clock.getDateTime();

  DisplayHours(dt.hour);
  DisplayMinutes(dt.minute);
  delay(1);
}

void DisplayHours(int hour) {
  if (hour == 0) {
    DisplayDigit(0, 0);  // display 0 in digit 0 (leftmost digit)
    DisplayDigit(0, 1);  // didplay 0 in digit 1
  } else {
    //  display the value corresponding to each digit
    for (int digit = 1; digit >= 0; digit--) {
      if (hour > 0) {
        DisplayDigit(hour % 10, digit);
        hour = hour / 10;
      }
    }
  }
}

void DisplayMinutes(int minute) {
  if (minute == 0) {
    DisplayDigit(0, 2);  // display 0 in digit 2
    DisplayDigit(0, 3);  // display 0 in digit 3 (rightmost digit)
  } else {
    //  display the value corresponding to each digit
    for (int digit = 3; digit >= 2; digit--) {
      if (minute > 0) {
        DisplayDigit(minute % 10, digit);
        minute = minute / 10;
      }
    }
  }
}

//Function  to display on one seven segments digit
void DisplayDigit(unsigned char num, int digit) {
  digitalWrite(latch, LOW);
  shiftOut(data, clocksh, MSBFIRST, table[num]);
  digitalWrite(latch, HIGH);

  digitalWrite(digitPins[digit], LOW);
  delay(4);
  digitalWrite(digitPins[digit], HIGH);
}

Your code for minutes and hours generation is overcomplicated. You have display two digit only, you don't need do it with for loop:

More easy to calculate each minute digit separately:

DisplayDigit(minute % 10, 4);
DisplayDigit(minute / 10, 3);

With these lines you also don't need a separate code for (minute == 0 ) case.

Also your functions DisplayHour() and DisplayMinute are very similar, the only difference is the display position numbers. Pass them to the function parameters and you will able to use single function for both cases.

Simpler is (almost) always better!

#include <Wire.h>
#include <DS3231.h>

DS3231 clock;
RTCDateTime dt;

const int latch = 3;    //74HC595  pin 9 STCP
const int clocksh = 4;  //74HC595  pin 10 SHCP
const int data = 2;     //74HC595  pin 8 DS

const unsigned char table[] = { 0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f, 0x77, 0x7c, 0x39, 0x5e, 0x79, 0x71, 0x00 };  //Display  digital data

const int nbrDigits = 4;  // the number of digits in the LED display
                          //dig 0 1 2 3
const int digitPins[nbrDigits] = { 5, 6, 7, 8 };


void setup() {

  clock.begin();
  clock.setDateTime(__DATE__, __TIME__);

  //Configuring  output pins for the 74HC595
  pinMode(latch, OUTPUT);
  pinMode(clocksh, OUTPUT);
  pinMode(data, OUTPUT);

  //Configuring output pins for common cathod of  each 7 segment digit
  for (int i = 0; i < nbrDigits; i++) {
    pinMode(digitPins[i], OUTPUT);
    digitalWrite(digitPins[i], HIGH);
  }
}

void loop() {

  dt = clock.getDateTime();

  DisplayDigit(dt.hour / 10, 0);
  DisplayDigit(dt.hour % 10, 1);
  DisplayDigit(dt.minute / 10, 2);
  DisplayDigit(dt.minute % 10, 3);
}

//Function  to display on one seven segments digit
void DisplayDigit(unsigned char num, int digit) {
  digitalWrite(latch, LOW);
  shiftOut(data, clocksh, MSBFIRST, table[num]);
  digitalWrite(latch, HIGH);

  digitalWrite(digitPins[digit], LOW);
  delay(4);
  digitalWrite(digitPins[digit], HIGH);
}

Next challenge: do it without delay()

Yep, that did it. Thank you guys!

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