from machine import Pin, Timer #import libraries
import utime
right_player_score = 0
left_player_score = 0
#this is the list of pins connected to leds
led_list = [Pin(i, Pin.OUT) for i in range(3,11)]
right_button = Pin(2, Pin.IN, Pin.PULL_UP)
left_button = Pin(1, Pin.IN, Pin.PULL_UP)
for led in led_list:
led.value(0) #to ensure that at the first state all the leds are off, we set output pin voltages of the leds to 0.
left_led_list = led_list
right_led_list = led_list
"""BUTTON DEBOUNCING AND INTERRUPTS """
"""--------------------------------"""
button_down_time = utime.ticks_ms()
button_up_time = utime.ticks_ms()
left_double_press_counter = 0
old_button_state_left = 1
left_button_pressed = False
#define a function for button to prevent bouncing and to control the button state every time the button is pressed
def debounce_button_for_left(pin):
"""this method is used to handle debounce, checks state between 25 ms"""
utime.sleep(0.1) #this code helps pi pico to stabilize the values coming from the button while interruption
button = pin
global old_button_state_left, button_down_time, button_up_time, left_button_pressed, left_double_press_counter
if button.value() == 0:
button_down_time = utime.ticks_ms()
if button.value() == 1:
button_up_time = utime.ticks_ms()
if old_button_state_left == 1 and button.value() == 0 and utime.ticks_diff(button_down_time, button_up_time) > 25: #We check the difference time between the time that is pressed the button and released the button, and then we make sure that time is bigger than 25 ms so that pi pico can take the input from the button without debouncing.
left_button_pressed = True
left_double_press_counter += 1
old_button_state_left = button.value() #the old button state is preserved here.
utime.sleep(0.1)
right_double_press_counter = 0
old_button_state_right = 1
right_button_pressed = False
def debounce_button_for_right(pin):
"""this method is used to handle debounce, checks state between 25 ms"""
utime.sleep(0.01) #this code helps pi pico to stabilize the values coming from the button while interruption
button = pin
global old_button_state_right, button_down_time, button_up_time, right_button_pressed, right_double_press_counter
if button.value() == 0:
button_down_time = utime.ticks_ms()
if button.value() == 1:
button_up_time = utime.ticks_ms()
if old_button_state_right == 1 and button.value() == 0 and utime.ticks_diff(button_down_time, button_up_time) > 25: #We check the difference time between the time that is pressed the button and released the button, and then we make sure that time is bigger than 25 ms so that pi pico can take the input from the button without debouncing.
right_button_pressed = True
right_double_press_counter += 1
old_button_state_right = button.value() #the old button state is preserved here.
utime.sleep(0.1)
#-------------------------------------------------------------------------------------------------------------
"""BUTTON INTERRUPT"""
left_button.irq(trigger=Pin.IRQ_FALLING | Pin.IRQ_RISING, handler=debounce_button_for_left) #interruption method is used for the button.
right_button.irq(trigger=Pin.IRQ_FALLING | Pin.IRQ_RISING, handler=debounce_button_for_right)
"""RUNNING LEDS ONE STEP AT A TIME
-----------------------------------------"""
binary_number_left = 0b00001000
binary_number_right = 0b00000001
def to_8bit_binary():
global binary_number_left, binary_number_right, binary_str_left, binary_str_right
binary_str_left = bin(int(str(binary_number_left)))
binary_str_right = bin(int(str(binary_number_right)))
"""this method converts a given number to its 8-bit binary representation"""
#bin() method represents the number in binary
#but we need to remove the '0b' prefix from the string
#ex: 3 -> '0b11'
binary_str_left = binary_str_left[2:]
binary_str_right = binary_str_right[2:]
#we need the string to be 8 characters long
#so, we concatenate sufficient number of zeroes to the front
while len(binary_str_left) < 8:
binary_str_left = '0' + binary_str_left
while len(binary_str_right) < 8:
binary_str_right = '0' + binary_str_right
return binary_str_left, binary_str_right #returns the string format of binary_number without 0b prefix
print(to_8bit_binary())
def left_to_right_one_step():
global binary_str_left, right_led_list
counter = 0
for bit in binary_str_left:
left_led_list[counter].value(int(bit)) #get the binary string in the given index (i. e. counter)
counter += 1
def right_to_left_one_step():
global binary_str_right, right_led_list, binary_number_right
counter = 0
for bit in binary_str_right:
right_led_list[counter].value(int(bit)) #get the binary string in the given index (i. e. counter)
counter += 1
"""----------------------------------------------------"""
"""DEFINE SENSE, DECIDE AND ACT FUNCTIONS WITH THEIR TIME OBJECTS
----------------------------------------------------------------------"""
double_press_flag = False
right_butt_press_flag = False
FSM_STATE = 0
def sense():
global left_button_pressed, right_button_pressed, right_butt_press_flag, FSM_STATE, binary_number_right, double_press_flag, right_double_press_counter
if right_double_press_counter == 2 and FSM_STATE == 1:
right_button_pressed = False
double_press_flag = True
print("double")
if right_button_pressed == True and double_press_flag == False:
FSM_STATE = 1
print("sense")
print("FSM_state:", FSM_STATE)
right_button_pressed = False
def FSM():
global right_butt_press_flag, FSM_STATE, binary_number_right, right_button_pressed, double_press_flag
if FSM_STATE == 0:
right_butt_press_flag = False
double_press_flag = False
right_double_press_counter = 0
elif FSM_STATE == 1:
right_butt_press_flag = True
if binary_number_right == 0b100000000:
right_led_list[0].value(0)
binary_number_right = 0b00000001
FSM_STATE = 0
if double_press_flag == True:
FSM_STATE = 0
def action():
global right_butt_press_flag, binary_number_right
if right_butt_press_flag == True:
to_8bit_binary()
right_to_left_one_step()
binary_number_right = binary_number_right << 1
print(FSM_STATE)
utime.sleep(0.8)
#Define a timer object to sense the environment:
sense_timer = Timer()
sense_timer_period_ms = 11
sense_timer.init(
period = sense_timer_period_ms,
mode = Timer.PERIODIC,
callback = lambda t : sense()
)
#Define a timer object to make computations and arrange the states in FSM:
FSM_timer =Timer()
FSM_timer_period_ms = 50
FSM_timer.init(
period = FSM_timer_period_ms,
mode = Timer.PERIODIC,
callback = lambda t : FSM()
)
#Define a timer object to make an action:
act_timer = Timer()
act_timer_period_ms = 100
act_timer.init(
period = act_timer_period_ms,
mode = Timer.PERIODIC,
callback = lambda t : action()
)