Arduino Uno 6 digit clock

I had an arduino uno and some modules laying around for some time, and finally I decided to make it a weekend project and put it to useful work, by building a clock that could display the time in HH:MM:SS format.

Digging the web for inspiration, I found many examples that involved an extra 74HC595 shift register and a BCD to 7-segment decoder and a RTC (real time clock) module for greater accuracy.

I had a DS1307RTC module, the problem was that the only 7-segment decoder I found in the junkbox was a CD4511 which can only drive common-cathode dispays, and the displays I had where VQE24E common-anode.
I could’ve added transistors, but for 6 digits there would’ve been a lot of transistors and resistors.

In the end I found about SevSeg.h library, that makes it posibble to drive both common-cathode as well as common-anode displays easily, directly from arduino.

I took inspiration from here for the code: https://electronics-project-hub.com/arduino-7-segment-display-clock-with-and-without-rtc/

Below is my modified code and circuit diagram:

#include "SevSeg.h"
#include <Wire.h>
#include <TimeLib.h>
#include <DS1307RTC.h>
SevSeg Display;
const int ledPin =  A0;
unsigned long timeDisplay;
unsigned long currentMillis;
unsigned int Hour;
int ledState = LOW;
unsigned long previousMillis = 0;
const long interval = 500;
void setup()
{
  pinMode(ledPin, OUTPUT);
  byte numDigits = 6;
  byte digitPins[] = {10, 11, 12, 13, A1, A2};
  byte segmentPins[] = {2, 3, 4, 5, 6, 7, 8, 9};
  bool resistorsOnSegments = false; // false = resistors are on digit pins
  bool updateWithDelaysIn = true;
  byte hardwareConfig = COMMON_ANODE;
  Display.begin(hardwareConfig, numDigits, digitPins, segmentPins, resistorsOnSegments);
  Display.setBrightness(100);
}
void loop()
{
  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis >= interval)
  {
    previousMillis = currentMillis;
    if (ledState == LOW)
    {
      ledState = HIGH;
    }
    else
    {
      ledState = LOW;
    }
    digitalWrite(ledPin, ledState);
  }
  tmElements_t tm;
  if (RTC.read(tm))
  {
    Hour = tm.Hour;
    if (tm.Hour == 0)
    {
      Hour = 24;
    }

    timeDisplay = (Hour * 100 + tm.Minute) * 100L + tm.Second;
  }
  else {
    timeDisplay = 888888; // error
  }
  Display.setNumber(timeDisplay);
  Display.refreshDisplay();
}

In the end I didn’t use the blinking seconds LED, but left the option there.

To set the time on the DS1307 RTC, I followed the instructions in the link above.

On the breadboard there are anode resistors, but I ended up not using them. These displays needed some higher current to lit up well during the day.

I know the box isn’t the prettiest one, but at least it’s a box :)

Later edit (12 june 2020):
It seems that the DS1307 RTC (at leas the one I have) is not so “real”… the clock gained over 60 seconds in almost three weeks. Not very accurate for a clock crystal.

