Arduino 7 Segment Display Clock: With and Without RTC

In this post we are going to learn how to construct 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.

The proposed 7 segment clock design 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 power consumption of just one 7 segment display we can power 4 digits or more without any noticeable reduction in brightness with the same current draw, this is a boon if you are powering this clock using batteries. This is possible with a technique called multiplexing, let’s take a look briefly.

Multiplexing 4 Digit-7 Segment Displays:

Circuit Diagram:

Multiplexed 4 digit display
Multiplexed 4 digit display

Multiplexing is done when there are two or more 7 segment displays, multiplexing is done by connecting individual segments together like illustrated in the above schematic. The common terminals of a 7 segment display are treated as “select lines”, with the help of select lines we can enable or disable the individual displays.

While multiplexing at any given time only one digit lights up and rest of the 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 complete 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 is the detailed connection between Arduino and 7 segment display:

[Segment to Arduino Pin]: A – 2, B – 3, C – 4, D – 5, E – 6, F – 7, G – 8, DP – 9.

[Common terminals to Arduino Pin]: D1 – 10, D2 – 11, D3 – 12, D4 – 13.

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 = true;
  bool updateWithDelaysIn = true;
  byte hardwareConfig = COMMON_CATHODE;
  Display.begin(hardwareConfig, numDigits, digitPins, segmentPins, resistorsOnSegments);
  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.

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 of button.

The time vary because of the clock 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 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

Circuit Description:

The circuit consists of Arduino which is the brain and RTC module DS1307 or DS3231 which is heart of the project and four 7 segment displays which are multiplexed.

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

[Segment to Arduino Pin]: A – 2, B – 3, C – 4, D – 5, E – 6, F – 7, G – 8, DP – 9.

[Common terminals to Arduino Pin]: D1 – 10, D2 – 11, D3 – 12, D4 – 13.

The RTC has a 3V (CR2032) lithium non-rechargeable battery which can serve this module for more than couple of years even when no power supply is given. It keeps track of seconds, minutes, hours, date, month and year with leap year compensation. But we are going to extract only hours and minute information from 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. The Couple of blinking LEDs must be placed between hour and minute digits.

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 hours digits, stop when correct hours is displaying.
  • Press Min button to increment minutes digit, stop when correct minutes 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------------//

Accuracy of Digital Clock with RTC Module:

We can witness time deviation anywhere between +/- few seconds a month if you are using DS3231 to 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 high 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 data sheet. Some users reported that using DS3231 they are just drifting 1 second per month making it most accurate RTC, but 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 the first attempt, this is because of tedious wiring work involved in connecting 7 segment display. Most of them are getting partial output from this clock i.e the time is not displaying correctly or some segments are not lighting up / dimly lighting up or some times displays are acting randomly. This is a strong sign of poor wiring work / incorrectly connected segments.

When we were building this clock we faced these issues too, the one and only thing to be blame is our wiring with the display. We made a display test code which will count 0 to 9. When you upload this code to Arduino all the four display starts to count in this fashion: 1111 2222 3333 …… 9999.

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;
void setup()
{
  byte numDigits = 4;
  byte digitPins[] = {10, 11, 12, 13};
  byte segmentPins[] = {2, 3, 4, 5, 6, 7, 8, 9};
  bool resistorsOnSegments = true;
  bool updateWithDelaysIn = true;
  byte hardwareConfig = COMMON_CATHODE;
  Display.begin(hardwareConfig, numDigits, digitPins, segmentPins, resistorsOnSegments);
  Display.setBrightness(100);
}

void loop()
{
  Display.setNumber(0000);
  Display.refreshDisplay();
  delay(1500);
  Display.setNumber(1111);
  Display.refreshDisplay();
  delay(1500);
  Display.setNumber(2222);
  Display.refreshDisplay();
  delay(1500);
  Display.setNumber(3333);
  Display.refreshDisplay();
  delay(1500);
  Display.setNumber(4444);
  Display.refreshDisplay();
  delay(1500);
  Display.setNumber(5555);
  Display.refreshDisplay();
  delay(1500);
  Display.setNumber(6666);
  Display.refreshDisplay();
  delay(1500);
  Display.setNumber(7777);
  Display.refreshDisplay();
  delay(1500);
  Display.setNumber(8888);
  Display.refreshDisplay();
  delay(1500);
  Display.setNumber(9999);
  Display.refreshDisplay();
  delay(1500);
}
//-------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)

Blogthor

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.