1

I'm currently trying to write a program for a raspberry pi in Python 3 to control a set of linear actuators situated on a table that will both change the length of the legs and allow for the table top to be angled. One of the features of the table is an automatic leveling feature to ensure that the tabletop is is always level and will self correct if it detects it is not by pulling data from an onboard accelerator. The autolevel feature works perfectly fine however I am having difficulty programming on and off conditions. Ideally typing a(1) in the console will call the autolevel function and cause it to run continuously until typing a(0) stops it. I managed to get the function to run by typing a(1) but once that command is accepted the program stops listening for further commands and loops endlessly. The code in its current state is posted bellow.

def a(n):
    while n== 1:
        acceleration = sense.get_accelerometer_raw()
        x = acceleration['x']
        y = acceleration['y']
        z = acceleration['z']
        
        x=round(x, 3)
        y=round(y, 3)
        z=round(z, 3)
        
        if x >0.00:
            GPIO.output(12,0)
            GPIO.output(13,1)#leg 1 retract
            GPIO.output(15,0)
            GPIO.output(29,1)#leg 2 retract
            GPIO.output(31,1)
            GPIO.output(32,0)#leg 3 extend
            GPIO.output(33,1)
            GPIO.output(36,0)#leg 4 extend
            sense.show_message('Correcting forward tilt')
            
        elif x <0.00:
            GPIO.output(12,1)
            GPIO.output(13,0)#leg 1 extend
            GPIO.output(15,1)
            GPIO.output(29,0)#leg 2 extend
            GPIO.output(31,0)
            GPIO.output(32,1)#leg 3 retract
            GPIO.output(33,0)
            GPIO.output(36,1)#leg 4 retract
            sense.show_message('Correcting rearward tilt')
            
        else:
            if y >0.00:
                GPIO.output(12,0)
                GPIO.output(13,1)#leg 1 retract
                GPIO.output(15,1)
                GPIO.output(29,0)#leg 2 extend
                GPIO.output(31,0)
                GPIO.output(32,1)#leg 3 retract
                GPIO.output(33,1)
                GPIO.output(36,0)#leg 4 extend
                sense.show_message('Correcting right side tilt')
            elif y <0.00:
                GPIO.output(12,1)
                GPIO.output(13,0)#leg 1 extend
                GPIO.output(15,0)
                GPIO.output(29,1)#leg 2 retract
                GPIO.output(31,1)
                GPIO.output(32,0)#leg 3 extend
                GPIO.output(33,0)
                GPIO.output(36,1)#leg 4 retract
                sense.show_message('Correcting left side tilt')
            else:
                sense.show_message("No tilt to correct")
                print ("Stand currently level, standing by for reactive adjustment.")
  • This might help: https://stackoverflow.com/questions/49550355/how-to-stop-a-program-when-a-key-is-pressed-in-python – xnx Jul 28 '20 at 20:27
  • I think this may be in the vein of what I'm looking for but I'm unsure how to modify the code such that it's not just on by default. There's an accompanying raise and lower command for the tabletop that I don't think will be operable while the auto level is running. Ideally this would be a function that the user turns on and off themselves. – Jacob Caraig Jul 28 '20 at 20:43
  • @JacobCaraig did you try the multithreading way? – Hussain Jul 28 '20 at 21:03

1 Answers1

0

You can use multi threading, here is how you can incorporate it into:

You will be asked to enter value which in your case would be "exit" keyword. Let me know if worked.

import threading 

flag=False
def a1(): 
    global flag
    a= flag
    #if(a==True):
    while (!a):
        acceleration = sense.get_accelerometer_raw()
        x = acceleration['x']
        y = acceleration['y']
        z = acceleration['z']
        #paste the rest of your code here
   
    
def loopBreak(): 
    """ 
    function to exit the loop
    """
    global flag
    inp=input("Enter value")
    if inp=="exit":
      flag =True


if __name__ == "__main__": 
    # creating thread 
    t1 = threading.Thread(target=a1) 
    t2 = threading.Thread(target=loopBreak) 
  
    # starting thread 1 
    t1.start() 
    # starting thread 2 
    t2.start() 
  
    # wait until thread 1 is completely executed 
    t1.join() 
    # wait until thread 2 is completely executed 
    t2.join() 
    print(flag)
    # both threads completely executed 
    print("Done!") 
Hussain
  • 308
  • 2
  • 7
  • Unfortunately the provided code didn't work, it initialized the autoleveling program automatically without user input and didn't accept the exit command. – Jacob Caraig Jul 28 '20 at 21:05
  • @JacobCaraig how are you executing your script? did you also get "Enter value" prompt in the terminal or wherever you're running? I've made one small edit which I'd forgot to add. You need to slightly modify the while portion. check if it works now. – Hussain Jul 28 '20 at 21:51
  • I'm executing the script by using the Run feature in Thonny. I also made the edits you suggested but came up with the same result. – Jacob Caraig Jul 28 '20 at 22:28
  • @JacobCaraig can you try to run it using command prompt/terminal once? – Hussain Jul 29 '20 at 09:19