from machine import Pin, ADC, Timer
import time
# Segment pins A to DP → GP0–GP7
segment_pins = [Pin(i, Pin.OUT) for i in range(8)]
# Digit control pins DIG1 → DIG4 = GP11 → GP8
digit_pins = [Pin(11, Pin.OUT), Pin(10, Pin.OUT), Pin(9, Pin.OUT), Pin(8, Pin.OUT)]
# ADC input on GP26
adc = ADC(26)
# Button with interrupt and pull-up on GP16
button = Pin(16, Pin.IN, Pin.PULL_UP)
# Digit patterns (active low)
digits = {
'0': 0b11000000,
'1': 0b11111001,
'2': 0b10100100,
'3': 0b10110000,
'4': 0b10011001,
'5': 0b10010010,
'6': 0b10000010,
'7': 0b11111000,
'8': 0b10000000,
'9': 0b10011000,
' ': 0b11111111,
'-': 0b10111111
}
# Global flags and timer for debouncing
button_pressed = False
debounce_timer = Timer()
def clear_display():
for seg in segment_pins:
seg.value(1)
for dig in digit_pins:
dig.value(0)
def show_char(ch, digit_index, show_dp=False):
pattern = digits.get(ch, digits[' '])
if show_dp:
pattern &= 0b01111111 # Turn on decimal point (bit 7 LOW = ON)
for i in range(8):
segment_pins[i].value((pattern >> i) & 1)
digit_pins[digit_index].value(1)
time.sleep(0.003)
digit_pins[digit_index].value(0)
def mv_to_str(mv):
if mv < 1000:
return f"0.{mv:03d}"
else:
volts = mv // 1000
mvolts = mv % 1000
return f"{volts}.{mvolts:03d}"
# Interrupt handler
def button_irq_handler(pin):
global button_pressed
if not button_pressed:
button_pressed = True
debounce_timer.init(mode=Timer.ONE_SHOT, period=200, callback=lambda t: None)
# Attach interrupt
button.irq(trigger=Pin.IRQ_FALLING, handler=button_irq_handler)
# Display voltage for 2 seconds
def display_voltage(mv):
value_str = mv_to_str(mv)
digits_to_show = list(value_str)
start = time.ticks_ms()
while time.ticks_diff(time.ticks_ms(), start) < 2000:
i = 0
digit_pos = 0
while digit_pos < 4:
ch = digits_to_show[i]
if ch == '.':
i += 1
continue
dp = (i + 1 < len(digits_to_show)) and digits_to_show[i + 1] == '.'
show_char(ch, digit_pos, show_dp=dp)
i += 1
digit_pos += 1
clear_display()
# Main loop
print("System ready. Press button to read voltage.")
while True:
if button_pressed:
button_pressed = False
raw = adc.read_u16()
voltage_mv = (raw * 3300) // 65535
print("Voltage:", mv_to_str(voltage_mv), "V")
display_voltage(voltage_mv)