from machine import Pin, ADC
import math
from time import sleep, ticks_ms
import time
button_Pin = Pin(16, Pin.IN,Pin.PULL_UP)
SEVEN_SEGMENT_START_PIN = 0
ANALOGUE_INPUT_PIN = 26
DISPLAY_COUNT = 4
MEASUREMENT_COUNT = 16
DECIMAL_PRECISION = 4
ADC_RANGE = float((math.pow(2, 16) - 1))
ticks_ms = 200
# HEX value for 7 segment display values
digit_list_hex =[
0x40, # 0
0x79, # 1
0x24, # 2
0x30, # 3
0x19, # 4
0x12, # 5
0x02, # 6
0x78, # 7
0x00, # 8
0x10, # 9
0x08, # A
0x03, # B
0x46, # C
0x21, # D
0x06, # E
0x0E, # F
0x7F # Empty
]
# Global variables
button_pressed = False
last_button_time_stamp = 0
display_value = 0
segment_pins = []
display_select_pins = []
analogue_voltage_pin = ADC(26)
current_display_index = DISPLAY_COUNT - 1
display_timer = None
prev_analogue_voltage = -1
DECIMAL_PRECISION = 4 # Initialize DECIMAL_PRECISION, will be adjusted dynamically
def read_analogue_voltage(pin):
global display_value, display_timer
global prev_analogue_voltage, DECIMAL_PRECISION
global first_reading
total_value = 0
for _ in range(MEASUREMENT_COUNT):
total_value += pin.read_u16()
average_value = total_value // MEASUREMENT_COUNT
# Calculate voltage in mV for both display and serial output
analogue_voltage_mV = int(round((average_value / ADC_RANGE) * 3.3 * 1000))
if analogue_voltage_mV != prev_analogue_voltage:
prev_analogue_voltage = analogue_voltage_mV
# Display on serial monitor in mV
print(f'voltage: {analogue_voltage_mV}mV')
# Dynamically adjust DECIMAL_PRECISION based on voltage range
if analogue_voltage_mV > 1000 : # Less than 1V
DECIMAL_PRECISION = 4
new_display_value = int(analogue_voltage_mV)
max_val = 10 * (math.pow(10, DISPLAY_COUNT - 1) - 1)
if new_display_value > max_val:
print(f'warn: {new_display_value/10} V exceeds {max_val/10}, clipping')
new_display_value = int(max_val)
if display_value != new_display_value:
display_value = new_display_value
current_display_index = DISPLAY_COUNT - 1
for i in range(DISPLAY_COUNT):
digit = int((abs(display_value)// math.pow(10, current_display_index))) % 10
display_digit(digit, current_display_index,
current_display_index == DECIMAL_PRECISION - 1) # Adjust DP position
current_display_index -= 1
def scan_display(timer_int):
global current_display_index, display_value
digit = int((abs(display_value) // math.pow(10, current_display_index))) % 10
display_digit(digit, current_display_index,
current_display_index == DECIMAL_PRECISION - 1)
current_display_index = (current_display_index - 1)
if current_display_index < 0:
current_display_index = DISPLAY_COUNT - 1
def display_digit(digit_value, digit_index, dp_enable=False):
if digit_value < 0 or digit_value > len(digit_list_hex):
return
for pin in display_select_pins:
pin.value(0)
mask = digit_list_hex[digit_value]
for i in range(7):
segment_pins[i].value ((mask >> i) & 1 )
segment_pins[-1].value(1 if dp_enable == False else 0)
if digit_index == -1:
for pin in display_select_pins:
pin.value(1)
elif 0 <= digit_index < DISPLAY_COUNT:
display_select_pins[digit_index].value(1)
def int_handler(pin):
global button_pressed
global last_button_time_stamp
current_button_time = time.ticks_ms()
button_press_delta = current_button_time - last_button_time_stamp
if button_press_delta > 200:
last_button_time_stamp = current_button_time
button_pressed = True
def setup():
global segment_pins, display_select_pins, analogue_voltage_pin, voltage_value
global display_timer, button_pressed
# Initialize display_select_pins and segment_pins
display_select_pins = []
segment_pins = []
# Set up display select pins
for i in range(SEVEN_SEGMENT_START_PIN + 8, SEVEN_SEGMENT_START_PIN + 8 + DISPLAY_COUNT):
pin = machine.Pin(i, machine.Pin.OUT)
pin.value(0)
display_select_pins.append(pin)
for i in range(SEVEN_SEGMENT_START_PIN, SEVEN_SEGMENT_START_PIN + 8):
pin = machine.Pin(i, machine.Pin. OUT)
pin.value(1)
segment_pins.append(pin)
display_timer = machine.Timer()
display_timer.init(period=4, mode=machine.Timer.PERIODIC, callback=scan_display)
for btn_idx in range (16):
button_Pin.irq(trigger=Pin.IRQ_FALLING, handler=int_handler)
display_value = 0
current_display_index = DISPLAY_COUNT - 1
for i in range(DISPLAY_COUNT):
display_digit(0, current_display_index)
current_display_index -= 1
while True:
if button_pressed is True:
button_pressed = False
read_analogue_voltage(analogue_voltage_pin)
time.sleep(0.5)
if __name__ == '__main__':
setup()