import machine
import math
import time
# Pin and constant definitions
# Segment pins (a, b, c, d, e, f, g, dp)
segment_pins = [machine.Pin(pin, machine.Pin.OUT) for pin in [10,11,12,13,14,15,16,17]]
# Digit control pins for 4 digits (Common cathode)
digit_pins = [machine.Pin(pin, machine.Pin.OUT) for pin in [2,3,4,5]]
# ADC pin (e.g., Potentiometer on ADC0 / pin 26)
adc = machine.ADC(26)
# Button pin
button_pin = machine.Pin(18, machine.Pin.IN, machine.Pin.PULL_UP)
# Timer for display multiplexing
display_timer = machine.Timer()
#######################################
# Global variables
#######################################
display_value = 0.00
current_digit = 0
# Digit to segment mapping (without dp)
digit_map = {
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]
}
#######################################
# Function definitions
#######################################
# Function to read the ADC and convert to voltage
def read_analogue_voltage(pin):
global display_value
raw = adc.read_u16()
voltage = (raw / 65535.0) * 3.3
display_value = round(voltage, 2)
print("Voltage:", display_value)
# Disable display timer
def disable_display_timer():
display_timer.deinit()
# Enable display timer
def enable_display_timer():
display_timer.init(freq=500, mode=machine.Timer.PERIODIC, callback=scan_display)
# Display scan interrupt (multiplex 4 digits)
def scan_display(timer_int):
global current_digit, display_value
# Turn off all digits before updating
for dp in digit_pins:
dp.value(0)
# Format value to string (e.g., 3.30 -> "330" or "3.3")
val_str = f"{display_value:.2f}" # "3.30"
val_str = val_str.replace('.', '') # Remove dot: "330"
val_str = val_str[:4].rjust(4, '0') # Ensure 4 digits: "0330"
try:
digit_char = val_str[current_digit]
digit_val = int(digit_char)
dp_enable = (current_digit == 1) # Enable decimal point after 1st digit (e.g. 3.30)
display_digit(digit_val, current_digit, dp_enable)
except:
pass
# Move to next digit
current_digit = (current_digit + 1) % 4
# Display a single digit on the given digit index
def display_digit(digit_value, digit_index, dp_enable=False):
segments = digit_map.get(digit_value, [0]*7)
for i in range(7):
segment_pins[i].value(segments[i])
# Decimal point control
segment_pins[7].value(1 if dp_enable else 0)
# Enable only the current digit
for i in range(4):
digit_pins[i].value(1 if i == digit_index else 0)
# Button interrupt handler
def button_irq(pin):
time.sleep_ms(200) # debounce
read_analogue_voltage(pin)
# Function to test all digits
def display_value_test():
for i in range(10):
for d in range(4):
display_digit(i, d, dp_enable=(d==1))
time.sleep(0.2)
# Setup all hardware
def setup():
for dp in digit_pins:
dp.init(mode=machine.Pin.OUT)
dp.value(0)
for sp in segment_pins:
sp.init(mode=machine.Pin.OUT)
sp.value(0)
button_pin.irq(trigger=machine.Pin.IRQ_FALLING, handler=button_irq)
enable_display_timer()
if __name__ == '__main__':
setup()
# display_value_test()