from machine import Pin, ADC , Timer
from utime import ticks_ms , ticks_diff , sleep_ms
import time
# --- Pin setup ---
# segment_pins[0] is for segment A, segment_pins[1] for B, ..., segment_pins[6] for G.
segment_pins = [Pin(i, Pin.OUT) for i in range(7)]
# Decimal point pin (DP) connected to Pico GP11.
dp_pin = Pin(7, Pin.OUT)
# D4 (rightmost digit) -> Pico GP7
digit_pins = [Pin(i, Pin.OUT) for i in [11, 10, 9, 8]] # DIG0 (left) to DIG3 (right)
# Analog-to-Digital Converter (ADC) setup.
# Connected to GP26 (ADC0) on the Raspberry Pi Pico.
adc = ADC(Pin(26))
# Button input pin, connected to GP16. Configured with an internal pull-up resistor.
button = Pin(16, Pin.IN, Pin.PULL_UP)
lst_btn_press = 0
# -- for Common ANODE display --
# A '0' in the corresponding bit position means that segment should be ON.
display_codes = [
0xC0, # Digit 0 (A,B,C,D,E,F ON; G is OFF)
0xF9, # Digit 1 (B,C ON; other are OFF)
0xA4, # Digit 2
0xB0, # Digit 3
0x99, # Digit 4
0x92, # Digit 5
0x82, # Digit 6
0xF8, # Digit 7
0x80, # Digit 8
0x90 # Digit 9
]
# --- Global variables ---
voltage_digits = [0, 0, 0, 0]
display_timer = Timer()
# - update digits -
def read_voltage(pin=None):
raw = adc.read_u16()
mv = int((raw / 65535) * 3300)
print(f"Raw ADC: {raw}, Voltage: {mv} mV")
display_val = mv
for i in range(4):
voltage_digits[3 - i] = display_val % 10
display_val //= 10
# --- Display one digit on the 7-segment display ---
def show_digit(val, pos, show_dp=False):
# 1. Turn OFF all digit common pins. For Common Anode, set digit pins LOW to turn them OFF.
for d in digit_pins:
d.value(0)
# 2. Set the segment pins. For Common Anode, a LOW (0) activates a segment.
code = display_codes[val]
for i in range(7):
# If bit is 0, pin goes LOW (ON). If bit is 1, pin goes HIGH (OFF).
segment_pins[i].value((code >> i) & 1)
# Set the decimal point state. For Common Anode, 0 turns DP ON, 1 turns DP OFF.
dp_pin.value(0 if show_dp else 1)
# 3. Enable the desired digit. For Common Anode, set digit pin HIGH to turn it ON.
digit_pins[pos].value(1)
# --- (multiplexing function) ---
def update_display(timer):
for i in range(4):
pos = i
# The decimal point is turned on ONLY for the first digit (position 0).
show_digit(voltage_digits[i], pos, show_dp=(i == 0))
time.sleep_ms(2)
# Immediately disable the current digit. For Common Anode, set digit pin LOW to turn it OFF.
digit_pins[pos].value(0)
# --- Button interrupt handler ---
def handler(pin):
global lst_btn_press
current_time = ticks_ms()
if ticks_diff(current_time , lst_btn_press) < 200 :
return
lst_btn_press = current_time
if button.value() == 0: # Confirm button is still pressed (active low)
read_voltage()
# --- Setup function for initial configuration ---
def setup():
display_timer.init(period=8, mode=Timer.PERIODIC, callback=update_display)
button.irq(trigger=Pin.IRQ_FALLING, handler=handler)
read_voltage()
# --- Main program ---
setup()
while True:
time.sleep(0.1)