# Four Digit Seven Segment Display Clock/Timer

**URL:** <https://forum.arduino.cc/t/four-digit-seven-segment-display-clock-timer/324009>\
**Category:** Programming\
**Created:** [July 15, 2015, 6:41am UTC](https://forum.arduino.cc/t/four-digit-seven-segment-display-clock-timer/324009 "2015-07-15T06:41:35Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![stevenplanet](https://avatars.discourse-cdn.com/v4/letter/s/f05b48/32.png) [@stevenplanet](https://forum.arduino.cc/u/stevenplanet)\
**Post date:** [July 15, 2015, 6:41am UTC](https://forum.arduino.cc/t/four-digit-seven-segment-display-clock-timer/324009/1 "2015-07-15T06:41:35Z")

</div>

I'm having a lot of trouble with this, all I want to do is build a simpletimer. I have pins 9, 10, 11, and 12, attached to the digits and the rest are the segment controls, starting with pin 1 being 'a', etc. I'm using an Arduino UNO. So in setup, I set all the pins to output, and then in loop I do this:

```cpp
int d1=9,d2=10,d3=11,d4=12;
void setup()
{
  int i;
  for(i = 1; i < 13; i++)
    pinMode(i, OUTPUT);
}
 
void loop()
{
  // light up first digit only
  digitalWrite(d2,HIGH);
  digitalWrite(d3,HIGH);
  digitalWrite(d4,HIGH);
  digitalWrite(d1,LOW);
    // light up segments of first digit, display number #1, segments bc
  one();

delay(20);
  // light up second digit only
  digitalWrite(d1,HIGH);
  digitalWrite(d3,HIGH);
  digitalWrite(d4,HIGH);
  digitalWrite(d2,LOW);
  two();
    delay(20);
}

void one()
{
  int i;
  for(i = 0; i < 8; i++)
  {
    if(i == 2 || i == 3)
      digitalWrite(i, HIGH);
    else
      digitalWrite(i, LOW);
  }
}

void two()
{
  int i;
  for(i = 0; i < 8; i++)
  {
    if(i == 1 || i == 2 || i == 4 || i == 5 || i == 7)
      digitalWrite(i, HIGH);
    else
      digitalWrite(i, LOW);
  }
}

```

So I get a the two numbers 21 on the third and fourth digits of my segment, spelling 21. But how would I get it to count up? I get the cycling back and forth but perhaps I need help on the algorithm. I just want it to count up to 100. The problem I see is changing one number while keeping the other static. Any ideas? I've been wrestling with this for a couple of hours, scouring the web but nothing. Do I need shift registers or something? I just have it hooked up directly into the pins using a couple resistors on some of the wires. Thanks!

---

<div class="post-metadata">

**Author:** ![Ps991](https://avatars.discourse-cdn.com/v4/letter/p/43a26b/32.png) [@Ps991](https://forum.arduino.cc/u/Ps991)\
**Post date:** [July 15, 2015, 9:06am UTC](https://forum.arduino.cc/t/four-digit-seven-segment-display-clock-timer/324009/2 "2015-07-15T09:06:04Z")

</div>

Well, first thing I would do is not use delays. I would recommend using interrupts for precise timing.

Basic interrupt timer example code

```cpp
void setup() {
  int frequency = 50; // in hz
  //Interupt Service Routine and timer setup
  noInterrupts();// kill interrupts until everybody is set up
  //We use Timer 1 to refresh the cube, its the only 16 bit timer
  TCCR1A = B00000000;//Register A all 0's since we're not toggling any pins
    // TCCR1B clock prescalers
    // 0 0 1 clkI/O /1 (No prescaling)
    // 0 1 0 clkI/O /8 (From prescaler)
    // 0 1 1 clkI/O /64 (From prescaler)
    // 1 0 0 clkI/O /256 (From prescaler)
    // 1 0 1 clkI/O /1024 (From prescaler)
  TCCR1B = B00001011;//bit 3 set for CTC mode, will call interrupt on counter match, bits 0 and 1 set to divide clock by 64, so 16MHz/64=250kHz
  TIMSK1 = B00000010;//bit 1 set to call the interrupt on an OCR1A match
  OCR1A  = (unsigned long)((250000UL / frequency) - 1UL);//our clock runs at 250kHz, which is 1/250kHz = 4us
  interrupts();//let the show begin, this lets the multiplexing start
}

void loop() {
  
}

ISR(TIMER1_COMPA_vect){ //Interrupt Service Routine, Timer/Counter1 Compare Match A
  
}

```

Now, lets take an arbitrary refresh rate of 60hz per digit and multiply it by 4 digits, this will be our interrupt frequency (240hz).

Now, everytime you go into the interrupt, update the next digit (1,2,3,4,1,2,3,4,1,2,3,4,...) with the number you want.

Advice: Instead of calculating each digit's segments everytime you want to display a number, just use a "decoder", an array holding which segments should be set. Like this,

```cpp
boolean segmentDecoder[10][7] = {{1,1,1,1,1,1,0},{...},{...},{...},{...},{...},{...},{...},{...},{...}}; //10 digits 0-9 each holding 7 segment details. If it is a 1, then turn the segment on

//Example of reading it
//Lets say you want to output a 3
byte segmentDisplay[7] = {the pins to each segment, example, 3,4,5,6,7,8,9};
byte output = 3; //the desired number to display
for(byte i = 0; i < 7; i++)
  digitalWrite(segmentPin[i], segmentDecoder[output][i]);

```

---

<div class="post-metadata">

**Author:** ![stevenplanet](https://avatars.discourse-cdn.com/v4/letter/s/f05b48/32.png) [@stevenplanet](https://forum.arduino.cc/u/stevenplanet)\
**Post date:** [July 15, 2015, 9:38pm UTC](https://forum.arduino.cc/t/four-digit-seven-segment-display-clock-timer/324009/3 "2015-07-15T21:38:03Z")

</div>

Multiplexing! That looks really complicated so please excuse me if that went over my head my friend Ps991, I am still new at this I'm only into my 2nd year as a ECE student. I got down and wrote an algorithm that basically just counts from 0 up. I finally got it to work! The trick is to incorporate the delay between switching digits with the timer! So after each delay I would sum up the delays into an integer and whenever that integer reached 1000ms, I advanced the numbers. And once that seconds hit the 10 digit I would reset it to 0 and advance the tenths digit. Its really rudimentary but itll work! So I was thinking of expanding this to make my own seven segment displays using 12V led strips. Is it possible for the arduino to power this? What else would I need to buy? Thanks for the help by the way! Heres the code for anyone interested!

```cpp
const char d1 = 9, d2 = 10, d3 = 11, d4 = 12; //digit controller (NOT SEGMENT)
const int numDigits = 4; //four digit display
const int interrupt = 5; //in ms, the delay for multiplexing (switching between each digit rapidly to update screen)
int startNum[] = {0, 0, 0, 0};
int loopTime = 0; //controls timer loop, summed from interrupt, everytime it reaches 1000 ms, or 1 second, it increments the seconds digit
const int interval = 100;
void setup() {
  int i;
  for(i = 0; i < 13; i++)
  {
    pinMode(i, OUTPUT); //set all pins :)
  }
}

void loop() {
  // put your main code here, to run repeatedly:
    int digit = d1;
    int number = numDigits - 1;
    int i;
    for(i = 0; i < numDigits; i++)
    {
      selectDigit(digit); //choose from digits 1 through 4 to display
      pickNumber(startNum[number]); //choose a number 0 - 9
      delay(interrupt);
      ++digit; //next digit
      --number; //i started from end of array :) 
    }
    loopTime += interrupt * numDigits;
    if(loopTime == interval) //controls seconds digit
    {
      ++startNum[numDigits - 1];
      if(startNum[numDigits - 1] == 10) //controls tenth digit
      {
        startNum[numDigits - 1] = 0;
        ++startNum[numDigits - 2];
        if(startNum[numDigits - 2] == 10) //controls hundreds digit
        {
          startNum[numDigits - 2] = 0;
          ++startNum[numDigits - 3];
          if(startNum[numDigits - 3] == 10) //thousands! 
          {
            startNum[numDigits - 3] = 0;
            ++startNum[numDigits - 4];
          }
        }
      }
      loopTime = 0;
    }
  }

void selectDigit(int digit)
{
  int i;
  for(i = d1; i < (d4 + 1); i++)
  {
    if(i == digit)
    {
      i++;
    }
    digitalWrite(i, HIGH);
  }
  digitalWrite(digit, LOW);
}

void pickNumber(int x)  //define pickNumber(x)to display number x
{
  switch(x)
  {
  default: 
    zero(); 
    break;
  case 1: 
    one(); 
    break;
  case 2: 
    two(); 
    break;
  case 3: 
    three(); 
    break;
  case 4: 
    four(); 
    break;
  case 5: 
    five(); 
    break;
  case 6:
    six();
    break;
  case 7:
    seven();
    break;
  case 8:
    eight();
    break;
  case 9: 
    nine();
    break;
  }
}

void zero()
{
  digitalWrite(1, HIGH);
  digitalWrite(2, HIGH);
  digitalWrite(3, HIGH);
  digitalWrite(4, HIGH);
  digitalWrite(5, HIGH);
  digitalWrite(6, HIGH);
  digitalWrite(7, LOW);
}

void one()  // define 1 as cathode pin switch
{
  digitalWrite(1, LOW);
  digitalWrite(2, HIGH);
  digitalWrite(3, HIGH);
  digitalWrite(4, LOW);
  digitalWrite(5, LOW);
  digitalWrite(6, LOW);
  digitalWrite(7, LOW);
}

void two()
{
  digitalWrite(1, HIGH);
  digitalWrite(2, HIGH);
  digitalWrite(3, LOW);
  digitalWrite(4, HIGH);
  digitalWrite(5, HIGH);
  digitalWrite(6, LOW);
  digitalWrite(7, HIGH);
}

void three()
{
  digitalWrite(1, HIGH);
  digitalWrite(2, HIGH);
  digitalWrite(3, HIGH);
  digitalWrite(4, HIGH);
  digitalWrite(5, LOW);
  digitalWrite(6, LOW);
  digitalWrite(7, HIGH);

}

void four()
{
  digitalWrite(1, LOW);
  digitalWrite(2, HIGH);
  digitalWrite(3, HIGH);
  digitalWrite(4, LOW);
  digitalWrite(5, LOW);
  digitalWrite(6, HIGH);
  digitalWrite(7, HIGH);
}

void five()
{
  digitalWrite(1, HIGH);
  digitalWrite(2, LOW);
  digitalWrite(3, HIGH);
  digitalWrite(4, HIGH);
  digitalWrite(5, LOW);
  digitalWrite(6, HIGH);
  digitalWrite(7, HIGH);
}

void six()
{
  digitalWrite(1, HIGH);
  digitalWrite(2, LOW);
  digitalWrite(3, HIGH);
  digitalWrite(4, HIGH);
  digitalWrite(5, HIGH);
  digitalWrite(6, HIGH);
  digitalWrite(7, HIGH);
}

void seven()
{
  digitalWrite(1, HIGH);
  digitalWrite(2, HIGH);
  digitalWrite(3, HIGH);
  digitalWrite(4, LOW);
  digitalWrite(5, LOW);
  digitalWrite(6, LOW);
  digitalWrite(7, LOW);
}

void eight()
{
  digitalWrite(1, HIGH);
  digitalWrite(2, HIGH);
  digitalWrite(3, HIGH);
  digitalWrite(4, HIGH);
  digitalWrite(5, HIGH);
  digitalWrite(6, HIGH);
  digitalWrite(7, HIGH);
}

void nine()
{
  digitalWrite(1, HIGH);
  digitalWrite(2, HIGH);
  digitalWrite(3, HIGH);
  digitalWrite(4, HIGH);
  digitalWrite(5, LOW);
  digitalWrite(6, HIGH);
  digitalWrite(7, HIGH);
}

```

---

<div class="post-metadata">

**Author:** ![Ps991](https://avatars.discourse-cdn.com/v4/letter/p/43a26b/32.png) [@Ps991](https://forum.arduino.cc/u/Ps991)\
**Post date:** [July 16, 2015, 8:08am UTC](https://forum.arduino.cc/t/four-digit-seven-segment-display-clock-timer/324009/4 "2015-07-16T08:08:50Z")

</div>

The thing is, your code is 212 lines long...it is completely unnecessary to be that long and inefficient, my code could probably do that in 1/3 or 1/4 that amount. I have provided you with the tools and some examples, I would recommend trying testing them out so you can learn new and better ways to do things. If you have any immediate questions, we are here to help.

> The trick is to incorporate the delay between switching digits with the timer! So after each delay I would sum up the delays into an integer and whenever that integer reached 1000ms, I advanced the numbers.

I'm sorry, but this is just the wrong way to do it.

If you want to increase a number every 1 second, try this example:

```arduino
void setup(){
  Serial.begin(9600);
}

unsigned long previousMillis = 0;
int seconds = 0;

void loop(){
  if(millis() - previousMillis >= 1000){
    previousMillis() = millis();
    Serial.println(++seconds);
  }
}

```

---

<div class="post-metadata">

**Author:** ![system](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/system/32/1140315_2.png) [@system](https://forum.arduino.cc/u/system)\
**Post date:** [May 5, 2021, 9:23pm UTC](https://forum.arduino.cc/t/four-digit-seven-segment-display-clock-timer/324009/5 "2021-05-05T21:23:21Z")

</div>


