▷ Up and down counter with 7-segment displays - Arduino

In this post, we will see how to make an ascending and descending counter from 0 to 99 using Arduino and 7-segment displays.

MATERIALS:

The materials we will use for this project are as follows:

WIRING DIAGRAM

EXPLANATION PART BY PART:

We declare the pins where the 7-segment displays will be connected.

int pins [] = {0, 1, 2, 3, 4, 5, 6};

We make the connections as follows:

  • Pin 6 with a
  • Pin 5 with b
  • Pin 4 with c
  • Pin 3 with d
  • Pin 2 with e
  • Pin 1 with f
  • Pin 0 with g

We define the pins where the transistors will be connected.

- The transistor connected to the tens display will be connected to pin 8 of Arduino and the units display to pin 10.

#define decenaTr 8
#define unitTr 10

We create an array.

In this array we will store the values of the numbers in binary code in ascending order from 0 to 9, (we add a position before 0 since we will need it for descending counting) we use this array if we are using common anode displays.

byte anodeNumbers[] {
 B0000000,//NA - position 0
 B0000001,//0 - position 1
 B1001111,//1 - position 2
 B0010010,//2 - position 3
 B0000110,//3 - position 4
 B1001100,//4 - position 5
 B0100100,//5 - position 5
 B0100000,//6 - position 7
 B0001111,//7 - position 8
 B0000000,//8 - position 9
 B0000100,//9 - position 10
};

We declare variables:

- The variables: estadoUp and estadoDown will be used to implement debouncing.

- The variables: ten and unit will be used to indicate the index of the array.

- The variable pause will be used for the activation and deactivation time of the transistors (multiplexing).

bool estadoUp = 0;
bool estadoDown = 0;

byte ten = 0;
byte unit = 0;

short pause = 5;

Void setup.

In the void setup, we declare inputs, outputs, and set the units and tens to 1 because remember that the position number 1 of the array numerosAnodo will show the number 0 on the 7-segment display.

void setup() {
  pinMode(tr1, OUTPUT);
  pinMode(tr2, OUTPUT);

We created this for loop to declare the pins that are connected to the displays (since they are in order, from 0 to 6 we can do it this way)

  for (int led = 0; led < 8; led++) {
    pinMode(pins[led], OUTPUT);
  }
  tens = 1;
  units = 1;
}

Void loop:

In the void loop we create two variables which will store the logical states of the buttons.

The button for the ascending count will be connected to pin A0 and the button for the descending count to pin A1.

bool  pUp = digitalRead(A0);
bool  pDown = digitalRead(A1);

We perform multiplexing.

Multiplexing is a technique that allows multiple streams of information to share a single transmission medium. Thanks to this technique, we can reduce the number of pins used for this type of circuit; it works as follows.

To display two different numbers on different displays, what we do is:

Activate one display, show the number, and then activate the other display and show a different number.

In this case, we first activate the units display and deactivate the tens display (we do this using transistors; the bases of the transistors are connected to the Arduino pins, the collector is connected to VCC, and the emitter is connected to the activation pins of the displays), we show the number located at position x of the array through port D, we set a pause, and we do the same for the tens display.

Depending on the value of the variables: unit and ten; it will show a number or another on the display. Example:

If the unit variable = 4, we will see the number "3" on the display.

digitalWrite(decenaTr, HIGH);
digitalWrite(unidadTr, LOW);
PORTD = numerosAnodo[unidad];
delay(pausa);
digitalWrite(decenaTr, LOW); 
digitalWrite(unidadTr, HIGH);
PORTD = anodeNumbers[ten];
delay(pause);

When the ascending count button is pressed, the following occurs:

First, we will check with the anti-bounce system if the button was pressed

-If the button was pressed then:

*We check: If the count reaches 99, then it will stay at 99. Otherwise, the value of the tens will be added.

-If the value of the ten is equal to 11, the ten will be equal to 1 and we add the units. (We put 11 because as we know the array has 10 positions and position 10 is equal to number 9, we make the equality with 10 so when the counter reaches 9 the value of ten will be equal to 1 if we do this, we will not be able to observe values like 10, 20, 30, etc. We equal the ten to 1 because the value of number 0 is in that position of the array).

