Python Run script on startup

I have the script below running ok out of Thonny.

from gpiozero import Button

from PiicoDev_Unified import sleep_ms
from PiicoDev_Servo import PiicoDev_Servo, PiicoDev_Servo_Driver

# Initialise the Servo Driver Module
controller = PiicoDev_Servo_Driver() 

# Simple setup: Attach a servo to channel 1 of the controller with default properties
servo_1 = PiicoDev_Servo(controller, 1)
servo_2 = PiicoDev_Servo(controller, 2)
servo_3 = PiicoDev_Servo(controller, 3)
servo_4 = PiicoDev_Servo(controller, 4)

# Customised setup - Attach a servo to channel 1 of the controller with the following properties:
#    - min_us: the minimum expected pulse length (microsecconds)
#    - max_us: the maximum expected pulse length (microsecconds)
#    - degrees: the angular range of the servo in degrees
# Uncomment the line below to use customised properties
# servo = PiicoDev_Servo(controller, 1, min_us=600, max_us=2400, degrees=180)

print("x1 ")


inc_1 = 5

# Start positions

angle_1 =   130
servo_1.angle = 130

angle_2 = 100
servo_2.angle = 100

angle_3 = 20
servo_3.angle = 20

angle_4 = 0
servo_4.angle = 0

print("x2 ")

#********************************************************
def joint_1_add():
    global angle_1 
    angle_1_old = angle_1
    angle_1 = angle_1 + inc_1
    if angle_1 >= 180:
        angle_1 = 180
    print("1 " + str(angle_1))

    for x in range(angle_1_old,angle_1,1):
        servo_1.angle = x
        sleep_ms(100)                                                                                  

def joint_1_sub():
    global angle_1
    angle_1_old = angle_1
    angle_1 = angle_1 - inc_1
    if angle_1 <= 0:
        angle_1 = 0
    print("1 " + str(angle_1))

    for x in range(angle_1_old,angle_1,-1):
        servo_1.angle = x
        sleep_ms(100)                                                                                  
       
button_1 = Button(pin=17,bounce_time=0.05)
button_2 = Button(pin=5,bounce_time=0.05)

button_1.when_pressed = joint_1_add
button_2.when_pressed = joint_1_sub

#********************************************************
print("x3 ")

def joint_2_add():
    global angle_2 
    angle_2_old = angle_2
    angle_2 = angle_2 + inc_1
    if angle_2 >= 180:
        angle_2 = 180
    print("2 " + str(angle_2))

    for x in range(angle_2_old,angle_2, 1):
        servo_2.angle = x
        sleep_ms(100)                                                                                  

def joint_2_sub():
    global angle_2
    angle_2_old = angle_2
    angle_2 = angle_2 - inc_1
    if angle_2 <= 0:
        angle_2 = 0
    print("2 " + str(angle_2))

    for x in range(angle_2_old,angle_2,-1):
        servo_2.angle = x
        sleep_ms(100)                                                                                  
       
button_3 = Button(pin=22,bounce_time=0.05)
button_4 = Button(pin=27,bounce_time=0.05)

button_3.when_pressed = joint_2_add
button_4.when_pressed = joint_2_sub

#********************************************************
print("x4 ")

def joint_3_add():
    global angle_3 
    angle_3_old = angle_3
    angle_3 = angle_3 + inc_1
    if angle_3 >= 180:
        angle_3 = 180
    print("3 " + str(angle_3))

    for x in range(angle_3_old,angle_3,1):
        servo_3.angle = x
        sleep_ms(100)                                                                                  

def joint_3_sub():
    global angle_3
    angle_3_old = angle_3
    angle_3 = angle_3 - inc_1
    if angle_3 <= 0:
        angle_3 = 0
    print("3 " + str(angle_3))

    for x in range(angle_3_old,angle_3,-1):
        servo_3.angle = x
        sleep_ms(100)                                                                                  
       
button_5 = Button(pin=6,bounce_time=0.05)
button_6 = Button(pin=19,bounce_time=0.05)

button_5.when_pressed = joint_3_add
button_6.when_pressed = joint_3_sub

#********************************************************
print("x5 ")

def joint_4_add():
    global angle_4 
    angle_4_old = angle_4
    angle_4 = angle_4 + inc_1
    if angle_4 >= 180:
        angle_4 = 180
    print(angle_4)

    for x in range(angle_4_old,angle_4,1):
        servo_4.angle = x
        sleep_ms(100)                                                                                  

def joint_4_sub():
    global angle_4
    angle_4_old = angle_4
    angle_4 = angle_4 - inc_1
    if angle_4 <= 0:
        angle_4 = 0
    print(angle_4)

    for x in range(angle_4_old,angle_4,-1):
        servo_4.angle = x
        sleep_ms(100)                                                                                  
       
button_7= Button(pin=25,bounce_time=0.05)
button_8 = Button(pin=24,bounce_time=0.05)

button_7.when_pressed = joint_4_add
button_8.when_pressed = joint_4_sub
            
print("x6 ")

There is no apparent while loop but I assume there is one behind the scenes.

I want it to run on startup and have added this line to rc.local

python3 /home/gjc/mikado/robot.py &

my script runs because it implements the startup positions near the beginning of the script.

However, the buttons do not work.

Any clues on why please?

The Pi will be at the top of a 15 metre mast so it will be running headless.

1 Like

Hey @Geoff45102,

What a weird error my best guess would be that this is caused by the inner workings of the ‘gpiozero’ library that you are importing ‘Button’ from.

It uses multi-threading for button handling so it’s possible the button event handler thread might be killed off when your program finishes executing what it can without extra input from the buttons.

This is likely because there is no ‘wait’ mechanism in your script to enable it to wait for the button event handlers to finish their operation.

I would manually add a loop to the bottom of this code to stop it from finishing before you are expecting it to. Something like this while loop should do the trick to keep it running.

while True: 
    sleep_ms(100)

Let me know how that goes!

1 Like

Like a charm. Thanks

2 Likes