Arduino 7 Segment Display Clock: With and Without RTC

In this post we are going to learn how to construct 4 digit – 7 segment display digital clock using Arduino, we will be constructing two digital clocks, one with RTC and one without RTC module.

We will see:

  • Multiplexing 4 digit-7 segment display.
  • Circuit Diagram of 7 Segment Clock without RTC.
  • Circuit Description.
  • Program Code.
  • How to Set Time.
  • Accuracy of Digital Clock without RTC.
  • Circuit Diagram of 7 segment Clock with RTC.
  • Circuit Description.
  • Program Code.
  • How to Set Time to RTC.
  • Accuracy of RTC Based Digital Clock
  • Prototype Images.

How to multiplex 4 Digit-7 Segment Displays:

The proposed 7 segment clock is a four digit timepiece with couple of LEDs blinking at the rate of 1 Hz between hour and minute digits. The 4 digits are multiplexed to reduce the number of wires that connects from Arduino to 7 segment displays, this will also reduce the power consumption significantly; with the equivalent power consumption of just one 7 segment display we can power 4 or more digits without any noticeable reduction in brightness, this is a huge advantage if you are powering this clock using batteries.

Multiplexed 4 digit display
Multiplexed 4 digit display

Multiplexing is done when there are two or more 7 segment displays exist, multiplexing is done by connecting individual segments (A to G) together like illustrated in the above schematic and the common terminals of 7 segment display are treated as “select lines”, with the help of select lines we can turn ON or OFF the individual 7 segment display.

While multiplexing the digits, at any given time only one digit lights up and rest of the three digits stays OFF, but this occurs 100s of time per second such that we will perceive all the digits lit up simultaneously.

To know more on how multiplexing works in detail, click here after you finish reading this post.

7 Segment Display Clock without RTC

Arduino 7 Segment clock without RTC

Circuit Description:

The proposed circuit consists of Arduino which is the brain of this project and four 7 segment displays which are multiplexed. There are two LEDs which blink at the rate of 1 Hz; these two LEDs are to be placed between the hour and minute digits and there are two push buttons provided to the set time.

Here are the detailed connection between Arduino and 7 segment display:

SegmentsArduino Pins
A2
B3
C4
D5
E6
F7
G8
DP9

Common TerminalArduino Pin
D110
D211
D312
D413

Download the “SevSeg” library before compiling this code: click here

Program Code:

//------Electronics-project-hub.com-----//
#include "SevSeg.h"
SevSeg Display;
const unsigned long period = 1000; //one second
const unsigned long led_period = 500; //LED blink millisecond
unsigned long startMillis;
unsigned long led_startMillis;
unsigned long currentMillis;
unsigned long led_currentMillis;
const int hrs_btn = A0;
const int min_btn = A1;
const int ledPin = A2;
int Hrs = 12;
int Min = 0;
int Sec = 0;
int Time;
int ledState = LOW;
void setup()
{
  pinMode(hrs_btn, INPUT_PULLUP);
  pinMode(min_btn, INPUT_PULLUP);
  pinMode(ledPin, OUTPUT);
  byte numDigits = 4;
  byte digitPins[] = {10, 11, 12, 13};
  byte segmentPins[] = {2, 3, 4, 5, 6, 7, 8, 9};
  bool resistorsOnSegments = false;
  bool updateWithDelays = false;
  byte hardwareConfig = COMMON_CATHODE;
  bool leadingZeros = true;
  bool disableDecPoint = true;
  Display.begin(hardwareConfig, numDigits, digitPins, segmentPins, resistorsOnSegments, updateWithDelays, leadingZeros, disableDecPoint);
  Display.setBrightness(100);
}
void loop()
{
  currentMillis = millis();
  if (currentMillis - startMillis >= period)
  {
    Sec = Sec + 1;
    startMillis = currentMillis;
  }
  led_currentMillis = millis();
  if (led_currentMillis - led_startMillis >= led_period)
  {
    led_startMillis = led_currentMillis;
    if (ledState == LOW)
    {
      ledState = HIGH;
      if (digitalRead(hrs_btn) == LOW)
      {
        Hrs = Hrs + 1;
      }
      if (digitalRead(min_btn) == LOW)
      {
        Min = Min + 1;
        Sec = 0;
      }
    }
    else
    {
      ledState = LOW;
    }
    digitalWrite(ledPin, ledState);
  }
  if (Sec == 60)
  {
    Sec = 0;
    Min = Min + 1;
  }
  if (Min == 60)
  {
    Min = 0;
    Hrs = Hrs + 1;
  }
  if (Hrs == 13)
  {
    Hrs = 1;
  }
  Time = Hrs * 100 + Min;
  Display.setNumber(Time);
  Display.refreshDisplay();
}
//------Electronics-project-hub.com-----//

