from machine import Pin, ADC
import time
# --- Segment and digit pins ---
SEG_PINS = [Pin(i, Pin.OUT) for i in range(8)] # A-G, DP on GPIO 0–7
DIGIT_PINS = [Pin(i, Pin.OUT) for i in [11, 10, 9, 8]] # DIG1–DIG4
DOT_PIN = SEG_PINS[7] # DP is pin 7
# --- ADC and button setup ---
adc = ADC(26) # GPIO 26 = ADC0
button = Pin(16, Pin.IN, Pin.PULL_UP)
# --- 7-segment digit codes (common cathode) ---
digit_codes = [
0b11000000, # 0
0b11111001, # 1
0b10100100, # 2
0b10110000, # 3
0b10011001, # 4
0b10010010, # 5
0b10000010, # 6
0b11111000, # 7
0b10000000, # 8
0b10010000 # 9
]
# --- Global display value (mV) ---
display_value = 0
last_press_time = 0 # for debounce
# --- Display a digit with optional dot ---
def display_digit(digit, digit_index, dot=False):
segments = digit_codes[digit]
for i in range(7):
SEG_PINS[i].value((segments >> i) & 1)
DOT_PIN.value(0 if dot else 1)
DIGIT_PINS[digit_index].on()
time.sleep(0.005)
DIGIT_PINS[digit_index].off()
# --- Scan display to show full 4-digit number ---
def scan_display():
value = display_value
for i in range(3, -1, -1): # DIG4 to DIG1
digit = value % 10
value //= 10
dot = (i == 0) # Turn on dot after first digit
display_digit(digit, i, dot)
# --- Button interrupt: read and convert voltage ---
def button_pressed(pin):
global display_value, last_press_time
now = time.ticks_ms()
if time.ticks_diff(now, last_press_time) < 200:
return # debounce: ignore if < 200ms
last_press_time = now
raw = adc.read_u16()
voltage = (raw * 3.3) / 65535 # Convert to voltage
mv = int(voltage * 1000) # Convert to millivolts for display
display_value = mv
print("Voltage:", voltage, "V")
# Attach interrupt to button (falling edge = press)
button.irq(trigger=Pin.IRQ_FALLING, handler=button_pressed)
# --- Main loop: keep scanning display ---
while True:
scan_display()