Stuart Compaan
Stuart Compaan

Reputation: 187

How to move two servos at the same time using pyfirmata, python and Arduino

I am trying to program a robot arm and I need two servos to run at the same time and be able to run in different directions for example on going 90° to 180° and the other servo going 90° to 0° , I am using a Arduino, python and pyfirmata any help would be good thank you!

import pyfirmata
import time

board = pyfirmata.Arduino('/dev/cu.usbmodem14201')

armlower2 = board.get_pin('d:6:s')
armlower1 = board.get_pin('d:10:s')

for angle in range(90, 180, 1):
    armlower2.write(angle)
    time.sleep(0.015)

for angle in range(180, 90, -1):
    armlower2.write(angle)
    time.sleep(0.015)

for angle in range(90, 0, -1):
    armlower1.write(angle)
    time.sleep(0.015)

for angle in range(0, 90, 1):
    armlower1.write(angle)
    time.sleep(0.015)

This moves the servos but only one at a time ?

Upvotes: 1

Views: 1779

Answers (2)

Łukasz Kwieciński
Łukasz Kwieciński

Reputation: 15728

The easiest approach would be to use threading, here's a really simple example:

import threading

def move_armlower2(): 
    for angle in range(90, 180, 1):
        armlower2.write(angle)
        time.sleep(0.015)

    for angle in range(180, 90, -1):
        armlower2.write(angle)
        time.sleep(0.015)

def move_armlower1():
    for angle in range(90, 0, -1):
        armlower1.write(angle)
        time.sleep(0.015)

   for angle in range(0, 90, 1):
        armlower1.write(angle)
        time.sleep(0.015)

threads = [
    threading.Thread(target=move_armlower2), # Creating threads
    threading.Thread(target=move_armlower1) 
]

for th in threads:
    th.start() # Starts the thread

for th in threads:
    th.join() # Waits for the thread to terminate

References:

Upvotes: 2

mmixLinus
mmixLinus

Reputation: 1714

You should write your main loop around the concepts of "current value" and "want value", i.e., the values you want vs the values (angles) you currently are at. This can be expanded to any number of motors using arrays for the motors, and traversing their values in a loop. But for two, you can simply do the following.

// The angle values you want to achieve, and what they currently are
GLOBAL want1, want2
GLOBAL current1, current2
LOOP {
    LOCAL updelta = 1
    LOCAL downdelta = -1
    if want1 > current1
        movearm1(updelta)
        current1 = current1 + updelta
    else if want1 < current1
        movearm1(downdelta)
        current1 = current1 + downdelta
    if want2 > current2
        movearm2(updelta)
        current2 = current2 + updelta
    else if want2 < current2
        movearm2(downdelta)
        current2 = current2 + downdelta

    sleep(0.015)
}

Upvotes: 1

Related Questions