if (pUp != estadoUp) {
  if (pUp == HIGH) {
      
    if (unit == 10 && ten == 10){
      ten = 10;
      unit = 10;    	    
    } else {
      ten++;
    }

    if (ten == 11 ) {
      ten = 1;
      unit++;
    } 
  }
} 
When the countdown button is pressed, the following occurs:

First, we will check with the anti-bounce system if the button was pressed

-If the button was pressed, then:

* We subtract the value of the ten: if the ten is equal to 0 (position 0 of the array = Not important), the value of the ten variable will be equal to 10 and we subtract the value of the unit.

if (pDown != estadoDown) {
  if (pDown == HIGH) {

    decena--;

    if (decena == 0) {
      decena = 10;
      unidad--;
    }
  }
}

We added a condition so that the counter number is not less than 00 and we equalized estadoUp and estadoDown with the values of pUp and pDown respectively, this is for the anti-bounce system.

if (decena == 10 && unidad == 0){
  decena = 1;
  unidad = 1;
}
      
  
estadoUp = pUp;
estadoDown = pDown;

FULL CODE:

int pins [] = {0, 1, 2, 3, 4, 5, 6};

#define tensTr 8
#define unitsTr 10
 
bool stateUp = 0;
bool stateDown = 0;
 
byte tens = 0;
byte units = 0;
 
short pause = 5;
 
byte anodeNumbers[] {
  B0000000,//NA
  B0000001,//0
  B1001111,//1
  B0010010,//2
  B0000110,//3
  B1001100,//4
  B0100100,//5
  B0100000,//6
  B0001111,//7
  B0000000,//8
  B0000100,//9
};
 
byte cathodeNumbers[] {
 
  B0000000,//NA
  B1111110,//0
  B0110000,//1
  B1101101,//2
  B1111001,//3
  B0110011,//4
  B1011011,//5
  B1011111,//6
  B1110000,//7
  B1111111,//8
  B1111011,//9
};
 
 
void setup() {
 
  pinMode(tensTr, OUTPUT);
  pinMode(unitTr, OUTPUT);
 
  for (int led = 0; led < 8; led++) {
    pinMode(pins[led], OUTPUT);
  }
  ten = 1;
  unit = 1;
}
 
void loop() {
 
  bool  pUp = digitalRead(A0);
  bool  pDown = digitalRead(A1);
 
  if (pUp != estadoUp) {
    if (pUp == HIGH) {
     
      if (unit == 10 && ten == 10){
        ten = 10;
        unit = 10;           
      } else {
        ten++;
      }
 
      if (ten == 11 ) {
        ten = 1;
        unit++;
      }
    }
  }
 
  if (pDown != estadoDown) {
    if (pDown == HIGH) {
 
      ten--;
 
      if (ten == 0) {
        ten = 10;
        unit--;
      }
    }
  }
 
  if (ten == 10 && unit == 0){
    ten = 1;
    unit = 1;
  }
     
  stateUp = pUp;
  stateDown = pDown;
 
  digitalWrite(tenTr, HIGH);
  digitalWrite(unitTr, LOW);
  PORTD = anodeNumbers[unit];
  delay(pause);
  digitalWrite(tenTr, LOW);
  digitalWrite(unitTr, HIGH);
  PORTD = anodeNumbers[ten];
  delay(pause);
  
}

0/Leave a comment/Comments

Hello! We're so glad you've made it this far and are reading this article on Edeptec.

This form is an open space for you: you can leave a comment with your questions, suggestions, experiences, or simply your opinion on the topic discussed.

» Did you find the information helpful?
» Do you have any personal experiences you'd like to share?
» Do you have any topics you'd like to see covered in future articles?

Remember that this space is for learning and sharing, so we encourage you to participate respectfully and constructively. Your comments can help other readers who are on the same path, whether in electronics, programming, sports, or technology.

Thank you for being part of this learning community! Your participation is what makes this project grow.