from machine import Timer, Pin
import utime
#DECLARATIONS
#Defining led pins
led_pins=[0,1,2,3,4,5,6,7]
#Defining the corresponding led pins as outputs
leds = list()
for x in range(len(led_pins)):
leds.append(Pin(led_pins[x], Pin.OUT))
FSM_state = 0
LED_mask_close = 0
LED_mask_far = 0
LED_state_close = 0
LED_state_far = 0
move_LEDS_close = False
move_LEDS_far = False
lit_pin_close = None
lit_pin_far = None
# button related
button_close = Pin(8, Pin.IN, Pin.PULL_UP)
button_far = Pin(9, Pin.IN, Pin.PULL_UP)
button_close_state = 0
button_far_state = 0
button_pressed_released_close = False
button_pressed_released_far = False
player_close_pts = 0
player_far_pts = 0
last_time_close = 0
last_time_far = 0
success_close = False
success_far = False
collision_flag = False
collision_dict_close = {}
collision_dict_far = {}
result_dict = {}
for pin_order, led in enumerate(leds):
collision_dict_close[f"order_{pin_order}"] = 0
collision_dict_far[f"order_{pin_order}"] = 0
result_dict[f"order_{pin_order}"] = 0
"""both of the led functions ( move_lights_far() and move_lights_close())
will update this dictionary by adding 1 for each pin
if a value of 2 obtained at any pin the it means collision has occured.
By doing this first case of collision is handled"""
debounce_time = 30 #ms
# FSM code
def FSM():
global FSM_state, move_LEDS_close, move_LEDS_far, button_pressed_released_far, \
button_pressed_released_close,collision_flag, success_far, success_close, \
player_far_pts, player_close_pts
if FSM_state == 0:
if button_pressed_released_close:
#ledler soldan sağa hareket etcek move_LEDS = True demiş
FSM_state = 1
button_pressed_released_close = False
elif button_pressed_released_far:
#ledler tam tersi yönde hareket etcek move_LEDS = True demiş
FSM_state = 3
button_pressed_released_far = False
elif FSM_state == 1:
move_LEDS_close = True
if button_pressed_released_close:
print("player_close pressed more than once!")
print (f"SCORE:\nplayer_close: {player_close_pts}, player_far: {player_far_pts}\n\
player_far won")
move_LEDS_close = False
FSM_state = 0
player_close_pts = 0
player_far_pts = 0 #initialize game içine koyulablir bunlar if (game ended) sıfırla tarzı
initialize_game()
button_pressed_released_close = False
else:
if success_close:
move_LEDS_close = False
player_close_pts += 1
if player_close_pts == 5:
print (f"SCORE:\nplayer_close: {player_close_pts}, player_far: {player_far_pts}\n\
player_close won")
player_close_pts = 0
player_far_pts = 0
else:
print(f"SCORE:\nplayer_close: {player_close_pts}, player_far: {player_far_pts}")
FSM_state = 0
success_close = False
move_LEDS_close = False
initialize_game()
elif button_pressed_released_far:
FSM_state = 2
button_pressed_released_far = False
move_LEDS_far = True
elif FSM_state == 2:
if button_pressed_released_close:
print("player_close pressed more than once!")
print (f"SCORE:\nplayer_close: {player_close_pts}, player_far: {player_far_pts}\n\
player_far won")
FSM_state = 0
move_LEDS_close = False
player_close_pts = 0
player_far_pts = 0
initialize_game()
button_pressed_released_close = False
elif button_pressed_released_far:
print("player_far pressed more than once!")
print (f"SCORE:\nplayer_close: {player_close_pts}, player_far: {player_far_pts}\n\
player_close won")
FSM_state = 0
move_LEDS_far = False
player_close_pts = 0
player_far_pts = 0
initialize_game()
button_pressed_released_far = False
elif collision_flag == True:
print("collision")
collision_flag = False
move_LEDS_close = False
move_LEDS_far = False
print("Clashing shots, move on to next round")
print (f"SCORE:\nplayer_close: {player_close_pts}, player_far: {player_far_pts}")
FSM_state = 0
initialize_game()
elif FSM_state == 3:
move_LEDS_far = True
if button_pressed_released_far:
print("player_close pressed more than once!")
print (f"SCORE:\nplayer_close: {player_close_pts}, player_far: {player_far_pts}\n\
player_close won")
FSM_state = 0
player_close_pts = 0
player_far_pts = 0 #initialize game içine koyulablir bunlar if (game ended) sıfırla tarzı
initialize_game()
button_pressed_released_far = False
else:
if success_far:
player_far_pts += 1
if player_far_pts == 5:
print (f"SCORE:\nplayer_close: {player_close_pts}, player_far: {player_far_pts}\n\
player_far won")
player_close_pts = 0
player_far_pts = 0 #initialize game içine koyulablir bunlar
else:
print(f"SCORE:\nplayer_close: {player_close_pts}, player_far: {player_far_pts}")
FSM_state = 0
success_far = False
move_LEDS_far = False
initialize_game() # bu fonksiyon reseticek buna bak
elif button_pressed_released_close:
FSM_state = 2
button_pressed_released_close = False
move_LEDS_close = True
#callback functions for pins
def sense_ISR(timer):
check_button_close()
check_button_far()
def compute_ISR(timer):
FSM()
def actuate_ISR(time):
button_close_fire()
move_lights_close()
button_far_fire()
move_lights_far()
# define the timers
timer_sense = Timer()
timer_compute = Timer()
timer_actuate = Timer()
# initialize timers
timer_sense.init(period = 50, mode = Timer.PERIODIC, callback = sense_ISR)
timer_compute.init(period = 10, mode = Timer.PERIODIC, callback = compute_ISR)
timer_actuate.init(period = 1000, mode = Timer.PERIODIC, callback = actuate_ISR)
# check the close button (to pico) with debounce
def check_button_close():
global button_close_state, button_pressed_released_close, last_time_close
if button_close_state == 0:
if button_close.value() == 0:
new_time_close = utime.ticks_ms()
if utime.ticks_diff(new_time_close, last_time_close) > debounce_time:
last_time_close = new_time_close
button_close_state = 1
elif button_close_state == 1:
if button_close.value() == 1:
new_time_close = utime.ticks_ms()
if utime.ticks_diff(new_time_close, last_time_close) > debounce_time:
last_time_close = new_time_close
button_close_state = 0
button_pressed_released_close = True
# check the far button (to pico) with debounce
def check_button_far():
global button_far_state, button_pressed_released_far, last_time_far
if button_far_state == 0:
if button_far.value() == 0:
new_time_far = utime.ticks_ms()
if utime.ticks_diff(new_time_far, last_time_far) > debounce_time:
last_time_far = new_time_far
button_far_state = 1
elif button_far_state == 1:
if button_far.value() == 1:
new_time_far = utime.ticks_ms()
if utime.ticks_diff(new_time_far, last_time_far) > debounce_time:
last_time_far = new_time_far
button_far_state = 0
button_pressed_released_far = True
# led related functions
def button_close_fire():
global LED_mask_close, move_LEDS_close
if move_LEDS_close:
if LED_mask_close == 0:
LED_mask_close = 0b10000000
return
if LED_mask_close != 0b00000001:
LED_mask_close= LED_mask_close >> 1
def move_lights_close():
global LED_state_close, success_close, collision_dict_close,collision_dict_far, \
result_dict,collision_flag, lit_pin_close
LED_state_close = LED_mask_close
LED_bit = 7
for pin_order,led in enumerate(leds):
led.value((LED_state_close >> LED_bit) & 1)
if (LED_state_close >> LED_bit) & 1:
lit_pin_close = pin_order
collision_dict_close[f"order_{pin_order}"] += 1
result_dict = {key: collision_dict_close.get(key, 0) +\
collision_dict_far.get(key, 0) for key in set(collision_dict_close) | set(collision_dict_far)}
if led == leds[7]:
success_close = True
LED_bit = LED_bit - 1
if lit_pin_close != None:
print("close")
if result_dict[f"order_{lit_pin_close}"] == 2:
collision_flag = True
print("collision")
collision_dict_close = {key: 0 for key in collision_dict_close}
result_dict = {key: 0 for key in result_dict}
lit_pin_close = None
return
print(result_dict.values())
for pin_order, led in enumerate(leds):
if (collision_dict_far[f"order_{pin_order}"] == 1) and (pin_order < lit_pin_close):
collision_flag = True
print("collision")
""" this for loop checks for the other case of collision:
if the turned on leds goes over each other. Since the collision_dict() will be updated
if another led is lit up due to the other player if the order of that led is smaller from
close to far then it means leds have gone over each other hence collision is occured."""
collision_dict_close = {key: 0 for key in collision_dict_close}
def button_far_fire():
global LED_mask_far, move_LEDS_far
if move_LEDS_far:
if LED_mask_far == 0:
LED_mask_far = 0b00000001
return
if LED_mask_far != 0b10000000:
LED_mask_far = LED_mask_far << 1
def move_lights_far():
global LED_state_far, success_far, collision_dict_far, collision_flag, lit_pin_far, result_dict
LED_state_far = LED_mask_far
LED_bit = 7
for pin_order,led in enumerate(leds):
led.value((LED_state_far >> LED_bit) & 1)
if (LED_state_far >> LED_bit) & 1:
lit_pin_far = pin_order
collision_dict_far[f"order_{pin_order}"] += 1
if led == leds[0]:
success_far = True
LED_bit = LED_bit - 1
if lit_pin_far != None:
print("far")
if (result_dict[f"order_{lit_pin_far}"] == 2) and (collision_flag == False):
collision_flag = True
print("collison")
collision_dict_far = {key: 0 for key in collision_dict_far}
result_dict = {key: 0 for key in result_dict}
lit_pin_far = None
return
#print(collision_dict_far.values())
for pin_order, led in enumerate(leds):
if (collision_dict_far[f"order_{pin_order}"] ==1) and (pin_order > lit_pin_far):
collision_flag = True
print("collision")
collision_dict_far = {key: 0 for key in collision_dict_far}
# Utility functions
def initialize_game():
global LED_state_close, LED_mask_close,LED_state_far, LED_mask_far
LED_state_close = 0
LED_mask_close = 0
LED_state_far = 0
LED_mask_far = 0
def clear_leds():
LED_mask_close = 0
move_lights_close()
LED_mask_far = 0
move_lights_far()