Up And Down Counter On Single-Digit 7-Segment Display

Hardware Required
- PICUNO Microcontroller board
- 5161AS Single-Digit 7-Segment Display (Common Cathode)
- 2 × Push Buttons (with internal pull-up)
- Breadboard
- Jumper wires
- USB cable
Description
This project implements an up and down counter using two push buttons. One button increments the count, while the other decrements it. The current digit is shown on the 7-segment display. The decimal point (DP) is also toggled ON as an indicator.
Circuit Diagram
[Fritzing image to be added here]
Circuit
- Connect the PICUNO board to the computer using a USB cable.
- Connect segment pins A to G and DP to GPIO pins 6 to 13 on the PicUNO.
- Connect either COM1 or COM2 (or both) to GND.
- Connect one button between GPIO 15 and GND (increment).
- Connect another button between GPIO 16 and GND (decrement).
Schematic
A → GPIO 6
B → GPIO 7
C → GPIO 8
D → GPIO 9
E → GPIO 10
F → GPIO 11
G → GPIO 12
dp → GPIO 13
COM 1 or COM 2 → GND
One side of button 1 → GPIO 15
One side of button 2 → GPIO 16
Other sides of both button → GND
Code - C
int segmentPins[8] = {6, 7, 8, 9, 10, 11, 12, 13}; // A-G + DP
int buttonUp = 15;
int buttonDown = 16;
byte digits[10][8] = {
{1,1,1,1,1,1,0,1}, // 0
{0,1,1,0,0,0,0,1}, // 1
{1,1,0,1,1,0,1,1}, // 2
{1,1,1,1,0,0,1,1}, // 3
{0,1,1,0,0,1,1,1}, // 4
{1,0,1,1,0,1,1,1}, // 5
{1,0,1,1,1,1,1,1}, // 6
{1,1,1,0,0,0,0,1}, // 7
{1,1,1,1,1,1,1,1}, // 8
{1,1,1,1,0,1,1,1} // 9
};
int counter = 0;
int lastUp = HIGH;
int lastDown = HIGH;
void setup() {
for (int i = 0; i < 8; i++) {
pinMode(segmentPins[i], OUTPUT);
}
pinMode(buttonUp, INPUT_PULLUP);
pinMode(buttonDown, INPUT_PULLUP);
}
void loop() {
int up = digitalRead(buttonUp);
int down = digitalRead(buttonDown);
if (up == LOW && lastUp == HIGH) {
counter = (counter + 1) % 10;
display(counter);
delay(200);
}
if (down == LOW && lastDown == HIGH) {
counter = (counter - 1 + 10) % 10;
display(counter);
delay(200);
}
lastUp = up;
lastDown = down;
}
void display(int num) {
for (int i = 0; i < 8; i++) {
digitalWrite(segmentPins[i], digits[num][i]);
}
}
int buttonUp = 15;
int buttonDown = 16;
byte digits[10][8] = {
{1,1,1,1,1,1,0,1}, // 0
{0,1,1,0,0,0,0,1}, // 1
{1,1,0,1,1,0,1,1}, // 2
{1,1,1,1,0,0,1,1}, // 3
{0,1,1,0,0,1,1,1}, // 4
{1,0,1,1,0,1,1,1}, // 5
{1,0,1,1,1,1,1,1}, // 6
{1,1,1,0,0,0,0,1}, // 7
{1,1,1,1,1,1,1,1}, // 8
{1,1,1,1,0,1,1,1} // 9
};
int counter = 0;
int lastUp = HIGH;
int lastDown = HIGH;
void setup() {
for (int i = 0; i < 8; i++) {
pinMode(segmentPins[i], OUTPUT);
}
pinMode(buttonUp, INPUT_PULLUP);
pinMode(buttonDown, INPUT_PULLUP);
}
void loop() {
int up = digitalRead(buttonUp);
int down = digitalRead(buttonDown);
if (up == LOW && lastUp == HIGH) {
counter = (counter + 1) % 10;
display(counter);
delay(200);
}
if (down == LOW && lastDown == HIGH) {
counter = (counter - 1 + 10) % 10;
display(counter);
delay(200);
}
lastUp = up;
lastDown = down;
}
void display(int num) {
for (int i = 0; i < 8; i++) {
digitalWrite(segmentPins[i], digits[num][i]);
}
}
segmentPins[] - GPIO pins 6 to 13 control segments A to G and the decimal point.
digits[][] - Each sub-array represents the ON/OFF states of segments A-G and DP for digits 0–9.
setup() - Initializes all segment pins as OUTPUT and buttons as INPUT_PULLUP.
loop() - Monitors button states: If the increment button is pressed (LOW after HIGH), the counter increases. If the decrement button is pressed (LOW after HIGH), the counter decreases.
digits[][] - Each sub-array represents the ON/OFF states of segments A-G and DP for digits 0–9.
setup() - Initializes all segment pins as OUTPUT and buttons as INPUT_PULLUP.
loop() - Monitors button states: If the increment button is pressed (LOW after HIGH), the counter increases. If the decrement button is pressed (LOW after HIGH), the counter decreases.
Code - Micropython
from machine import Pin
import time
segments = [Pin(i, Pin.OUT) for i in range(6, 14)] # A-G + DP (GPIO 6-13)
button_up = Pin(15, Pin.IN, Pin.PULL_UP)
button_down = Pin(16, Pin.IN, Pin.PULL_UP)
# Segment bitmaps for digits 0-9 (A-G + DP always ON)
numbers = [
[1,1,1,1,1,1,0,1], # 0
[0,1,1,0,0,0,0,1], # 1
[1,1,0,1,1,0,1,1], # 2
[1,1,1,1,0,0,1,1], # 3
[0,1,1,0,0,1,1,1], # 4
[1,0,1,1,0,1,1,1], # 5
[1,0,1,1,1,1,1,1], # 6
[1,1,1,0,0,0,0,1], # 7
[1,1,1,1,1,1,1,1], # 8
[1,1,1,1,0,1,1,1] # 9
]
counter = 0
last_up = 1
last_down = 1
def display(num):
for i in range(8):
segments[i].value(numbers[num][i])
while True:
up = button_up.value()
down = button_down.value()
if up == 0 and last_up == 1:
counter = (counter + 1) % 10
display(counter)
time.sleep(0.2)
if down == 0 and last_down == 1:
counter = (counter - 1) % 10
display(counter)
time.sleep(0.2)
last_up = up
last_down = down
import time
segments = [Pin(i, Pin.OUT) for i in range(6, 14)] # A-G + DP (GPIO 6-13)
button_up = Pin(15, Pin.IN, Pin.PULL_UP)
button_down = Pin(16, Pin.IN, Pin.PULL_UP)
# Segment bitmaps for digits 0-9 (A-G + DP always ON)
numbers = [
[1,1,1,1,1,1,0,1], # 0
[0,1,1,0,0,0,0,1], # 1
[1,1,0,1,1,0,1,1], # 2
[1,1,1,1,0,0,1,1], # 3
[0,1,1,0,0,1,1,1], # 4
[1,0,1,1,0,1,1,1], # 5
[1,0,1,1,1,1,1,1], # 6
[1,1,1,0,0,0,0,1], # 7
[1,1,1,1,1,1,1,1], # 8
[1,1,1,1,0,1,1,1] # 9
]
counter = 0
last_up = 1
last_down = 1
def display(num):
for i in range(8):
segments[i].value(numbers[num][i])
while True:
up = button_up.value()
down = button_down.value()
if up == 0 and last_up == 1:
counter = (counter + 1) % 10
display(counter)
time.sleep(0.2)
if down == 0 and last_down == 1:
counter = (counter - 1) % 10
display(counter)
time.sleep(0.2)
last_up = up
last_down = down
segments = [...] - Initializes GPIO 6 to 13 as outputs for A to G and DP.
button_up, button_down - Assigned to GPIO 15 and 16 as inputs with pull-up.
numbers[][] - Contains 8-bit segment control patterns for each digit.
display(num) - Loops through segments and updates their state to represent the current digit.
while True - Main loop continuously reads button states. If increment button transitions from HIGH to LOW, counter is incremented. If decrement button transitions from HIGH to LOW, counter is decremented.
button_up, button_down - Assigned to GPIO 15 and 16 as inputs with pull-up.
numbers[][] - Contains 8-bit segment control patterns for each digit.
display(num) - Loops through segments and updates their state to represent the current digit.
while True - Main loop continuously reads button states. If increment button transitions from HIGH to LOW, counter is incremented. If decrement button transitions from HIGH to LOW, counter is decremented.