from machine import Pin, ADC, Timer
import time
# SEGMENTS = GP0 to GP7 (A–DP)
segment_pins = [Pin(i, Pin.OUT) for i in range(8)]
# DIGITS = GP11 to GP8 (left to right)
digit_pins = [Pin(i, Pin.OUT) for i in range(11, 7, -1)]
adc = ADC(Pin(26))
button = Pin(16, Pin.IN, Pin.PULL_UP)
voltage_read = 0.0
last_press_time = 0
digit_codes = {
0: [1, 1, 1, 1, 1, 1, 0],
1: [0, 1, 1, 0, 0, 0, 0],
2: [1, 1, 0, 1, 1, 0, 1],
3: [1, 1, 1, 1, 0, 0, 1],
4: [0, 1, 1, 0, 0, 1, 1],
5: [1, 0, 1, 1, 0, 1, 1],
6: [1, 0, 1, 1, 1, 1, 1],
7: [1, 1, 1, 0, 0, 0, 0],
8: [1, 1, 1, 1, 1, 1, 1],
9: [1, 1, 1, 1, 0, 1, 1]
}
def voltage_to_digits(v):
v = max(0.0, min(v, 9.999))
val = int(v * 1000)
return [val // 1000, (val % 1000) // 100, (val % 100) // 10, val % 10]
def show_digit(val, pos, dot=False):
code = digit_codes.get(val, [0]*7)
for i in range(7):
segment_pins[i].value(code[i])
segment_pins[7].value(1 if dot else 0)
for i in range(4):
digit_pins[i].value(1)
digit_pins[pos].value(0)
time.sleep_ms(2)
digit_pins[pos].value(1)
def refresh_display(timer):
digits = voltage_to_digits(voltage_read)
for i in range(4):
dp = True if i == 0 else False # Decimal after 1st digit
show_digit(digits[i], i, dot=dp)
def handle_button(pin):
global voltage_read, last_press_time
now = time.ticks_ms()
if time.ticks_diff(now, last_press_time) > 200:
last_press_time = now
voltage_read = round((adc.read_u16() / 65535) * 3.3, 3)
print("Voltage:", voltage_read)
# Attach interrupt to button
button.irq(trigger=Pin.IRQ_FALLING, handler=handle_button)
# Start display timer
timer = Timer()
timer.init(freq=250, mode=Timer.PERIODIC, callback=refresh_display)
# Main loop (empty, because interrupts & timers handle everything)
print("Voltmeter running...")
while True:
time.sleep(1)