Comments

  1. written by: Md Ashraful Alam on August 12, 2020 at 6:45 am - Reply

    Output one error

    • written by: Mihai on August 25, 2020 at 3:51 pm - Reply

      Hello!
      For me it worked.
      If it does not work for you, dig into it and debug. That is the fun part!
      Good luck!

  2. written by: MITCH MITCHELL on August 15, 2020 at 10:40 pm - Reply

    HI BUDDY. THIS IS EXACTLY WHAT I NEED. DO YOU HAVE A CODE WITH PUSH BUTTONS TO SET TIME. CAN I USE A DS3231 FOR THIS.
    THANKS
    MITCH MITCHELL
    mitch@scotchandsofa.co.za

    • written by: Mihai on August 25, 2020 at 3:47 pm - Reply

      Hello!
      Check the link to the article I’ve mentioned in the text. There is an example with push buttons also.
      You can use any RTC, just include the appropriate library and change the code to read the RTC correctly.
      Good luck!

      • written by: Md Ashraful Alam on August 27, 2020 at 6:50 am - Reply

        Hi, your project is doing the right thing and I could make it. But I can not give any picture here. Clock would have run at 24 hours, but need 12 hours (AM / PM).
        Thank you very much

        • written by: Mihai on August 28, 2020 at 4:35 pm - Reply

          Hello!
          To achieve this you could replace the if statement (line 45 to 48, including those) with something like this:

          if (tm.Hour > 12)
          {
          if (tm.Hour == 13) Hour = 1;
          if (tm.Hour == 14) Hour = 2;
          if (tm.Hour == 15) Hour = 3;
          if (tm.Hour == 16) Hour = 4;
          if (tm.Hour == 17) Hour = 5;
          if (tm.Hour == 18) Hour = 6;
          if (tm.Hour == 19) Hour = 7;
          if (tm.Hour == 20) Hour = 8;
          if (tm.Hour == 21) Hour = 9;
          if (tm.Hour == 22) Hour = 10;
          if (tm.Hour == 23) Hour = 11;
          }
          else
          {
          if (tm.Hour == 0) Hour = 12;
          }

          If you want an AM/PM LED, you could use the seconds indicator LED declared on A0, changing it’s purpose to indicate AM/PM, or declaring a new one on the remaining A3 pin.

          If you discard the seconds indicator to re-use it as AM/PM, delete the lines 27 to 40, as they will no longer be necessary, and in the new if statement (described above), change the LED state according to which part of day is it. For example:

          if (tm.Hour > 12)
          {
          if (tm.Hour == 13) Hour = 1;
          if (tm.Hour == 14) Hour = 2;
          if (tm.Hour == 15) Hour = 3;
          if (tm.Hour == 16) Hour = 4;
          if (tm.Hour == 17) Hour = 5;
          if (tm.Hour == 18) Hour = 6;
          if (tm.Hour == 19) Hour = 7;
          if (tm.Hour == 20) Hour = 8;
          if (tm.Hour == 21) Hour = 9;
          if (tm.Hour == 22) Hour = 10;
          if (tm.Hour == 23) Hour = 11;
          ledState = HIGH; // PM
          }
          else
          {
          if (tm.Hour == 0) Hour = 12;
          ledState = LOW; // AM
          }
          digitalWrite(ledPin, ledState);

          Note that I have not tested this code.
          Have fun!

  3. written by: Peter Putnam on September 3, 2020 at 7:48 pm - Reply

    The result of putting the current-limiting resistor in the digit line shows in the picture of the box where the “1” is brighter than the “4” and the “8” as fewer segments share the digit current. The “3” and the “5” in the middle are equally bright because the same number of segments are illuminated.

    • written by: Mihai on September 13, 2020 at 5:25 pm - Reply

      Actually, that is due to the “Display.setBrightness(100);” line.
      “setBrightness” doesn’t really affect brightness, it controls the update rate of the digits.
      100 = 2000µs delay after each digit
      0 = 1µs delay
      In the picture showing the breadboard, the “setBrightness” was set to 10, meaning the digits were updated faster than in the picture with the box where I’ve set it to 100.
      The naked eye will not notice a difference between 10 and 100, but a camera will.
      A slight difference in illumination can be seen in the breadboard picture also (the 1 and the 6 from seconds).

  4. written by: Santo on September 13, 2020 at 7:40 pm - Reply

    How to add switch?

  5. written by: Abdul on November 5, 2020 at 7:17 pm - Reply

    How to add switch

  6. written by: Rana on December 12, 2020 at 2:53 pm - Reply

    What if I want to use bigger displays?

    • written by: Mihai on January 6, 2021 at 4:38 pm - Reply

      If the bigger displays need more that 1.2V and ~20mA (per segment), then you will need transistors to drive them.
      Otherwise there is no problem.

  7. written by: Adi on March 7, 2021 at 10:11 am - Reply

    I was wondering if i could use non addressable rgb led strips for each segment but i am wondering how would the schematic look like for that option. Some guidance would be much appreciated.

  8. written by: Jerry on April 12, 2021 at 3:02 am - Reply

    I have combined suggestions to make sketch that displays 12 hours, has PM indicator, and uses DS3231 RTC, but still can’t get the time setting buttons to work. Please help. Thanks.

  9. written by: David on October 31, 2021 at 5:36 pm - Reply

    Great project! Could this be done with 6 single digits, instead of 3 duo digits?

    • written by: Mihai on November 2, 2021 at 11:02 am - Reply

      Yes. Same wires/pin connections. The double digits are just two single digits stuck togeter.

  10. written by: barun on February 9, 2022 at 10:32 am - Reply

    Very nice video ..How to add hour and minute switch..
    where to change code.
    please tell me Sir..

    • written by: barun on February 10, 2022 at 1:00 pm - Reply

      please sir…

  11. written by: Mohammed Kittaneh on December 15, 2022 at 4:16 pm - Reply

    Hello,,
    I want project using Ds1302 to view clock on leds and relay

Leave a Reply

Your email address will not be published. Required fields are marked *

− 1 = 1

This site uses Akismet to reduce spam. Learn how your comment data is processed.