Problem Statement
Individuals living with Multiple Sclerosis (MS) often experience progressive motor weakness, spasticity, and reduced range of motion, making consistent upper-limb physiotherapy difficult to maintain. While regular rehabilitation is critical for preserving mobility and functional independence, existing physiotherapy solutions are frequently clinic-dependent, costly, repetitive, or poorly suited to patients’ daily routines—especially for those who travel or experience fatigue easily. As a result, many MS patients struggle with long-term adherence to therapy, leading to further functional decline. There is a need for a safe, affordable, and engaging at-home physiotherapy device that supports range-of-motion exercises, accommodates fluctuating fatigue levels, and empowers patients to independently manage their rehabilitation.
Control & Game Logic (Python, Raspberry Pi
PYTHONfrom sensor_library import *
m gpiozero import *
import time
import sys
import random
# Define GPIO pin numbers for buttons, LEDs, buzzer and photocells
button1 = Button(21)
button2 = Button(20)
led1 = LED(26)
led2 = LED(19)
led3 = LED(13)
led4 = LED(6)
buzzer = Buzzer(10)
photocell1 = Force_Sensing_Resistor(0)
photocell2 = Force_Sensing_Resistor(1)
photocell3 = Force_Sensing_Resistor(2)
photocell4 = Force_Sensing_Resistor(3)
# This function turns all LEDs on and prompts the user to start a session by pressing the "game" button.
def device_on():
led1.on()
led2.on()
led3.on()
led4.on()
print("Welcome! Press the 'game' button to start your session.")
# When this button is pressed, it will execute the device_on function.
button1.when_pressed = device_on
# This function starts the game by prompting the user to type in a level, turns on random LEDs, and tracks the number of lights turned off for a set time interval.
def start_game(level):
start_time = 0
threshold = 80
light = 0
start = time.time()
elapsed_time = 0
stop = 15
# Prompting the user to input a level corresponding to how long they would like their time session to be.
level = int(input("Type number of level (30-second session is level 1, 60-second session is level 2, etc.) or type 0 to quit:"))
# if zero is inpuutted, the game turns off.
if level == 0:
print("Game turning off...")
print("Goodbye.")
else:
# Depending on the level inputted, the start time (initalized at 0) will increase by an interval of 30 seconds, modifying the session time interval.
for i in range(level):
start_time += 30
# While the time passed is less than the time interval of the session, a random number is called between 1-4, corresponding to a specific LED turning on.
while elapsed_time < start_time:
broken = False
call = random.randint(1,4)
# if 1 is called, LED 1 turns on and the corresponding photocell is monitored.
if call == 1:
while photocell1.force_raw() >= threshold:
value = photocell1.force_raw()
led1.on()
led2.off()
led3.off()
led4.off()
elapsed_time = time.time()-start
# If the photocell resistance (value) is less than the set threshold, the light will turn off, trigger the buzzer to beep, the light and elapsed time are recorded and displayed.
if value < threshold:
buzzer.on()
time.sleep(0.1)
buzzer.off()
time.sleep(0.1)
buzzer.on()
time.sleep(0.1)
buzzer.off()
led1.off()
light+=1
stop += elapsed_time
print("Elapsed time:", round(elapsed_time,2))
print(round(stop,2))
print("light hit:", round(light,2))
# If the resistance value is consistently greater than the threshold for more than the initialized buffer time (15 secs), the loop breaks and level is not complete the level.
elif value >= threshold and elapsed_time >= stop:
broken = True
print ("Sorry, you did not complete this level. Take a break and come again later.")
led1.off()
break
if broken == True:
break
# This process is repeated for other three LEDs
elif call == 2:
while photocell2.force_raw() >= threshold:
value = photocell2.force_raw()
led2.on()
led1.off()
led3.off()
led4.off()
elapsed_time = time.time()-start
if value < threshold:
buzzer.on()
time.sleep(0.1)
buzzer.off()
time.sleep(0.1)
buzzer.on()
time.sleep(0.1)
buzzer.off()
led2.off()
light+=1
stop += elapsed_time
print("Elapsed time:", round(elapsed_time,2))
print(round(stop,2))
print("light hit:", round(light,2))
elif value >= threshold and elapsed_time >= stop:
broken = True
print ("Sorry, you did not complete this level. Take a break and come again later.")
led2.off()
break
if broken == True:
break
elif call == 3:
while photocell3.force_raw() >= threshold:
value = photocell3.force_raw()
led3.on()
led1.off()
led2.off()
led4.off()
elapsed_time = time.time()-start
if value < threshold:
buzzer.on()
time.sleep(0.1)
buzzer.off()
time.sleep(0.1)
buzzer.on()
time.sleep(0.1)
buzzer.off()
led3.off()
light+=1
stop += elapsed_time
print("Elapsed time:", round(elapsed_time,2))
print(round(stop,2))
print("light hit:", round(light,2))
elif value >= threshold and elapsed_time >= stop:
broken = True
print ("Sorry, you did not complete this level. Take a break and come again later.")
led3.off()
break
if broken == True:
break
elif call == 4:
while photocell4.force_raw() >= threshold:
value = photocell4.force_raw()
led4.on()
led1.off()
led2.off()
led3.off()
elapsed_time = time.time()-start
if value < threshold:
buzzer.on()
time.sleep(0.1)
buzzer.off()
time.sleep(0.1)
buzzer.on()
time.sleep(0.1)
buzzer.off()
led4.off()
light+=1
stop += elapsed_time
print("Elapsed time:", round(elapsed_time,2))
print(round(stop,2))
print("light hit:", round(light,2))
elif value >= threshold and elapsed_time >= stop:
broken = True
print ("Sorry, you did not complete this level. Take a break and come again later.")
led4.off()
break
if broken == True:
break
# When the time of level is completed, the user is congratulated and told how many lights they've hit.
# Prompts the user to start the next level.
if elapsed_time >= start_time and broken == False:
print("Congrats! You succesfully completed level", level, "! You hit", light, "lights!")
start_time += 30
print ("Your next session is a", start_time, "-second interval. Press and hold the 'game' button to start:")
music()
# the LEDs blink after the game is complete.
while button2.is_pressed == False:
led1.on()
led2.on()
led3.on()
led4.on()
time.sleep(0.5)
led1.off()
led2.off()
led3.off()
led4.off()
time.sleep(0.5)
# when the "game" button is pressed, the start_game function is called.
button2.when_pressed = start_game
# This function makes the buzzer chime three times and is called when level is completed to indicate the user.
def music():
buzzer.on()
time.sleep(0.2)
buzzer.off()
time.sleep(0.05)
buzzer.on()
time.sleep(0.2)
buzzer.off()
time.sleep(0.05)
buzzer.on()
time.sleep(0.2)
buzzer.off()