import time
import board
import digitalio
# SET PARAMETERS
x = 60 # Max count value (stopwatch reset after 60)
interval = 0.2 # Time delay between counts (speed of counting)
# BUTTON INPUTS
sw1 = digitalio.DigitalInOut(board.GP15) # Start button (SW1)
sw1.direction = digitalio.Direction.INPUT # Set as input
sw1.pull = digitalio.Pull.UP # Enable pull-up (pressed = low)
sw2 = digitalio.DigitalInOut(board.GP16) # Reset button (SW2)
sw2.direction = digitalio.Direction.INPUT # Set as input
sw2.pull = digitalio.Pull.UP # Enable pull-up (pressed = low)
# SHARED BCD DATA LINES (D0-D3)
A = digitalio.DigitalInOut(board.GP2) # BCD bit 0 #MSB
B = digitalio.DigitalInOut(board.GP3) # BCD bit 1
C = digitalio.DigitalInOut(board.GP4) # BCD bit 2
D = digitalio.DigitalInOut(board.GP5) # BCD bit 3 #LSB
# Set all BCD pin as output
for pin in [A, B, C, D]:
pin.direction = digitalio.Direction.OUTPUT
bcd_pins = [A, B, C, D] # Store BCD pins for easy looping
# LATCH ENABLE PINS (CD4511 control)
s72 = digitalio.DigitalInOut(board.GP0) # Control tens display
s72.direction = digitalio.Direction.OUTPUT
s71 = digitalio.DigitalInOut(board.GP1) # Control ones display
s71.direction = digitalio.Direction.OUTPUT
# BCD FUNCTION
def send_bcd(value):
# Send 4-bit binary value to CD4511 decoder
for i in reversed (range(4)):
bcd_pins[i].value = (value >> i) & 1 # Extract each bit
def latch(pin):
# Send pulse to latch data into 7-segment display
pin.value = 0 # Enable latch (active low)
time.sleep(0.001) # Small delay for hardware stability
pin.value = 1 # disable latch
def display_number(num):
# Split number into tens and ones digits
tens = num // 10
ones = num % 10
# Send tens digit to left display
send_bcd(tens)
latch(s72)
# Send ones digit to right display
send_bcd(ones)
latch(s71)
def display_off():
# Turn OFF both segment
for pin in bcd_pins:
pin.value = 0 # Clear BCD input
# Turn OFF both display
latch(s72)
latch(s71)
# MAIN VARIABLES
count = x # Current stopwatch value
running = False # State of stopwatch (false = stopped, True = running)
# Initial display OFF
display_off()
# MAIN LOOP
while True:
# Always update display with current count
display_number(count)
# START BUTTON (SW1)
if not sw1.value: # Button pressed (low signal)
count = x
running = True # Start counting
print("START COUNTDOWN")
time.sleep(0.3) # Debounce delay
# RESET BUTTON (SW2)
if not sw2.value: # Button pressed
running = False # Stop counting
count = x # Reset value to 0
display_off()
print("RESET -> DISPLAY OFF")
time.sleep(0.3) # Debounce delay
# COUNTING PROCESS
if running: # Only count when stopwatch is running
time.sleep(interval) # Wait before increasing count
count -= 1 # Increase count by 1
# MAX VALUE CONDITION
if count <= 0: # If count exceed max value
count = 0 # Reset back to 0
running = False
print("TIME UP -> RESET")
# Display formatted output(always 2 digit)
print("Time: {:02d}".format(count))