I have an Arduino Nano & am success fully controlling 4 servos from it but it then occurred to me that I am controlling these in a serial manner, ie I set 1 position then the next then the next....
I would like the servos to act in a parallel manner i.e. that their motions can happen at the same time but at different speeds or different position.
Is this possible using just 1 controller (maybe some sort of polling/interrupt setup?) or will I need to run separate controllers for each set of servos & synchronize them?
EDIT: Added the PC side code & the Arduino side code
PC Python code:
from Tkinter import *
import serial
usbport = 'COM5'
ser = serial.Serial(usbport, 9600, timeout=1)
def init():
for servo in range(1, 5):
print servo
ser.write(chr(255))
ser.write(chr(servo))
ser.write(chr(90))
class App:
def __init__(self, master):
frame = Frame(master)
frame.pack()
self.scale1 = Scale(master, from_=0, to=180, command=lambda ev: self.getAngle(1), bd=5, bigincrement=2, length=360, width=30, label='Servo 1')
self.scale1.set(90)
self.scale1.pack(side=LEFT)
self.scale2 = Scale(master, from_=0, to=180, command=lambda ev: self.getAngle(2), bd=5, bigincrement=2, length=360, width=30, label='Servo 2')
self.scale2.set(90)
self.scale2.pack(side=LEFT)
self.scale3 = Scale(master, from_=0, to=180, command=lambda ev: self.getAngle(3), bd=5, bigincrement=2, length=360, width=30, label='Servo 3')
self.scale3.set(90)
self.scale3.pack(side=LEFT)
self.scale4 = Scale(master, from_=0, to=180, command=lambda ev: self.getAngle(4), bd=5, bigincrement=2, length=360, width=30, label='Servo 4')
self.scale4.set(90)
self.scale4.pack(side=LEFT)
self.centre = Button(frame, text="Centre All", command=self.centre)
self.centre.pack(side=TOP)
def getAngle(self, slider):
if slider==1:
ang = self.scale1.get()
if slider==2:
ang = self.scale2.get()
if slider==3:
ang = self.scale3.get()
if slider==4:
ang = self.scale4.get()
ser.write(chr(255))
ser.write(chr(slider))
ser.write(chr(ang))
def centre(self):
for servo in range(1, 5):
ser.write(chr(255))
ser.write(chr(servo))
ser.write(chr(90))
self.scale1.set(90)
self.scale2.set(90)
self.scale3.set(90)
self.scale4.set(90)
init()
root = Tk()
app = App(root)
root.mainloop()
Arduino code
*
* ------------------------------
* MultipleSerialServoControl
* ------------------------------
*
* Uses the Arduino Serial library
* (http://arduino.cc/en/Reference/Serial)
* and the Arduino Servo library
* (http://arduino.cc/en/Reference/Servo)
* to control multiple servos from a PC using a USB cable.
*
* Dependencies:
* Arduino 0017 or higher
* (http://www.arduino.cc/en/Main/Software)
* Python servo.py module
* (http://principialabs.com/arduino-python-4-axis-servo-control/)
*
* Created: 23 December 2009
* Author: Brian D. Wendt
* (http://principialabs.com/)
* Version: 1.1
* License: GPLv3
* (http://www.fsf.org/licensing/)
*
*/
// Import the Arduino Servo library
#include <Servo.h>
// Create a Servo object for each servo
Servo servo1;
Servo servo2;
Servo servo3;
Servo servo4;
// Common servo setup values
int minPulse = 600; // minimum servo position, us (microseconds)
int maxPulse = 2400; // maximum servo position, us
// User input for servo and position
int userInput[3]; // raw input from serial buffer, 3 bytes
int startbyte; // start byte, begin reading input
int servo; // which servo to pulse?
int pos = 90; // servo angle 0-180
int i; // iterator
// LED on Pin 13 for digital on/off demo
int ledPin = 13;
int pinState = LOW;
void setup()
{
// Attach each Servo object to a digital pin
servo1.attach(3, minPulse, maxPulse);
servo2.attach(4, minPulse, maxPulse);
servo3.attach(5, minPulse, maxPulse);
servo4.attach(9, minPulse, maxPulse);
// LED on Pin 13 for digital on/off demo
pinMode(ledPin, OUTPUT);
// Open the serial connection, 9600 baud
Serial.begin(9600);
}
void loop()
{
// Wait for serial input (min 3 bytes in buffer)
if (Serial.available() > 2) {
// Read the first byte
startbyte = Serial.read();
// If it's really the startbyte (255) ...
if (startbyte == 255) {
// ... then get the next two bytes
for (i=0;i<2;i++) {
userInput[i] = Serial.read();
}
// First byte = servo to move?
servo = userInput[0];
// Second byte = which position?
pos = userInput[1];
// Packet error checking and recovery
if (pos == 255) { servo = 255; }
// Assign new position to appropriate servo
switch (servo) {
case 1:
servo1.write(pos); // move servo1 to 'pos'
break;
case 2:
servo2.write(pos);
break;
case 3:
servo3.write(pos);
break;
case 4:
servo4.write(pos);
break;
// LED on Pin 13 for digital on/off demo
case 99:
if (pos == 180) {
if (pinState == LOW) { pinState = HIGH; }
else { pinState = LOW; }
}
if (pos == 0) {
pinState = LOW;
}
digitalWrite(ledPin, pinState);
break;
}
}
}
}
centre()
function in the Python code the servo's are looped through)? – DrBwts Oct 14 '15 at 10:59