import machine
import time
from utime import sleep
BUTTON_START_PIN = 16
BUTTON_COUNT = 3
LED_START_PIN = 7
LED_COUNT = 9
MUX4_IN_PIN = 26
MUX4_S0_PIN = 27
MUX4_S1_PIN = 28
MUX4_INPUT_COUNT = 4
DEBOUNCE_DELAY = 200
last_button_press_time_stamp = 0
button_pressed_count = 0
get_passcode_list = []
PASSCODE_ENTERING_INACTIVE_TIME = 3000
## Button Init
#
# A function to initialize connected buttons
# Returns list of connected buttons
def button_Init():
button_init_list = []
for btn_idx in range(BUTTON_COUNT):
button_init_list.append(machine.Pin(BUTTON_START_PIN + btn_idx, machine.Pin.IN, machine.Pin.PULL_DOWN))
button_init_list[btn_idx].irq(trigger=machine.Pin.IRQ_FALLING, handler=interrupt_callback)
return button_init_list
## LED Init
#
# A function to initialize connected LEDs
# Returns list of connected LEDs
def led_Init():
led_init_list = []
for led_idx in range(LED_COUNT):
led_init_list.append(machine.Pin(LED_START_PIN + led_idx, machine.Pin.OUT))
return led_init_list
## MUX Init
#
# A function to initialize MUX input (to muc) and selections pins
# Returns mux s0, s1, in connected pins
def mux4_Init():
mux4_s0 = machine.Pin(MUX4_S0_PIN, machine.Pin.OUT)
mux4_s1 = machine.Pin(MUX4_S1_PIN, machine.Pin.OUT)
mux4_in = machine.Pin(MUX4_IN_PIN, machine.Pin.IN, machine.Pin.PULL_DOWN)
return mux4_s0, mux4_s1, mux4_in
## Reset password list, clear its elements
def clear_password_list():
global get_passcode_list
get_passcode_list = []
def get_button_index(pin):
# pin class as >> Pin(GPIO18, mode=IN, pull=PULL_DOWN)
x = str(pin).split(',')
y = x[0].split('(')
btn_idx = y[1][4:]
return int(btn_idx)
## Pin interrupt handler
#
# A function to handle pin interrupts
# Expects a machine.Pin type parameter
def interrupt_callback(pin):
global last_button_press_time_stamp
global button_pressed_count
current_button_press_time_stamp = time.ticks_ms()
button_press_delta = current_button_press_time_stamp - last_button_press_time_stamp
if button_press_delta > DEBOUNCE_DELAY:
last_button_press_time_stamp = current_button_press_time_stamp
get_passcode_list.append(pin)
print(f'key press: {get_button_index(pin) - BUTTON_START_PIN}')
button_pressed_count += 1
def main():
# a tiny sleep to allow the first print to be displayed
sleep(0.01)
print('Program starting')
print('')
global last_button_press_time_stamp
global button_pressed_count
global get_passcode_list
# HW Initialization
buttons = button_Init();
leds = led_Init();
s0, s1, mux_in = mux4_Init();
PASSCODE = [buttons[0], buttons[2], buttons[1]]
PASSCODE_LENGTH = len(PASSCODE)
last_decimal_value = -1
while True:
decimal_value = 0
# Convert binary representation of mux4 input lines to decimal value
for selector_val in range(MUX4_INPUT_COUNT):
s0.value(selector_val % 2)
s1.value(selector_val // 2)
decimal_value += (mux_in.value() * (pow(2, selector_val)))
if decimal_value != last_decimal_value:
last_decimal_value = decimal_value
print(f'selected output: {decimal_value}')
sleep(0.100)
if len(get_passcode_list) >= PASSCODE_LENGTH:
if get_passcode_list[:PASSCODE_LENGTH] == PASSCODE:
print('correct passcode')
if decimal_value < LED_COUNT:
print(f'Toggling led: {decimal_value}')
leds[decimal_value].toggle()
else:
print(f'Invalid output: {decimal_value}. Valid range: 0-{len(leds) - 1}. Nothing to be done')
else:
print("wrong passcode")
print('')
get_passcode_list = get_passcode_list[PASSCODE_LENGTH:]
# Reset button pressed count after the third press
if button_pressed_count == PASSCODE_LENGTH:
button_pressed_count = 0
# Clear passcode list for after 3 seconds on inactivity while entering the passcode
current_time_stamp = time.ticks_ms()
buttons_press_delta = current_time_stamp - last_button_press_time_stamp
if ((buttons_press_delta > PASSCODE_ENTERING_INACTIVE_TIME) and (button_pressed_count != 0) and (button_pressed_count < PASSCODE_LENGTH)):
clear_password_list()
button_pressed_count = 0
print("Clearing Input, Reason: Inactive while entering passcode for more than 3 seconds")
if __name__ == "__main__":
main()