# imports
import machine
import math
import time
########################################
# Pin and constant definitions
########################################
# ADC pin
ADC_PIN = 26
# Segment pins (a-g): GPIO 0, 1, 2, 3, 4, 5, 6
SEGMENT_PINS = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
# Digit select pins (DIG1 to DIG4): GPIO 18, 19, 20, 21
DIGIT_PINS = [18, 19, 20, 21]
# Button pin
BUTTON_PIN = 16
# Segment bit patterns for digits 0-9, and blank (COMMON CATHODE)
DIGIT_ENCODING = {
'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],
' ': [0, 0, 0, 0, 0, 0, 0],
'.': [0, 0, 0, 0, 0, 0, 1]
}
########################################
# Global variables
########################################
display_value = 0
segment_outputs = [machine.Pin(pin, machine.Pin.OUT) for pin in SEGMENT_PINS]
digit_outputs = [machine.Pin(pin, machine.Pin.OUT) for pin in DIGIT_PINS]
adc = machine.ADC(ADC_PIN)
button = machine.Pin(BUTTON_PIN, machine.Pin.IN, machine.Pin.PULL_UP)
display_digits = [' ', ' ', ' ', ' ']
current_digit_index = 0
display_timer = None
button_pressed = False
last_button_time = 0
display_enabled = False
########################################
# 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):
raw = adc.read_u16()
voltage = (raw * 3.3) / 65535
global display_value
display_value = voltage
# Function to disable timer that triggers scanning 7 segment displays
def disable_display_timer():
global display_timer
if display_timer:
display_timer.deinit()
display_timer = None
# Function to enable timer that triggers scanning 7 segment displays
def enable_display_timer():
global display_timer
display_timer = machine.Timer()
display_timer.init(freq=500, 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_digit_index, display_digits
# إيقاف تشغيل جميع الأرقام مؤقتًا قبل عرض الرقم التالي
for pin in digit_outputs:
pin.value(1)
digit_value = display_digits[current_digit_index]
display_digit(digit_value, current_digit_index)
current_digit_index = (current_digit_index + 1) % 4
# 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):
pattern = DIGIT_ENCODING.get(digit_value, DIGIT_ENCODING[' '])
offset = digit_index * 7 # حساب بداية أطراف أجزاء الرقم الحالي
# إيقاف تشغيل جميع الأرقام
for pin in digit_outputs:
pin.value(1)
# تعيين أطراف الأجزاء للرقم الحالي
for i in range(7):
if offset + i < len(segment_outputs):
segment_outputs[offset + i].value(pattern[i])
# تفعيل الرقم الحالي
if 0 <= digit_index < len(digit_outputs):
digit_outputs[digit_index].value(0)
else:
print("Error: digit_index out of range:", digit_index)
# Function to test available 7-segment displays
def display_value_test():
while True:
for i in range(10):
display_digits = list("{:4d}".format(i * 111))
time.sleep(1)
display_digits = [' ', ' ', ' ', ' ']
time.sleep(1)
def update_display_digits(voltage):
voltage_str = "{:.2f}".format(voltage)
digits = []
count = 0
for char in voltage_str:
if count < 4:
if char.isdigit() or char == '.':
digits.append(char)
count += 1
while len(digits) < 4:
digits.insert(0, ' ')
global display_digits
display_digits = digits[:4]
# Button interrupt handler
def button_handler(pin):
global last_button_time, button_pressed, display_enabled
now = time.ticks_ms()
if time.ticks_diff(now, last_button_time) > 300: # debounce
button_pressed = True
display_enabled = not display_enabled
if display_enabled:
enable_display_timer()
else:
disable_display_timer()
for pin in digit_outputs:
pin.value(1) # Turn off all digits
last_button_time = now
# Function to setup GPIO/ADC pins, timers and interrupts
def setup():
button.irq(trigger=machine.Pin.IRQ_FALLING, handler=button_handler)
if __name__ == '__main__':
setup()
while True:
if display_enabled:
read_analogue_voltage(ADC_PIN)
update_display_digits(display_value)
time.sleep(0.1)
#display_value_test()