How to Set Time:

The clock will display 12:00 when you power the circuit and the two LEDs starts to blink.

  • Pressing hour button will increment the hour digit; you can set hours from 1 to 12.
  • Pressing minute button will increment minute digit; you can set 00 to 59.
  • Release the hour/minute button when the display is showing correct hour/minute.

The hours and minutes digits will increment by one for every second after you depress the push button.

How Accurate is this RTC-less Digital Clock:

The proposed clock without RTC may drift +/- 30 seconds a day or more depending on the ambient temperature variations. The variation might get accumulated over time and may drift couple of minutes or more a week, so you might need to set the correct time again, but need not to worry much, as you can set the correct time easily with just couple of clicks.

The time variation is because of the clock signal generated by the crystal varies with the temperature; the clock signal is not precisely 16MHz but very close to it. Temperature variation of few degrees will change the oscillation frequency of the crystal by a fraction, but this tiniest error accumulates over time and deviate from the correct time. Most of the Arduino boards don’t use a high quality crystal oscillator, some even uses resonator instead of crystal.     

How to make a 7 segment clock with RTC

Circuit Diagram:

Arduino 7 Segment Clock with RTC
Arduino 7 Segment Clock with RTC

Circuit Description:

The circuit consists of Arduino which is the brain of the project and a RTC module DS1307 or DS3231 is the heart of the project and this circuit sport four 7 segment displays which are multiplexed. A couple of LEDs placed in between hour and minute digits.

Here are the detailed connection between Arduino and 7 segment display:

SegmentsArduino Pins
A2
B3
C4
D5
E6
F7
G8
DP9

Common TerminalArduino Pin
D110
D211
D312
D413

The RTC module consist of a 3V (CR2032) lithium non-rechargeable battery which can serve this module for more than couple of years without any external power . It keeps track of seconds, minutes, hours, date, month and year with leap year. But we are going to only extract hours and minute data from the RTC module.

To interface RTC module we just need to wire up four wires 5V, GND, SDA (Serial Data) and SCL (Serial Clock) to Arduino. The RTC module can detect power failure and will switch to battery mode instantly.

Download and add the following library files to the IDE:

DS3231.h: click here

SevSeg.h: click here

How to Set Time to RTC DS1307 /DS3231:

The clock will display 12:00 when you power the circuit and the two LEDs starts to blink.

  • Press Hrs button to increment hour digits, stop when correct hour is displaying.
  • Press Min button to increment minute digit, stop when correct minute is displaying.
  • Now disconnect the power, wait for 10 seconds and power the clock again, you should see the time set by you is still running.

Program code for 7 Segment RTC Clock:

//----------(C)Electronics-project-hub.com------------//
#include "SevSeg.h"
#include <DS3231.h>
DS3231  rtc(SDA, SCL);
Time  t;
SevSeg Display;
const int hrs_set = A0;
const int min_set = A1;
const int ledPin =  A3;
unsigned int number = 0;
const long interval = 500;
unsigned long startMillis;
unsigned long currentMillis;
unsigned long previousMillis = 0;
unsigned int Hour = 0;
unsigned int hrs_var = 0;
unsigned int min_var = 0;
int ledState = LOW;

void setup()
{
  rtc.begin();
  pinMode(ledPin, OUTPUT);
  pinMode(hrs_set, INPUT_PULLUP);
  pinMode(min_set, INPUT_PULLUP);
  byte numDigits = 4;
  byte digitPins[] = {10, 11, 12, 13};
  byte segmentPins[] = {2, 3, 4, 5, 6, 7, 8, 9};
  bool resistorsOnSegments = false;
  bool updateWithDelays = false;
  byte hardwareConfig = COMMON_CATHODE;
  bool leadingZeros = true;
  bool disableDecPoint = true;
  Display.begin(hardwareConfig, numDigits, digitPins, segmentPins, resistorsOnSegments, updateWithDelays, leadingZeros, disableDecPoint);
  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);
  }
  t = rtc.getTime();
  Hour = t.hour;
  hrs_var = t.hour;
  min_var = t.min;
  if (t.hour > 12)
  {
    if (t.hour == 13) Hour = 1;
    if (t.hour == 14) Hour = 2;
    if (t.hour == 15) Hour = 3;
    if (t.hour == 16) Hour = 4;
    if (t.hour == 17) Hour = 5;
    if (t.hour == 18) Hour = 6;
    if (t.hour == 19) Hour = 7;
    if (t.hour == 20) Hour = 8;
    if (t.hour == 21) Hour = 9;
    if (t.hour == 22) Hour = 10;
    if (t.hour == 23) Hour = 11;
  }
  else
  {
    if (t.hour == 0) Hour = 12;
  }
  number = Hour * 100 + t.min;
  Display.setNumber(number);
  Display.refreshDisplay();
  if (digitalRead(hrs_set) == LOW)
  {
    hrs_var += 1;
    if (hrs_var > 23) hrs_var = 0;
    rtc.setTime(hrs_var, min_var, 0);
    for (int i = 0; i < 1000; i ++)
    {
      Display.setNumber(number);
      Display.refreshDisplay();
    }
  }
  if (digitalRead(min_set) == LOW)
  {
    min_var += 1;
    if (min_var >= 60) min_var = 0;
    rtc.setTime(hrs_var, min_var, 0);
    for (int i = 0; i < 1000; i ++)
    {
      Display.setNumber(number);
      Display.refreshDisplay();
    }
  }
}
//----------(C)Electronics-project-hub.com------------//

