0

I am new to programming and am using Python/pyfirmata to control a little servo motor via my arduino. I have the motor working as I want it to: it spins x degrees every 3 seconds. The problem is that I'd like it to do so continuously until user input tells it to stop.

The code below will continuously ask for user input, which (if 1+ENTER is pressed) causes the motor to turn 3 times before asking for user input again. I can't figure out a way to get the motor running through those positions continuously while simultaneously being able to take user input to stop the motor.

Said another way, this is what I want to be able to do: Motor is off and user input is requested. User presses 1+ENTER and motor starts cycling through positions. If user presses 2+ENTER, motor stops. If user presses 1+ENTER again, motor starts cycling again. Seems simple, hopefully it is!

My current code:

from pyfirmata import SERVO
from pyfirmata import Arduino

board = Arduino("COM4")
board.digital[10].mode = SERVO
servo1 = board.get_pin('d:10:0')

while True:
  user_control = input('Enter 1 to start motor and 2 to stop motor \n')
  if user_control == '1':
    servo1.write(45)
    time.sleep(3)
    servo1.write(90)
    time.sleep(3)
    servo1.write(180)
    time.sleep(3)
  elif user_control == '2':
    servo1.write(45)
    print('motor paused')
dcmpjc
  • 1
  • You should probably look into [Threads](https://docs.python.org/3/library/threading.html) – Mike Scotty Dec 09 '19 at 00:15
  • This might be helpful https://stackoverflow.com/questions/15528939/python-3-timed-input – Aggragoth Dec 09 '19 at 00:25
  • You'll need some time to digest it, but I think you'll find everything you need in it: [How to control a Thread via input()?](https://stackoverflow.com/a/52356579/9059420) – Darkonaut Dec 09 '19 at 00:45

1 Answers1

0

Thanks to all for the input. I have this working the way I want now. In the end I created a thread to run the user_input function and threading.Timer to cause it to loop so that new input could be given every 1 second. The output from that thread sets a pin value on the arduino which determines whether the while loop controlling the motor will run, which turns the motor. Thanks again! My code is below.

from pyfirmata import SERVO
from pyfirmata import Arduino, util
import threading
import time

board = Arduino("COM4")
board.digital[10].mode = SERVO
servo1 = board.get_pin('d:10:o')
LED = board.get_pin('d:8:o')
servo1.write(15)


def user_input():
    userinput = input('Press 1 or 2\n')
    if userinput == '1':
        return board.digital[7].write(1)
    elif userinput == '2':
        return board.digital[7].write(0)
    elif userinput != "1" or "2":
        input('Press 1 or 2\n')

t1 = threading.Thread(user_input())
threading.Timer(1,user_input).start()

def autorun():
    while board.digital[7].read() == 1:
        servo1.write(45)
        time.sleep(2)
        servo1.write(90)
        time.sleep(2)
        servo1.write(180)
        time.sleep(2)
    if board.digital[7].read() == 0:
        print('automatic run stopped')

autorun()
dcmpjc
  • 1