import machine
import math
import time
# constants & Pins Declaration
SEVEN_SEGMENT_START_PIN = 0
ANALOGUE_INPUT_PIN = 26
BUTTON_PIN = 16
diplay_count = 4
measurment_count = 1
decimal_precision = 3
ADC_range = float((math.pow(2, 16) - 1))
DEBOUNCE_TIME = 50
digit_list_hexdecmial = [0x40, 0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10,0x08,0x03,0x46,0x21,0x06,0x0E,0x7F]
# Variables Declaration
display_value = 0
seg_pins = []
display_valu = 0
button_pin = None
analogue_voltage_pin = None
display_select_pins = []
display_timer = None
last_button_press = 0
current_display_index = diplay_count - 1
previous_analogue_voltage = -1
last_button_pressed = 0
# Function to read the ADC pin and
# to convert the digital value to a voltage level in the 0-3.3V range
# This function updates the value of the display_value global variable
def read_analogue_voltage(pin): # We can use the pin parameter if needed
global display_valu , previous_analogue_voltage
total_value = sum(pin.read_u16() for _ in range(measurment_count))
average_val = total_value // measurment_count
analogue_voltage = round((average_val / ADC_range) * 3.3, decimal_precision)
if analogue_voltage != previous_analogue_voltage:
previous_analogue_voltage = analogue_voltage
new_display_value = int(analogue_voltage * math.pow(10,decimal_precision))
max_value = math.pow(10, diplay_count) - 1
if new_display_value > max_value:
print(f'Warning: {new_display_value} exceeds {max_value}, clipping')
new_display_value = max_value
if display_value != new_display_value:
display_value = new_display_value
reset_display()
return analogue_voltage
# Function to disable timer that triggers scanning 7 segment displays
def disable_display_timer():
global display_timer
display_timer.deinit()
# Function to enable timer that triggers scanning 7 segment displays
def enable_display_timer():
global display_timer
display_timer.init(period=4, mode = machine.Timer.PERIODIC, callback = scan_display)
# Function to handle scanning 7 segment displays
# Display the value stored in the display_value global variable
# on available 7-segment displays
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 and decimal_precision != 0)
current_display_index = (current_display_index - 1) % diplay_count
# Function display the given value on the display with the specified index
# dp_enable specifies if the decimal pooint should be on or off
def display_digit(digit_value, digit_index, dp_enable=False):
if digit_value < 0 or digit_value > len(digit_list_hexdecmial):
return
for pin in display_select_pins:
pin.value(0)
mask = digit_list_hexdecmial[digit_value]
for i in range(7):
seg_pins[i].value((mask >> i) & 1)
seg_pins[7].value(not dp_enable)
if digit_index == -1:
for pin in display_select_pins:
pin.value(1)
elif 0 <= digit_index < diplay_count:
display_select_pins[digit_index].value(1)
# Function to test avaiable 7-segment displays
def reset_display():
global current_display_index
disable_display_timer()
current_display_index = diplay_count - 1
display_digit(16, -1)
time.sleep(0.1)
enable_display_timer()
def display_value_test():
for i in range(16):
display_digit(i, 0)
time.sleep(0.5)
# Function to setup GPIO/ADC pins, timers and interrupts
def setup():
global seg_pins, display_select_pins, analogue_voltage_pin, button_pin, display_timer
display_select_pins = [machine.Pin(i, machine.Pin.OUT) for i in range(SEVEN_SEGMENT_START_PIN + 8, SEVEN_SEGMENT_START_PIN + 8 + diplay_count )]
for pin in display_select_pins:
pin.value(0)
seg_pins = [machine.Pin(i, machine.Pin.OUT) for i in range(SEVEN_SEGMENT_START_PIN, SEVEN_SEGMENT_START_PIN + 8)]
for pin in seg_pins:
pin.value(1)
analogue_voltage_pin = machine.ADC(ANALOGUE_INPUT_PIN)
button_pin = machine.Pin(BUTTON_PIN, machine.Pin.IN, machine.Pin.PULL_UP)
display_timer = machine.Timer()
enable_display_timer()
if __name__ == '__main__':
setup()
#display_value_test()
while True:
if button_pin.value() == 0:
current_time = time.ticks_ms()
if current_time - last_button_pressed > DEBOUNCE_TIME:
last_button_pressed = current_time
voltage = read_analogue_voltage(analogue_voltage_pin)
if voltage is not None:
print(f'Voltage equal {voltage} V')
time.sleep(0.1)