NOTE: The above code can support DS3231 and DS1307 RTC modules.

Accuracy of Digital Clock with RTC Module:

We can witness time deviation anywhere between +/- few seconds a month if you are using DS3231 or a couple of minutes per month if you are using DS1307. A good quality RTC will have minimal time deviation, but cheaper DS1307 module from china will have more time deviation, this is because there is no temperature compensation for the crystal.

To get higher accuracy you may switch to DS3231 RTC which has temperature compensated crystal, it has time deviation of just 63 seconds per year or 5.25 seconds per month as per its datasheet. Some users reported that by using DS3231 they are just drifting 1 second per month, DS3231 is slightly more expensive than DS1307 RTC and it worth the cost.

How to Test the 7 Segment Display?

In the comments we can see some beginners are not able to successfully build this clock in their first attempt, this is because of the tedious wiring work involved in connecting 7 segment display. Some are getting partial output from this clock i.e the time is not displaying correctly or some segments are not lighting up or dimly lighting up or the 7 segment displays are acting randomly. This is a strong sign of poor wiring work / incorrectly connected segments.

To check whether your wiring connections associated with the display and Arduino are correct or not, please upload the below given code to Arduino. When you upload this code to Arduino all the four display starts to count in this fashion: 0000, 1111, 2222, 3333, till 9999 and repeats.

Now, if your connections are not correct or poorly soldered you can spot them easily and correct them.

Display test code for 4 digit 7 segment display:

//------Electronics-project-hub.com-----//
#include "SevSeg.h"
SevSeg Display;
unsigned long startMillis;
unsigned long led_startMillis;
unsigned long currentMillis;
unsigned long led_currentMillis;
const int hrs_btn = A0;
const int min_btn = A1;
const int ledPin = A2;
int Hrs = 12;
int Min = 0;
int Sec = 0;
int number = 0;
int ledState = LOW;
void setup()
{
  pinMode(hrs_btn, INPUT_PULLUP);
  pinMode(min_btn, INPUT_PULLUP);
  pinMode(ledPin, OUTPUT);
  digitalWrite(ledPin, HIGH);
  byte numDigits = 4;
  byte digitPins[] = {10, 11, 12, 13};
  byte segmentPins[] = {2, 3, 4, 5, 6, 7, 8, 9};
  bool resistorsOnSegments = false;
  bool updateWithDelays = false;
  byte hardwareConfig = COMMON_CATHODE;
  bool leadingZeros = true;
  bool disableDecPoint = true;
  Display.begin(hardwareConfig, numDigits, digitPins, segmentPins, resistorsOnSegments, updateWithDelays, leadingZeros, disableDecPoint);
  Display.setBrightness(100);
}
void loop()
{
  number = 0;
  for (int j = 0; j < 10; j++)
  {
    for (int i = 0; i < 3000; i++)
    {
      Display.setNumber(number);
      Display.refreshDisplay();
    }
    number = number + 1111;
  }
}
//------Electronics-project-hub.com-----//

Prototype Images:

Arduino 7 Segment Clock
Arduino 7 Segment Clock
Arduino 7 Segment Clock
Arduino 7 Segment Clock
Arduino 7 Segment Clock
Arduino 7 Segment Clock

If you have any question regarding this project, feel free to comment, you will get a guaranteed reply from us.

Top Comments by real people:

It’s a awesome project I have made it with RTC it’s work awesome but some fractional second slow if you ignore it that works fine
Thank you to the Developer for built this beautiful project…..

Sujoy Sarkararkar (Reader)

Thank you very much Sir for posting this beautiful project. I am an hobbyist. I have already made one with RTC successfully following your instructions………….

RAJESH CHAKRABORTY (Reader)

Avatar photo

My nick name is blogthor, I am a professional electronics engineer specialized in Embedded System. I am a experienced programmer and electronics hardware developer. I am the founder of this website, I am also a hobbyist, DIYer and a constant learner. I love to solve your technical queries via comment section.