≡ Menu

Arduino 2 Digit 7 Segment Display Counter: Sketch | Part 3

* This is a multi-part post. Here are links to all parts:

Part 1: Intro, bill of materials and simple sketch
Part 2: The circuit for the 2-digit 7-segment counter
Part 3: Sketch broken down in sections, explained; this post
Part 4: Added two buttons, and modified sketch
Part 5: Code for buttons, explained

So now on the the meatier sections of the sketch for this project:

Common anode displays are not immediately obvious as a segment is lit when the corresponding pin is made LOW. You might be surprised, though, that common anode displays are most often used because they can be used with 74xx series logic data-selector chips and general purpose general purpose PNP transistors.

// Segments that make each number when lit:
// 0 => -FEDCBA
// 1 => ----BC-
// 2 => G-ED-BA
// 3 => G--DCBA
// 4 => GF--CB-
// 5 => GF-DC-A
// 6 => GFEDC-A
// 7 => ----CBA
// 8 => GFEDCBA
// 9 => GF-DCBA

Remember, the Arduino pins are connected to the display’s cathodes. To light a segment we make the corresponding pin LOW.

We use 0s where the segments need to be lit up. The digit ‘zero’, for instance, is not the intuitive 0b0111111, but the less obvious 0b1000000.

// Segments that make each number
const byte numbers[10] = { 0b1000000, 0b1111001, 0b0100100, 0b0110000, 0b0011001, 0b0010010,
0b0000010, 0b1111000, 0b0000000, 0b0010000 };

To give the impression that both displays are active at the same time and avoid flickering we cycle through the digits in quick succession and keep each of them lit for 5ms. This is implemented by adding a short delay after displaying each digit. Since numbers stay lit for 600 ms, the whole process is repeated 60 times for each number displayed, and thanks to Persistence of Vision (POV) we have the impressios that both digits are actually lit up at the same time. (Even though they are not).

Arduino 2 digit 7 segment display counter sketch walk-through

The loop below is where the action takes place in our sketch: we cycle through both digits keeping each on for 5ms at a time for the 600ms during which we display each complete number.

void loop() {
  for (int digit1=0; digit1 < 10; digit1++) {
    for (int digit2=0; digit2 < 10; digit2++) {
      unsigned long startTime = millis();
      for (unsigned long elapsed=0; elapsed < 600; elapsed = millis() - startTime) {
        lightDigit1(numbers[digit1]);
        delay(5);
        lightDigit2(numbers[digit2]);
        delay(5);
      }
    }
  }
}

The lightDigit function for digit 1 enables only the transistor for the common anode pin of the tens digit:

void lightDigit1(byte number) {
  digitalWrite(CA1, LOW);
  digitalWrite(CA2, HIGH);
  lightSegments(number);
}

The lightDigit function for digit 2 enables only the transistor for the common anode pin of the units digit:

void lightDigit2(byte number) {
  digitalWrite(CA1, HIGH);
  digitalWrite(CA2, LOW);
  lightSegments(number);
}

Function lightSegments was reused from the single-digit 7-segment sketch:

void lightSegments(byte number) {
  for (int i = 0; i < 7; i++) {
    int bit = bitRead(number, i);
    digitalWrite(segs[i], bit);
  }
}

Next week we will modify our project to use buttons to control each digit, and as such we’ll avoid having to cycle through several numbers in order to achieve the desired number being displayed (if that number is significantly greater than the current number being displayed).

{ 8 comments… add one }
  • DuinoBP

    Hi this post is exactly what I am trying to build. I have a 2 digit 7 segment display and want to make an up and down counter. with a reset button if possible. Do you have the entire source code for this? I tried following along but got confused. I also need to purchase the 2 PNPs to make this work.

    Please email me if you can.

  • ajay singh

    nice job

  • Srisuwan Ponson

    this is my modified code now it work.
    const byte numbers[10] = { 0b0000001, 0b1111001, 0b0100100, 0b0110000, 0b0011001, 0b0010010,
    0b0000010, 0b1111000, 0b0000000, 0b0010000 };

    const int segs[7]={dg1a,dg1b,dg1c,dg1d,dg1e,dg1f,dg1g};
    void lightSegments(byte number) {
    for (int i = 0; i < 7; i++) {
    int Bit = bitRead(numbers[number], i);
    digitalWrite(segs[i], Bit);
    }
    }

Leave a Comment