# imports
import machine
import math
import time
#######################################
# Pin and constant definitions
#######################################
sev_seg = 0
sev_seg_digit = 8
button = 16
adc_start = 26
decimal = 3
# Digits for common cathode 7-segment display (Default = LOW or GND)
# schematic of digit in digits = g f e d c b a
digits = [
[0, 1, 1, 1, 1, 1, 1], # 0
[0, 0, 0, 0, 1, 1, 0], # 1
[1, 0, 1, 1, 0, 1, 1], # 2
[1, 0, 0, 1, 1, 1, 1], # 3
[1, 1, 0, 0, 1, 1, 0], # 4
[1, 1, 0, 1, 1, 0, 1], # 5
[1, 1, 1, 1, 1, 0, 1], # 6
[0, 0, 0, 0, 1, 1, 1], # 7
[1, 1, 1, 1, 1, 1, 1], # 8
[1, 1, 0, 1, 1, 1, 1], # 9
[1, 1, 1, 0, 1, 1, 1], # A
[1, 1, 1, 1, 1, 0, 0], # B
[0, 1, 1, 1, 0, 0, 1], # C
[1, 0, 1, 1, 1, 1, 0], # D
[1, 1, 1, 1, 0, 0, 1], # E
[1, 1, 1, 0, 0, 0, 1], # F
]
#######################################
# Global variables
#######################################
display_value = 0
scanner = None
last_pressed_time = 0.5
seg_pins = []
digit_pins = []
#######################################
# Function definitions
#######################################
# 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_value, last_pressed_time
button_time = time.ticks_ms() - last_pressed_time
if button_time > 199.5:
display_value = int(machine.ADC(machine.Pin(26)).read_u16() * 3300 / 65535)
print(f"Voltage: {round(display_value, 3)} mV or {round(display_value / 1000, 3)} V")
last_pressed_time = button_time
# Vin x
# ------ = -------- Vin(required), Vref(3V3), x(analog value), n(number of bits"16")
# Vref 2^n - 1
# Vref * x 3.3 * x
# Vin = ---------- --> Vin = --------- (Solving for Vin) in V Vin * 10^3 = Voltage in mV
# 2^n-1 65535
# Function to disable timer that triggers scanning 7 segment displays
def disable_display_timer():
global scanner
scanner.deinit()
# Function to enable timer that triggers scanning 7 segment displays
def enable_display_timer():
global scanner
scanner.init(period=45, 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 display_value, digit_pins
m = display_value
for i in range(len(digit_pins)):
display_digit(int(m % 10), i, i==3)
seg_pins[7].off()
digit_pins[i].on()
m /= 10
# 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):
global seg_pins, digit_pins
# Validity Check
if 0 > digit_value or digit_value > len(digits):
return
# Display Digit
val = digits[digit_value]
for i in range(7):
seg_pins[i].value(val[i])
# Position of Digit
if digit_index <= len(digit_pins):
digit_pins[digit_index].off()
else:
for i in range(4):
digit_pins[i].off()
# Decimal Point Check
seg_pins[7].value(1 if dp_enable else 0)
# Function to test avaiable 7-segment displays
def display_value_test():
disable_display_timer()
for i in range(len(digits)):
display_digit(i, 5, i % 2 == 0)
time.sleep(0.5)
enable_display_timer()
# Function to setup GPIO/ADC pins, timers and interrupts
def setup():
global display_value, digit_pins, seg_pins, scanner
time.sleep(0.02)
# PINS (GPIO or ADC)
b0 = machine.Pin(button, machine.Pin.IN, machine.Pin.PULL_UP)
a = machine.Pin(sev_seg, machine.Pin.OUT)
b = machine.Pin(sev_seg + 1, machine.Pin.OUT)
c = machine.Pin(sev_seg + 2, machine.Pin.OUT)
d = machine.Pin(sev_seg + 3, machine.Pin.OUT)
e = machine.Pin(sev_seg + 4, machine.Pin.OUT)
f = machine.Pin(sev_seg + 5, machine.Pin.OUT)
g = machine.Pin(sev_seg + 6, machine.Pin.OUT)
dp = machine.Pin(sev_seg + 7, machine.Pin.OUT)
dig1 = machine.Pin(sev_seg_digit + 3, machine.Pin.OUT)
dig2 = machine.Pin(sev_seg_digit + 2, machine.Pin.OUT)
dig3 = machine.Pin(sev_seg_digit + 1, machine.Pin.OUT)
dig4 = machine.Pin(sev_seg_digit, machine.Pin.OUT)
analog = machine.ADC(machine.Pin(adc_start))
# IRQ interrupt handler
b0.irq(trigger=machine.Pin.IRQ_FALLING, handler=read_analogue_voltage)
# segments and digits of seven segment display
digit_pins = [dig4, dig3, dig2, dig1]
seg_pins = [g, f, e, d, c, b, a, dp]
# Timer setup
scanner = machine.Timer()
enable_display_timer()
if __name__ == '__main__':
setup()
#display_value_test()