Although the Arduino platform is ideal for standalone applications, it really comes to life when interfaced with a PC. Connect Arduino to a personal computer and you instantly add a ton of versatility and processing power to your project.
This tutorial will describe how to use Arduino to control a bank of four independent RC servos with your PC (or Mac, or *nix Box), using a USB cable and a modular Arduino-Python software stack.
The following discussion builds upon concepts presented in two previous articles, “Arduino Serial Servo Control” and “Joystick Control of a Servo.” As always, comments, critiques, or suggestions for improving or adapting this code are welcome and appreciated.
Project Outline
The primary goal for this project was to create a software stack that allows simple and flexible control of multiple servos from any type of Python script.
The solution has two basic components: (1) an Arduino sketch that waits for serial input from a connected PC, then moves each servo to its commanded position, and; (2) a Python module on the PC that opens the serial connection and formats the data packets expected by the Arduino.
Any other Python program written to sit on top of these two layers need not worry about the messy details of serial communication, but rather can just say something like, “Move servo #2 to 90 degrees.” Or, more precisely:
servo.move(2,90)
Easy, right? Let’s get started.
Part I: Smoke, Mirrors, and Hand-Waving
If you just want to get things up and running quickly, start here. These instructions will get your servos connected and obeying every whim of your PC in no time.
Hardware Setup
Hardware for this project consists of an Arduino module, four JR Sport ST47 standard servos, and a breadboard to create the circuit.
The servos each have three wires: Ground (brown), Power (red) and Control (yellow). Each of the Control wires will connect to a different digital pin on the Arduino board (pins 2 through 5 in our setup), and all of the Power and Ground wires will need to connect somehow to the 5V and Gnd pins.
The simplest way to accomplish this is to create a “bus” bar along one of the breadboard’s edges, as shown in the photo above. Simply route the Arduino’s 5V and Gnd to a convenient area on the breadboard, and connect all the servos.
Required Software: The Lower Layers
To get the effects seen in the video above, you’ll need at least the following two programs. Although this code is designed to control four servos, it also works as-is with fewer servos, and — with a few modifications — as many as twelve (or 48 with the Arduino Mega!).
Download the code:
MultipleServos.pde: This is the Arduino sketch. Copy and paste this code into your Arduino software and upload it to the board.
MultipleSerialServoControl.pde: [Updated 12/23/09] This is the NEW Arduino sketch, which uses the Arduino Servo library to make alterations much simpler. You can control up to 12 servos using this code (with modifications) and most Arduino boards, or up to 48 servos using an Arduino Mega! (See the code comments for specific details.) This code should also solve most of the servo “jitter” issues mentioned in the comments below. Copy and paste this code into your Arduino software and upload it to the board. (Requires Arduino 0017 or greater.)
servo.py: This is the Python module which talks directly to the above Arduino sketch. This script requires the pyserial module, available from Sourceforge. Save this script on your PC wherever you like, just be sure to name it “servo.py”.
New to Python? Welcome! Python is a versatile and fun language to learn, and it’s used by just about everyone, from newbies to NASA! Check out the Beginner’s Guide to get your bearings, or get the full skinny at python.org.
Customize the code:
Depending on your computer system and Arduino hardware setup, you may need to make a few modifications to the code.
Arduino: In the “MultipleSerialServoContro” sketch, take note of the following variables and make adjustments as necessary for your setup. See “Arduino Serial Servo Control” for more details regarding the minPulse and maxPulse variables. (If you’ve got standard RC servos attached to pins 2-5, you probably won’t have to change anything.)
// Common servo setup values
int minPulse = 600; // minimum servo position, us (microseconds)
int maxPulse = 2400; // maximum servo position, us
// Attach each Servo object to a digital pin
servo1.attach(2, minPulse, maxPulse);
servo2.attach(3, minPulse, maxPulse);
servo3.attach(4, minPulse, maxPulse);
servo4.attach(5, minPulse, maxPulse);
Python: In the “servo.py” script, you’ll most likely need to change the value of the usbport variable, which tells Python how to find your Arduino (On Windows, it’ll be something like ‘COM5′. On a Mac, ‘/dev/tty.usbserial-xxxxx’. On Linux, ‘/dev/ttyUSB0′.). Try running ls /dev/tty* from a Mac or Linux terminal for a list of available ports. [ToDo: Modify the script to make this step unnecessary.]
Test the code:
Once your hardware is set up and the software is installed, you can test the system’s basic functionality from the Python interactive interpreter or “shell,” like so:
~/path/to/servo.py$ python
>>> import servo
>>> servo.move(2,150)
The servo.move() method takes two arguments, both integers. The first is the servo number you wish to move, 1-4 (or whatever). The second is the commanded angular position of the servo horn, from 0-180 degrees. So, if you want to move Servo #3 fully clockwise (180 degrees), you’ll type servo.move(3,180). Cake, baby!
Optional Software: From Totally Geek to Totally Chic
The following scripts are designed to leverage the functionality of the servo.move() method for simple and readable code. Make sure these files reside in the same directory as “servo.py”.
- servodance.py: A cascading effect that feels like watching a quarter spiral down one of those funnel-shaped wishing wells.
- servorandom.py: The final servo sequence seen in the video, with individual servos moving to random positions and then waving “goodbye” in unison.
- servomarch.py: This one’s not in the video, but it’s a fun script to test individual and simultaneous movement of multiple servos. Just set the number of servos to march (default is 4), and send them off!
- multijoystick.py: Allows joystick control of four servos, with each joystick axis controlling a single servo. This script is the most complex, so try getting the first three working, then graduate to this one — it’s easier to troubleshoot problems that way.
[Note: This script also requires installation of the pygame module.]
With any luck, you should now have everything up and running just like in the video!
Adding Servos: When 4 Axes Just Isn’t Enough
[Updated 12/23/09] If you’re using the new Arduino sketch, you can easily add servos to your project by making a few simple additions to the code. The beauty of this system is that servo.py can remain unchanged, and all of the higher-level Python scripts just need simple alterations to include whatever number of servos you decide to add. This segment will outline how to change the Arduino sketch; changes to the Python scripts will be up to you!
There are three places in the MultipleSerialServoControl sketch where you’ll need to make additions, if you want to control more than four servos. Each section of the code contains the comment “TO ADD SERVOS:” followed by a suggestion on what to add.
First, add a Servo object for each additional servo:
// Create a Servo object for each servo Servo servo1; Servo servo2; Servo servo3; Servo servo4; // TO ADD SERVOS: // Servo servo5; // etc...
Second, assign a digital pin to each additional servo:
// Attach each Servo object to a digital pin servo1.attach(2, minPulse, maxPulse); servo2.attach(3, minPulse, maxPulse); servo3.attach(4, minPulse, maxPulse); servo4.attach(5, minPulse, maxPulse); // TO ADD SERVOS: // servo5.attach(YOUR_PIN, minPulse, maxPulse); // etc...
Third, create a new switch case for each additional servo:
// 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;
// TO ADD SERVOS:
// case 5:
// servo5.write(pos);
// break;
// etc...
}
After making changes, be sure to click the “Verify” button on your Arduino software to make sure there are no errors, then upload it to the board. Test your changes by calling the servo.move() method from the Python interpreter. That’s it!
NEW: Joystick Button Digital On/Off Demo
[Updated 02/18/2011] So, you’ve got your joystick merrily controlling your servos, but dammit, you want to be able to press a button and magically activate your [insert cool/evil feature here] … and you just can’t figure out how to get started. Well, today is your lucky day. Due to the high demand in the comments field for this feature, I’ve released updated versions of multijoystick.py (v.0.4) and MultipleSerialServoControl.pde (v.1.1).
This simple little demo will allow you to control Arduino’s built-in LED on Pin 13 with your joystick Button 1 (the trigger, hopefully, but your joystick may require code-tweaking). Depressing and holding the trigger should set Pin 13 to HIGH (LED on), and releasing the trigger should set the pin back to LOW (LED off). The multijoystick.py script now has built-in skeleton support for 6 joystick buttons — which simply means the code structure is there, and you’ll be able to see in the Python interpreter window which button PyGame thinks you are pressing.
The new joystick code also adds support for the “Hat” or POV Switch. The hat switch toggles L/R/UP/DN and then centers, and the code supports events for each position. The included demo will drive servo #4 full left with a “hat left” command, full right with a “hat right” command, and then center the servo when the hat springs back to center — one possible method to control the “pan” function of a pan/tilt platform, for example.
Here are a couple of snippets from the new multijoystick.py script:
# Assign actions for Button DOWN events
elif e.type == pygame.JOYBUTTONDOWN:
# Button 1 (trigger)
if (e.dict['button'] == 0):
print "Trigger Down"
# Set pin 13 LED to HIGH for digital on/off demo
servo.move(99, 180)
# Button 2
if (e.dict['button'] == 1):
print "Button 2 Down"
# Assign actions for Button UP events
elif e.type == pygame.JOYBUTTONUP:
# Button 1 (trigger)
if (e.dict['button'] == 0):
print "Trigger Up"
# Set pin 13 LED to LOW for digital on/off demo
servo.move(99, 0)
# Button 2
if (e.dict['button'] == 1):
print "Button 2 Up"
I know, I know, you’re saying, “What’s with this servo.move(99, 180) crap? I don’t even have 99 servos!” Well, since the Arduino sketch is already listening for a servo number and position, it’s a trivial matter to just “pretend” that our LED (or relay, or nerf turret, etc.) is just another servo. And since you’re unlikely to have more than fifty servos in your project, 99 seemed like a safe number to pick. The servo positions — in this case 180 and 0 — simply substitute for “on” and “off” respectively, but you could easily come up with your own communication scheme.
Here are some snippets from the new Arduino sketch that were added to accommodate the LED demo:
In the header, with the other variable assignments:
// LED on Pin 13 for digital on/off demo int ledPin = 13; int pinState = LOW;
In the void setup() block:
// LED on Pin 13 for digital on/off demo pinMode(ledPin, OUTPUT);
In the switch(servo) block:
// 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;
So basically, the Arduino code just receives the servo.move(99, x) from the serial buffer, looks in the switch block to see if there is, in fact, a Servo #99 (which is an LED in our case), and then executes the code in that block, which sets the output of Pin 13 to either HIGH or LOW. You could conceivably replicate this code for as many digital pins as you like, and a handful of 5V solid-state relays could switch on or off just about any electronic device imaginable. Have fun!
Part II: Getting Down to Brass Tacks
Next, let’s take a look under the hood to see how it all works. If you’re the type that just wants to get things working and damn the details, STOP HERE. Otherwise, continue on, and I’ll do my best to explain how the code “do what it do.”
The Problem Set
Asynchronous serial communication is not perfect. Sometimes there are errors, dropped packets, confusion. Sometimes the mail does not get through. In both of the previous two serial/servo projects, the Arduino expected only one byte from the PC, and in both cases that byte represented a commanded servo position — and nothing more. If a byte was missed or skipped, it wasn’t a big deal, another one was sure to come along, and it was impossible to misinterpret.
This project presents a couple of new challenges. First, we are controlling more than one servo, so the Arduino needs more than one command element for each move. As we’ve seen above, it needs to know (at least) which servo to move, and how much to move it. Secondly, we have the problem of communication. This time, we’re sending two command elements for each move (servo number & position), and these elements are clearly not interchangable. That is, if we want to send servo.move(4,90), we need to make sure that Arduino knows that the ’4′ means “Servo #4″ and the ’90′ means “90 degrees.”
Tom Igoe’s article, “Interpreting Serial Data,” contains an excellent discussion of some of the problems involved in serial communication, and lists several issues that need to be addressed in every project, namely:
- How many bytes am I sending? Am I receiving the same number?
- Did I get the bytes in the right order?
- Are my bytes part of a larger variable?
- Is my data getting garbled in transit?
The Arduino’s Serial.read() function reads one byte of data at a time from its serial buffer. Think of the serial buffer as a mailbox. It’s a small (128 bytes) area of memory where incoming serial messages are stashed until the Arduino is ready to read them. Every character we send from the PC to Arduino is one byte. So, while we could send the Arduino something very unambiguous like, “Yeah, hi, Arduino, it’s the Linux Box again. What’s happening? If you could go ahead and move Servo #4 to the 90-degree position, that would be great. Thaaanks,” (163 bytes) it’s obviously better if we can come up with something a little more terse.
However, as we’ve seen, if we just send over the characters ’4′, ’9′, and ’0′ — remember, each character is a byte — the Arduino might get confused. This problem is amplified when more commands start stacking up in the buffer. Let’s say now we command servo.move(2,180) and servo.move(3,120). Now the buffer should hold {4,9,0,2,1,8,0,3,1,2,0}, except–OOPS!–one of the bytes got dropped along the way, so now it holds {4,9,0,2,1,8,3,1,2,0}. “Wait, which servo did you want me to move?” You can clearly see a problem developing.
Solution: Data Packets and Start Bytes
Luckily, part of the solution is handled in the way Arduino communicates. Arduino uses ASCII encoding to represent alphanumeric characters. Each character sent over the wire is converted to the binary equivalent of a decimal value from 0 to 255. [See this conversion chart for specifics.]
So, for example, if we send over the character ‘A’, Arduino recognizes this as its decimal value, ’65′. We won’t get too deep into this concept except to say that the implementation is great for our application, because as long as the values we’re sending are less than 255, they’ll fit neatly into one byte. Since the largest value we send is 180, we only have to send two bytes per command.
Now, if you’ve looked at the ASCII conversion chart, you’ll recognize that doing this every time you want to send a command would be a real pain. Also, trying to teach Python this chart would take up a lot of unnecessary code. Thankfully, this problem is already solved for us with Python’s chr() function. Wrap any decimal value from 0-255 in chr(), and you get back its ASCII equivalent. A few examples:
~$ python
>>> chr(65)
'A'
>>> chr(110)
'n'
>>> chr(13)
'r'
>>> chr(9)
't'
You get the idea, but notice that ASCII doesn’t just represent letters and numbers, but also symbols and other “control” or “non-printing” characters like line-feeds, returns, and tabs.
So, now if we want to send servo.move(4,90), we only need two bytes, the ASCII equivalents of ’4′ and ’90′, represented in Python as chr(4) and chr(90), and interpreted by the Arduino sketch as, once again, simply ’4′ and ’90′. Easy! [Seriously, if your brain explodes at this point, or you're bleeding from the ears, it's understandable. I don't like it any more than you do, but stick with me, it'll all work out neatly in the end.]
Packets, Headers, and Payloads
Okay, great, now instead of just digits in Arduino’s serial buffer, we have meaningful values. Part of the problem is solved, but we still haven’t addressed the issue of dropped or missing bytes. That is, how will the Arduino know that a ’4′ is “Servo #4″ and not “4 degrees” when pulling values out of a crowded buffer like {4,90,2,180,3,0,1,110} ?
The answer is data packets. Very simply, instead of just sending a long string of numbers to Arduino, we’ll send a very specific ordered message, a packet of values, that is intended to be read and interpreted as a whole and in order, or else discarded completely.
Now, the structure of a packet can be as simple or as complex as we need it to be, as you might have noticed if you followed that last link. But all we really need is some means of ensuring that Arduino doesn’t confuse one value for another.
Essentially, our Python script needs to tell Arduino three things:
- Here comes a new servo command.
- Servo number to move.
- Commanded servo position.
We’ve already been sending the last two elements, the servo number and position. Here, we’re adding a third element, which we’ll call the header or the start byte. Our header, like the rest of the data in our packet, will be just one byte long, and contain no real information other than the conceptual message, “I am a header.”
The order of this message is important. Every packet sent over the wire, or read from the serial buffer, will now have the following format:
(Header, Servo Number, Servo Position)
or, more tersely:
(startbyte, servo, angle)
What to use as a startbyte? Well, we’re only using the values from 0-180 as either our Servo Number or Servo Postion. Any value from 181 to 255 would be unique. We’ll use ’255′ just to make it obvious. So, every packet will now look something like one of the following:
(255, 1, 90)
(255, 2, 180)
(255, 3, 0)
And the Arduino’s serial buffer would look something like:
{255,1,90,255,2,180,255,3,0}
Now, instead of reading byte after byte and hoping for the best, Arduino will wait until a minimum of three bytes arrive in the buffer, and then read the first byte to determine whether or not it is, in fact, a header (255). If it’s not, Arduino skips that value, and moves on to the next byte without touching the servos. When it finally sees a header, Arduino continues reading the next two bytes, in order, and assigning them to the Servo Number and the Servo Position, respectively. If either of those two values is ’255′, Arduino assumes something is wrong, and skips everything until it reads a new header.
Side Note: Authoritarian Flow Control
“Now just a minute!” you’re saying. “If that is the case, then some of the commands Python sends to the Arduino will be totally ignored!” And you’re right. This method of serial flow control is definitely one-way, with no error-checking. Other methods, such as “call-and-response” or “handshaking” are much better at ensuring accuracy, since there’s a back-and-forth arrangement that can call for data to be re-sent in the event of dropped packets. But the two-way protocol this method requires is much slower.
We have to make an engineering decision. In our application, which is more important, accuracy or quick response? It depends on exactly how you are using the servos, but if you consider say, a joystick-controlled robot or RC vehicle application, then clearly an immediate response and quick visual feedback is preferable to perfect accuracy. If you command “turn right” with a joystick, and your vehicle doesn’t respond appropriately, you’ll just instinctively add more right stick input.
Perfect accuracy is not required.
Writing the Code
Very briefly, let’s look at how the above concepts are implemented in both the Python and Arduino software.
Python Implementation
Whenever we call the servo.move() method, the Python script servo.py handles the serial communication details using the pyserial module, and formats the arguments into the data packet outlined above. The bare-bones version looks like this:
#!/usr/bin/env python
import serial
usbport = '/dev/ttyUSB0'
ser = serial.Serial(usbport, 9600, timeout=1)
def move(servo, angle):
if (0 <= angle <= 180):
ser.write(chr(255))
ser.write(chr(servo))
ser.write(chr(angle))
else:
pass
Arduino Implementation
Arduino opens its own serial connection, waits for at least three bytes to fill the buffer, then starts reading:
/** MultipleSerialServoControl.pde (bare bones) **/
void setup() {
// 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; }
If Arduino gets a complete packet with header, servo, and angle values, it assigns the new position to the appropriate servo. If the value of servo is not between 1 and 4 (or whatever maximum number of servos you specify), the loop exits without assigning any new values. That's it! The Arduino Servo library really makes servo control easy and painless.
// 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;
}
}
Whew! We're Done.
Well, if you've made it this far, congratulations: you're totally insane. I hope the above dissertation helps at least one person better grasp these concepts, since it took me across many web pages and into several late nights to find the answers. Good luck!
References
- Tom Igoe, Making Things Talk: Practical Methods for Connecting Physical Objects
- Tom Igoe, "Serial Communication"
- Tom Igoe, "Interpreting Serial Data"
- Society of Robots, "Actuators and Servos"
- ITP Physical Computing, "Servo Lab"
- ITP Physical Computing, "Serial Lab"

This is really excellent. Thank you!
p.s. any tips on how to extend servo wires? I’m finding that the wire is really thin and frays easily. Is there a name for that black terminal? Or does one need some sort of wire crimp?
Hey Allen, thanks for the props! The best solution I’ve found so far is the servo wire extensions you get at your local hobby store. They come in several different lengths, although it looks like there might be a practical limit of a few feet.
For longer wire runs or applications other than radio control, I’d probably chop the connectors off a couple of the short extensions and splice them to something beefier. There could be signal degradation and/or interference with the pulses over a longer run; you’ll probably have to experiment a bit with setup and voltages if you’re going beyond three feet or so.
Gidday , this looks great. I am into wanting to make a motion platform for a flight simulator.am looking at using 12 v motors as servo’s. will this system be able to be beefed up to run these , or will do the job as is. My ? may sound silly ,But Be patient with me as I’m new to this .
Hey John, you could certainly use Arduino and a PC to control your project, but the hardware setup would be substantially different, primarily due to your need to isolate the 12V devices from the Arduino’s 5V circuit. You code would probably need to be different as well, although the modular theory presented here could still apply. Try posting your question over on ladyada’s forum. You’re sure to get a wealth of helpful responses over there.
I’ve had to do a similar program that I will be posting about soon on my project blog. When you need to make sure information goes through but don’t want to try and synchronize the serial port connection, send data both ways through arrays. Certain spots in the arrays are reserved for data for a certain spot. If you continually resend the array, then it will catch dropped bits if you reserve the first and last spots for a certain value. If the array does not begin or end with the right values, it ignores those values. If it does, it just takes the values of the arrays and applies them to your outputs. This works for inputs as well.
Hi, I’m doing similar stuff, but I’m controlling ShiftBrites instead. Here’s my serial port setup code, which tries multiple port devices until it finds one that works:
getserial.py
Hi. Great tutorial! It worked right from the start, and left me happiliy tinkering with the code, without hassle. I used some servos i had lying around, old ones and thus still analog. Now i’d like to use some stronger and faster ones, and i had my eyes on digital servos. from the vantage of control this should not make a difference, the whole ‘digital’ thing about digital servos is kinda overstated anyway, but those servos will be using a lot more juice (2 amp peak 7 per servo) – do i’d like to hook them to a separate current source, not simply give a wall wart to my diecimila, but running the power/ground cables of the servo directly off a wall wart – after all this preambling: I don’t have much clue of electronics -> Is it possible to have the power run directly to the servos and have a branch of that supply run to the diecimila so the brunt of the current will be caught by the wall wart, but the control is still on the same level?
loonquawl: I’m glad everything worked for you out of the box; thanks for the feedback! There are undoubtedly several different options for keeping the power separate. I’d probably just power the Arduino from USB, then use the wall wart to power the servos. I’m not sure about power requirements for digital servos, since I’ve never used them, but you can get a nice little 5V/3.3V Breadboard Power Supply kit from SparkFun that will run off the same 9V wall wart that works on the Diecimila. You might also want to take a look at Adafruit Industries’ Arduino Motor Shield kit as well. At the very least, you’ll get some ideas for circuits!
Hi John, as Brian says you will fry the Arduino if you even try to run a modest DC motor from it directly. As an experiment I tried to isolate some commercial hobby servos from my Arduino by using a Darlington Array IC (ULN2003). It did not work, for me at least. The array seems to monkey with the signal in a way that my non-electronics brain does not fathom. (I expect I will be enlightened)
Can I suggest it might be better to run stepper motors, rather than servos for your flight simulator? There are many circuits that you could google to drive even power hungry stepper motors. I’m guessing your motors are to move scenery, or perhaps even the ‘pilot’ so they would have to be reasonably powerful.
Good luck on your project and please share your experiences with the community.
Pop
Hi,John,your tutorial provide a gread help for me,but I can not finish “multijoystick”.when I key in “import servo”and “import pygame”,and move my “joystick”,my servo motors don’t move like your video,could you tell me what’s wrong ?
And could you teach me the other way to control a number of motors in the same time just like your video?
Hi, this is gold. I am in the processes of building a robotic arm controlled by arduino, but as i am new to programing, i am wondering if there are graphical interface add-ons for controlling 6+ servos. (especially ones already written for robotic arms) Thanks in advance
Freeman
@Freeman: Thanks for stopping by. I haven’t seen a GUI for controlling servos out in the wild, but that doesn’t mean there isn’t one. One of the goals I had in mind when creating
servo.pywas to allow enough flexibility to add a WxPython or TKinter GUI on top of it. Python is perfect for that kind of thing. Let me know what you come up with!hi again, i have purchase my hardware for the robotic arm and am currently trying to run this code, but i can not seem to import the servo.py… in the command line interface it says no module was found. can you point me in the right direction? im running python 2.6
thanks again
@Freeman: In order for
import servoto work, the fileservo.pymust be in the same directory as the program calling it. So, if you’re calling it from the interactive interpreter, you must run thepythoncommand (to launch the interpreter) from the same directory in whichservo.pylives. If you’re having trouble with theimport serialcommand, it just means you need to install the pyserial module (see text above for details). Hope that helps.thank you, that was the problem, and that i had 2.6 instead of 2.5.2 running
thanks again, this is a great start for me
I just want to say thank you again. I have edited your multijoystick code to run five servos with a game pad and it’s working without a hitch. I could not believe that I can get so much done on my first day with the arduino.
Thanks again
Freeman
Very nice indeed!!!
This article has inspired me to try the same thing with my next bot. An arduino controlled rig from a remote laptop(linux of course) via bluetooth. I figure that bluetooth is the best option to send packets.
Basically a rover similar to the SRV-1 by surveyor but home-brew.
Wish list: -Full joystick control of a skid-steer tank-type chassis.(constant rotation servo control required) -Joystick hat button to control the pan and tilt of camera (most likely a cheapie until I feel the need for machine vision capabilities) -Additional joystick buttons for whatever I deem geek enough. Search lights. Blue led strobes, flares(JK) -All run through a python to arduino interface.
-The icing on the cake would be an WxPython gui for graphical representation of current pin states. Eg search lights on. Yes I could see the lights are on but this is for geek cred ;) -While I’m day-dreaming it would be nice to get sensor feedback displayed in a gui or as an overlay on the video feed ala HUD. Items such remaining battery power represented in a graphical or numerical format, compass readings, etc.
So… any progress on the integration of a WxPython gui with the arduino? :)
@Chad: I love it! Your surveyor bot sounds like one of my over-the-top harebrained schemes! ;) Instead of Bluetooth, you should check out XBee/ZigBee modules. The range is better than Bluetooth, and they interface easily with Arduino. (Oh, and they’re relatively cheap too.) You can get the modules from Sparkfun, Adafruit and others, along with XBee shields for Arduino. Have fun and keep me posted!
Could this be used with analog / digital inputs such as GPS/Compass and micro switches?
@Mitchell: Absolutely! Check out Ladyada’s GPS datalogger shield for Arduino and her great Arduino tutorials for more info.
A lot of your source code can’t be found. servo.py and multijoystick.py in particular.
@Silas: Sorry about that and thanks a bunch for the feedback! I recently switched the site over to a different server and apparently I didn’t have all the bugs worked out. You should be able to grab the code now. Let me know if you still have problems.
thanks!! this is great. I used the arduino code, but instead of python i used visual basic 2005 to make a form control. After i got vb to send ascii characters it worked great!!!
First of all allow me to congratulate you on this excellent work of yours. It’s an excellent tutorial on how to handle servos with Arduino. I have only one question. Can you please explain how can we send ascii equivalents to Arduino, ranging from 0 to 255, when the ascii table of Arduino only goes from 0 to 127?
@Miguel: Thanks for your comments. The short answer to your question is, “No, I can’t explain it very well.”
The long answer is that although ASCII is a 128-character code, it is a deprecated subset of Unicode, which supports 256 characters. Since the Python
chr()function supports 256 characters, and since Arduino’s serial library accepts these values, it works for our purposes.I specifically didn’t get into the actual ASCII value conversions in this tutorial, since only the decimal equivalents were important to this application. My brain is exploding just thinking about it right now, so that’s as deep as I’ll get. Check out the Wikipedia page on ASCII if you really want the gory details.
I don’t necessarily like the way serial communication works, but I tried to explain how to make it work for the purposes of this application. Tom Igoe’s article does a much better job of explaining it than I do.
Excellent article to get started with servos. I really appreciated the post. I’ve been able to follow the tutorial, but when i move one servo the other one kind of shake a little. I’m using Tower Hobbies TS-53 standard servos, and arduino diecimilanove. Any thoughts why this could happen??
Thanks in advanced!
@Daniel: Thanks for stopping by! I’ve encountered this phenomenon as well, and it can be difficult to troubleshoot.
Basically what’s happening (I think) is that the servo is “confused” by pulses it is either receiving or NOT receiving from the Arduino. The servos expect a pulse every 20ms or so, or they will start to “drift.” You might want to experiment with the
refreshTimevariable to see if this changes anything.You might also try tweaking the
minPulseandmaxPulsevariables. Start with just one servo and send it commands for full left and full right (0 and 180 degrees). The servo should not “buzz” at either of these settings. If it does, you probably need to shorten the pulse width.Sometimes operating multiple servos with rapid command inputs will cause uncommanded servos to buzz. I’m not sure if this is because Arduino is getting mixed signals or what. You’ll notice in the
servorandom.pyscript that I’ve included the variablet = 0.23 #sleep time. As I recall, this was to space out the servo commands so they didn’t all pile up in the buffer. I think if you shorten that time, you’ll start to see servo buzz. Remember, your PC can send data a lot faster than a servo can move. You have to give it some time to do its thing.Finally, if you’re using a joystick or something similar as an input device, it’s hard to avoid some uncommanded “jitter.” The joystick is constantly sending position data to the Arduino — even when its centered — and I think this tends to overload the buffer. If you look closely at the video above, you’ll notice that servo #1 (far left) tends to vibrate even when its axis is not being commanded by the joystick. I have not found a solution to that particular problem — in fact, from a vehicle-control standpoint, I think I basically wrote it off as a non-issue.
Give those suggestions a try and report back if you get time. I’d like to hear how things turn out!
Brian, Thank you very much for your reply, I will try adjusting those things, and try them with the servos in my plane to see if that’s really an issue or not. Thanks a lot!
Hi Brian. Thanks for the excellent tutorial. In the comment (#27) you make above about joysticks and the jitter issue. This is often combated using a deadzone, where anything below 1% or 2% of the sticks motion is clamped to Zero.
In the tutorial you suggest that this method works well if you want to send 8bit data, (i.e. 0-255). Can you describe how you would go about sending more? perhaps a 10bit number or even a float (for GPS NEMA data for instance?)
Over the next few days i’m going to try and recreate your servo.py lib in processing. I’ll let you know how i get on and send you a link when it’s done.
cheers Jim
Hey Jim, thanks for the tip. I’ll try it out. I haven’t messed around with GPS at all, but it’s next on my list, either with Arduino or with something like a TinyTrak and the APRS network.
Limor Fried (ladyada) has built a cool-looking GPS shield for Arduino that you might want to check out. I think it’s mostly just a datalogger, and from a quick glance at your website, it looks like you might want to do vehicle control. There’s a bunch of code for parsing NMEA sentences that’s blowing my mind just to look at right now. She’s also got a great forum over there. Limor’s actually an MIT EE grad, so if anyone can answer your question, she can.
Yes, respect due to Limor, she’s a great source of knowledge as as well as cool toys :)
Hi Brian, thanks again for all. My next question is if you had tried this wireless with xbee. I’ve been trying to do that, but not with the result i’ve expected. If send moves more than 1 every 3 or 4 seconds it does get the message well. I’m using Xbee ZB 2mW ZigBee Pro RF modules at 9600. (I’ve also tried with 4800 and faster). (I’m actually getting two XBee Pro 50mW Series 2.5 RPSMA in the mail soon). Well thanks in advanced.
Sorry Daniel, I haven’t used the Xbee radios yet. I’m afraid I can’t help with that one.
thanks anyway man, I’ll keep trying.
This stuff looks great, however it is “asking” for something called “pygame” which as far as I can tell is not a “default” package… dependencies! Please check your dependencies when you project stuff out to the “learning” public. So far, all I have been able to do with this pygame requirement is get fully lost in the Python install nightmare… version this, requirement that… All I wanted was to try your cool application on my BoArduino! NOT re-learn the entire Python development system! By the way, the Sketch loads just fine, the pyserialstuff seems to work, but the multijoystick.py thing stopped me cold.
Thanks for the nice application. However, I’m not even able to run the python script. Can someone help me troubleshooting this. I’m far from an expert. here is what I get when I start servo.py in command lines:
@Phil: The
multijoystick.pyscript depends on three additional modules:servo.py,pyserial, andpygame, each of which are mentioned in the header comments of that script. You’ll have to install all three before that script will work. Specifics about joystick control were beyond the scope of this article, as I mentioned in the introduction.For more information about controlling servos with a joystick, see the article entitled “Joystick Control of a Servo.” For detailed instructions on installing Pygame on your system, consult the Pygame documentation.
@Hugo: Thanks for including your error messages. From the looks of things, you’re running Python 3.0, and it doesn’t seem to like the code syntax I’ve used in the
servo.pyscript. I wrote that script using Python 2.5.x, and Python 3.0 is not backwards compatible with earlier versions. I haven’t played around with 3.0 at all, so I’m not sure of all the differences, but it looks like my syntax needs to be altered a bit to use parentheses, as in this example from the Python 3.0 docs.So, instead of:
Try
I’m not sure if that will work, since I’m still running 2.5.x, but it’s worth a shot! Let me know what happens. :)
This project looks great, but I can’t get the Python code to work. When I try to ‘import servo’ it returns an ImportError: DLL load failed for importing win32file. What is this? I’m running 2.6.1 and have downloaded pyserial.
@Joel: Thanks for stopping by. I’m afraid I don’t run Python on Windows very often; I’m mostly a Linux guy. But I seem to recall needing the pywin32 module to run these scripts on Windows. Try installing that and see if it helps. Also, you need to launch the Python interpreter from the same directory in which
servo.pyresides, otherwise Python won’t be able to find it.I installed pygame and pyserial but when i import them it has importerror:dll load issues. Is it just because I have a newer version of python than the modules support?
I get this when I try to run the code, everything is installed and I got rid of a bunch of other errors earlier but I still get this one.
Traceback (most recent call last): File "C:\Python25\Lib\idlelib\servo.py", line 20, in ser = serial.Serial(usbport, 9600, timeout=1) File "C:\Python25\Lib\site-packages\serial\serialutil.py", line 171, in init self.open() File "C:\Python25\Lib\site-packages\serial\serialwin32.py", line 53, in open raise SerialException("could not open port %s: %s" % (self.portstr, msg)) SerialException: could not open port COM5: (5, 'CreateFile', 'Access is denied.')Any ideas?
I figured out the error. In the servo.py implementation it says ser = serial.Serial(usbport, 9600, timeout=1)
it should be
ser = serial.Serial(usbport, 9600)
I also experienced some jitter issues and am now using the interrupt based library servo routines. It’d be interesting to re-work this code to use those, though I’m not sure about controlling more than two servos.
More here:
http://forums.ladyada.net/viewtopic.php?f=25&t=8637&p=51884#p51884
HI there,
i am trying to figure some of this out myself for a uni project. i study architecture not electronics but cant afford to pay someone.
how would i need to modify it to control 12 or is it pssible to control 18 servos?
would appreciaite any help!!! cheers
ango
hi
grt tutorial! so far i have got everything working, i can control what ever servo i want via typing in the command to pythons line command, also my joystick work with my computer no problem, i have the same one as you have used in your tutorial, but when i type in import multi joystick it don’t do anything at all when i move my joystick!
help please!
@matt: I think the problem is that you don’t want to import
multijoystick.pyfrom the Python interpreter, but rather run it as a Python program. Multijoystick.py will then import theservoand thepygamemodules on its own (you’ll need to install pygame if you haven’t).Next, make sure that
from within that directory (using the regular command line, NOT the Python interpreter), and you should be up and running.servo.pyis in the same directory asmultijoystick.py, and simply run the commandYou might also try running
servodance.pyorservorandom.pyfirst, since those require nothing more thanservo.pyand thepyserialmodule to work. Get those running and then graduate to the joystick program — it’s easier to iron out the bugs that way.Hey everybody! As of today, I’ve replaced the
MultipleServossketch with one calledMultipleSerialServoControl. This new sketch uses the fantastic Arduino Servo library to do everything the old one did, just with waaaay less code, which makes alterations easy.Also, the Servo library allows you to connect nearly as many servos as your board has pins, and I’ve made the sketch easy to alter so you can add servos to your heart’s content.
Read the documentation for the Servo library and the code comments in
MultipleSerialServoControlfor instructions on adding more servos. Have fun!hi again got the servos working with the computer (both dance and random work) but the command you said
‘python multijoystick.py’
come up with the error message
‘file “”, line 1 python multijoystick.py ^ SynstaxError: invalid syntax
i installed the pygame so it was in the python folder
much greatful for your time
@matt: It looks to me like you’re still trying to type
python multijoystick.pyin the Python interactive interpreter. If your command prompt looks like this:then you’re still in the Python environment. Hit CTRL-D or type
quit()to exit Python and get back to your system’s regular terminal command prompt, and then try typing the command. If you’re using Windows, you need to be using the Terminal application, and thencdinto the directory which containsservo.pyand the rest.sorry bit of a amature here, what do you mean by terminal application and ‘cd’ and yes i am using good old usless windows
once again thanks for your time
muct appricated
@matt: Try clicking Start->Run and then typing
cmdin the box to start the DOS Terminal.@matt The DOS command
cdis the “change directory” command in DOS. Try Googling “MS-DOS tutorial” or check out this site for more info on getting around in the Terminal.@matt: The Windows DOS prompt should look something like this:
and you can run the
pythoncommand right from there to start the Python interpreter, rather than opening it from the Start menu. But, to get all this code to work correctly, you first shouldcdinto the directory which containsservo.py, etc. The command will be something like:@matt: Once you’ve changed into the directory containing
servo.pyandmultijoystick.py, then you can runright from the DOS prompt. You should see a message like:
Then you’ll know it’s working.
@matt: Not to complicate your life too much, but you should also grab the shiny new MultipleSerialServoControl.pde sketch, which replaces the old
MultipleServos.pde. It will be much easier to understand and work a whole lot better than the old one. I’ve changed the text above to reflect the differences in the new code.@matt: You know, while I’m thinking about it, you MIGHT even be able to just double-click on the
multijoystick.pyicon, wherever it lives on your system, and Python should just automatically run it. No guarantees, but it can’t hurt to give it a shot!thank you so much! you made my christmas come early!
also to let you know, what you said in comment 57 works
cheers
merry christmas to your and a happy new year!
@matt: Niiiiiiice. No worries; my pleasure. It was fun dredging out the old toys again!
Hi; Have you the code to control a stepper with python, thankyou
@ouazar.yahia: Try checking out the Adafruit Arduino Motor Shield. It’s got some code for running steppers.
hi can you help me, i want to set a maximum the servos can move say 37degrees either side of 90 for x and y axis how will i do this with out building somthing to stop the joystick moving to far!
thank you
@hart: Try reading the code to figure out what it does. The solution to your problem is trivial.
For each axis, find the following code snippet:
and change the last line to:
That’s it. If you uncomment the line
#output(str, e.dict['joy']), Python will output the position of the joystick axes as you move it. You’ll notice that each axis outputs a range of values from -1.0 to 1.0, with 0.0 the centered position. The above code simply converts this scale into values from -90 to +90.thanks for your help, and with what u said about the +/-1 i worked out myself how to change the direction of the servos spins in relation to the joystick, and not that you want to do it but so all directs on the joysticks can move only one servos one direction!
loving playing wit the programming!
Hi
I’m not user of this project. jet. I plan to be and I am willing to create gui for this scripts. If someone is doing it right now I can help. I plan to use gtk libs with glade.
I will try to have simple gui till end of this week. Any gui features anyone has in mind and would like them implemented please tell them so we can bring this project to its gui heavensnesnes :)
I’m not great python dev but I would like to help in anyway posible.
If anyone would like to help please mail me at christooss AT gmail.com
I did it :) Its quite simple. More features to come. There are three files in package: servo.py servo_gui.py servo.glade
http://dl.dropbox.com/u/45675/servo.tar.gz
Run python servo_gui.py for GUI version. I don’t have arduino but it should work as normal version since there are only chr() functions in servo.py
Hopefully it will work for you arduino folks.
Comment if I failed!!!
@christooss: W-O-W!! This is great stuff! Thanks a bunch for creating this little GUI. It’ll be the perfect starting point for myself and others, I’m sure. I haven’t played much with Glade or wxPython, so this will be a nice challenge.
I had to make one simple change to get your code to work with
servo.py, and that was simply to rename your “servo” variable to something else (“serv” in this case), since the old name was conflicting with the “servo” method. Other than that, it worked out of the box! Here are the changes:Ok I will fix this in my source. I have some ideas about gui so I will try to implement them even further. Implement random button etc. (implement brian’s scripts :))
I will base from this project a robot that will pick up elements from table but I have to do some math for controling 4 servos with right angles.
As I said the problem is that I don’t have audrino and I don’t load servo.py in my servo_gui file. No bugs for me since all I test is print serv and print angle :) . Hope that will not cause to much trouble when I will post other versions.
Hope to see you soon with more leet features in python 4-axis servo control :)
does anyone have any ideas how to implement the buttons of the joystick in python and arduino
@overclock999: Check out the multijoystick.py script. Find this code block starting at line 91:
elif e.type == pygame.JOYBUTTONDOWN: str = "Button: %d" % (e.dict['button']) # uncomment to debug #output(str, e.dict['joy']) # Button 0 (trigger) to quit if (e.dict['button'] == 0): print "Bye!\n" quit()Depressing the trigger (Button 0) is designed to quit the application, but you can re-code it to do whatever you want. The buttons on a joystick are all numbered, starting with zero.
You can experiment with your joystick to figure out which number corresponds to which button by simply uncommenting the line
#output(str, e.dict['joy']), and the script will print out the number of each button as you press them.The terminal output should look something like this:
hey hi…I am facing lot of problem in running the code…please help me out. My agenda is to control three servos using the joystick. I have given the connections to the servo.I downloaded the multiple serial servo control and loaded in the arduino. Now in the terminal when i run the multiplejoystick.py, it detects the joystick but when I am moving the joystick it shows me the following error:
@sanjay: Do you have
servo.pyinstalled in the same directory asmultijoystick.py?@brain Thanks a lot man
This looks great! Tho i have problems with my PC:
Traceback (most recent call last): File “C:\Python26\servo.py”, line 20, in ser = serial.Serial(usbport, 9600, timeout=1) File “C:\Python26\lib\site-packages\serial\serialwin32.py”, line 30, in init SerialBase.init(self, *args, **kwargs) File “C:\Python26\lib\site-packages\serial\serialutil.py”, line 201, in init self.open() File “C:\Python26\lib\site-packages\serial\serialwin32.py”, line 56, in open raise SerialException(“could not open port %s: %s” % (self.portstr, ctypes.WinError())) SerialException: could not open port COM3: [Error 5] Access is denied.As far as i can tell the error means that COM3 port is in use by other program, but the thing is, its not. I don’t know whats going on…
The whole thing works just fine with my mac on the other hand. Any ideas?
@Dude: To me it looks like a permission error. When you installed Python (and/or
serialwin32.py), did you do it as the Administrator?@Brian: I’m using XP so yes, ran as admin. I don’t really think, XP has any permission tools going on when it comes to that.
I’m really lost here. It works just fine on my macbook. Weird, really.
Brian! you are genius! ;-) I just want to remind for beginners who is using Windows XP: I had problems before because of using Python 2.6. If something does not work like pygame is not running – remember in Windows XP: you install Python 2.5. (not older)! then you install pyserial-2.5-rc2.win32, pygame-1.9.1.win32-py2.5, and run in parralel arduino 0018. After this joystick is detected automatically and you can play!
Hi! How to modify program to change servo speed? I have a problem that in zero joystick position servo still rotates till the end in one direction. What it can be? it is not like stop rotating but continue.
@Lucky: Thanks for your comments. I’m not sure what is going on with your setup, but if I were you, I would uncomment all the lines from
multijoystick.pywhich read:This will print out your joystick positions in Windows Command Prompt (terminal), so you can see what it’s sending to the Arduino.
Also, you might try experimenting with the
minPulseandmaxPulsevariables in theMultipleSerialServoControlsketch:Good luck!
Hey Brian, I’m new to the arduino world but this 4 servo project will be a great start for me. One question. What if I wanted to use an ethernet shield rather than doing this over serial. Any thoughts as to where I might look for ideas?
Cheers
John
@John: Thanks for stopping by. Ethernet/ZigBee/WiFi would be awesome ways to take this project to the next level. I think it would be really cool to use this as a basis for a LAN robot or RC vehicle of some kind.
I haven’t played around with that stuff at all, but you’d have to change all the communication stuff from serial to HTTP. I’d start by checking out the Arduino Ethernet library.You’ll also have to change
servo.pysignificantly in order to talk to Arduino.I’d probably head over to the Adafruit forums and see what others are saying. They’ll have more expertise over there!
Hi, I’m trying to implement this into a quad rotor helicopter using brushless motors. Could you explain to me what I would need to modify in order to make the brushless motors spin according to the movement of the joystick?
I would like to be able to control which motor spins in relation to the joystick’s position. for example, if i move the joystick to the right, i would like the left motor on the helicopter to increase its speed.
The motors only need a pwm signal from arduino (between 0 and 255) and the speed controller attached to the motor handles the rest.
@undoo: Try asking your question over at DIY Drones. They’ll be able to point you in the right direction. (Be sure to check out the FAQ and the “Top Five n00b Questions and Answers.”)
Hey Brian, I love your work. This might be covered in the previous comments, but to be honest it’s 2:00 AM and I just want to go to bed instead of pouring over all the comments :/… Anyway, I was wondering if you found a way to use this same system but wireless like you were going to do in the “Joystick Control of a Servo” article? I was wondering if you were to just use a USB Bluetooth device and plug it into the Arduino controller and connect via computer if that would give you a successful wireless connection… Thanks.
@Jerald: Haven’t tried wireless yet, but your idea might work. Let us know!
Question: Is there a way to make the servos move to a predefined position on boot-up of arduino instead of going to 90 degrees as it is now with the MultipleSerialServoControl.pde? Because it moves to unwanted position before I start the program on the PC and it would be great to eliminate that.
I have visited and poured over your articles many times regarding servo control via joystick and I haven’t read all the comments but I did make a WiFi module for micro controllers. you can find out more here http://leetgeekgear.blogspot.com/ but essentially it shows up as a serial port via an FTDI cable and transmits/receives via serial uart. I am trying to implement your code by using the WiFi modules but instead of servos (don’t have any) I am going to use leds. I will report back as soon as I can. Thanks for sharing such a wonderful project…
Without sounding too stupid; I cannot make heads or tails of the python part. I have no idea what to do with the script, where to insert the control into python, nothing. I’ve even tried the python web page and cannot make the simplest script work (except hello world). I’m a hardware person and would really like to try this controller; but without some help in the input of the software; I’m dead in the water. Thanks, Bill Hackett
Second comment: I tried to install 3.1.2 on my mac (snow leopard). It goes through the motions but when I type “python” into the terminal window it stays at version 2.6.1. Maybe I should stick to flower arranging in Antarctica. Bill Hackett
Hello, great tutorial. I am currently working on a project in which i need to control a steering servo and ESC via an arduino duemilanove and ethernet shield. I would like to control the ESC and Servo with a joystick connected to my computer. this then transmits data from a WRT54GL to a bridged WRT54GL on the rover to control the servo and ESC.
I am having a little trouble with making this work, do you know anywhere i could find more information on sending these commands through the ethernet shield?? Any help would be greatly appreciated, this is my major work for Design and Technology.
Thankyou, Chris
I’m trying to work through the 4 axis python-arduino setup. I’ve read the instruction but don’t know exactly what to do with py-serial. I’m on an Intel Mac with snow leopard. I’ve gone through the installation instruction posted by Brian; but am getting nowhere. Any help, Bill Hackett
@William Hackett: Sorry, I haven’t been checking in on this blog as regularly as I should. Are you having problems installing
pyserial? If that’s the case, just download thepyserial-2.5-rc2.tar.gzfile (or whatever the current version is) from the Sourceforge project page, then extract the file using the following command:This should leave you with a directory entitled
pyserial-2.5-rc2. Simply navigate into that directory and run the following command:This will install the
pyserialmodule on your Mac, and you should be able to follow along with the rest of the tutorial from there. Let me know if you need any more help!G’day Brian, just wanted to say many thx for this detailed and beginner-friendly info. My first Arduino project will be a joystick-controlled laser pointer, so this is exactly what I needed to get started. Just got to find where I put the Saitek joystick… Cheers, Geoff.
Thanks for posting this code. gave me a head start on my arduino project. It makes a lot of sense to use high level python code on the computer to do the heavy lifting and simplify the microcontroller code to simply sending/receiving commands from the computer.
Thx
Hey people, I see this code pyton and its good for my project. But I want this code in VB.net. Can some one help me please? I have problem in the code #Arduino joystick-servo hack. I dont know how take the joystick position to arduino to move the servo. Thanks!
@Chris Wright: I’m trying to do the exact same thing with not much luck. Bluetooth just does not have the range I’m looking for. I’ve seen similar methods used by wifibot and superdroid using different micro controllers, unfortunately there all closed source. I’m not sure if I need to send the serial data over telnet with the Ethernet shield or is there another way. Anyone have any suggestions?
The link to serial interpreting data is broke – here’s the working version http://www.tigoe.net/pcomp/code/communication/interpreting-serial-data-bytes
@Serial: Fixed. Thanks!
very impresive work indeed. I’m currently playing with a 5DOF arm running with your code and wired as specified. I’m wandering about the resolution of the movement. It seems impossible the get a < 1 degree resolution. Is it possible for you to elaborate a bit in this direction?
thank you, will
@willy: Thanks! The 1-degree max resolution is a result of using the Arduino Servo library’s
write()function, which accepts integers from 0-180 as position commands. If you want finer resolution, you’ll need to use thewriteMicroseconds()function, and specify the desired pulsewidth in μs.Read Arduino Pulse Width Modulation and Arduino Serial Servo Control if you’re confused by what I mean. Play with the code in these articles, but definitely use the Arduino Servo Library for your 5DOF robot arm, since it’s optimized for the task.
i am working on a robotics project,in that i have to interface 10 servo motor..How can i do by arduino..i think there is only 4 dedicated pwm channel ,so how can we interface 10 servo??please reply
@Lentin: The Arduino sketch presented here will control as many as 12 servos (or 48 with Arduino Mega). This article contains detailed instructions for expanding beyond 4 servos, and the code is well-documented. Please read.
Thnks Brian ,i tested the code..work fine..but a small issue is there..sometime servo has some jittering.. i googled this issue..i found servo::refresh,eventhough ,the issue is there.also i got megaservo library….Is this issue is fixed or not??i am not using the orginal arduino board..i just wrting the arduino hex code into an atmega8 running at 1mhz..its working fine..i hve to limit the jittering ..pls replay
@Brian..My issue fixed..i connected a 8mhz crystal ..now its ok..no jittering..thanks for u r support..
very well written, thanks for the low overhead serial protocol tips
There are other options to create data packets that are able to deal with data loss without a start byte or are able to recognize (many, not all) forms of byte loss within a packet. I’ll start with a simple 2-byte protocol which is self-synchronizing (even self-labeling), i.e. the receiver will always know whether the byte it just received is a servo number or an angle:
Angles are encoded as values in the range 0…180. This also implies that any value outside 0…180, namely 181…255, cannot be an angle.
For transmitting the servo number, we thus use some of the values from the (so far) unused set, 181…255. One could use 181 to indicate servo 1, 182 for servo #2, and so on until 228 for #48. This would still leave 27 values (229…255) to be used for future extensions of our protocol.
So the host code would do the following as part of servo.move(serv, angle) after some basic input parameter validation:
1. Send chr(serv+180)
2. Send chr(angle)
The Arduino would do the following:
1. Wait for a byte to arrive.
2. If that byte is within [181…228], set serv=byte-180 and read another byte. If this byte is in [0…180], set angle=byte and move servo #serv to angle.
3. Repeat this forever
Voilà!
Hi Mr Brian,
From the picture, it is not clear how the servos are connected to the power supply. Are the 4 servos running only from the usb power? hopefully not. Can you specify the wiring for the connection to the power supply.
thank you so much tony
@Tony: Yep, in the setup pictured, the servos and Arduino are all running off the USB power supply, but I wouldn’t recommend it. I’d plug the wall wart into Arduino and run it that way, or, if you wanted to get creative, set up a separate 5V regulated power supply right on the breadboard. SparkFun sells some nice power supply kits for just such a purpose.
Thank you Brian for your quick response. Actually I have a 5V (5 A) regulated power supply (Toshiba – laptop) that I can use. Can you post informations about it’s wiring to your setup. Also, I’d like to keep my usb communication active. Is there a jumper issue? Again,thank you for your time, Tony
@Tony: I guess I’m not really understanding your question. A standard hobby servo has three wires. Two of them need to connect to +5V and GND, and the other one goes to a digital pin on the Arduino. How you set up your own breadboard is, of course, totally up to you. Check out this post for more help.
As for the jumper, the Arduino can be powered by USB or external power. Some of the older models have a jumper; the newer ones switch automatically. Check out the hardware reference on the Arduino website to find out which is which. Good luck!
I’m using this tutorial with winxp and Python25. I have some problems with working. When I turn the joy servo is moving but the program is begin to crash and return’s message:
Traceback (most recent call last): File "C:\Documents and Settings\Administrator\Pulpit\multijoystick.py", line 134, in main() File "C:\Documents and Settings\Administrator\Pulpit\multijoystick.py", line 130, in main joystickControl() File "C:\Documents and Settings\Administrator\Pulpit\multijoystick.py", line 111, in joystickControl handleJoyEvent(e) File "C:\Documents and Settings\Administrator\Pulpit\multijoystick.py", line 62, in handleJoyEvent servo.move(1, serv) File "C:\Documents and Settings\Administrator\Pulpit\servo.py", line 38, in move ser.write(chr(255)) File "C:\Python25\Lib\site-packages\serial\serialwin32.py", line 260, in write raise writeTimeoutError SerialTimeoutException: Write timeout@Flay: Open the file
servo.pyin your favorite text editor, and find this line:ser = serial.Serial(usbport, 9600, timeout=1)and change it to:
ser = serial.Serial(usbport, 9600, timeout=0)Let me know if that works.
Unforunately it doesn’t work. Error is the same.
@ Flay: Try simplifying things first, to narrow down where the problem is. Have you tried just running
servo.pyby itself? Open the Command Prompt, navigate to the folder whereservo.pyresides, and try the following:If that throws the same error, you know there’s an issue with
servo.py. You could try removing the timeout altogether, like so:ser = serial.Serial(usbport, 9600)hmm it seems to be workinng with ser = serial.Serial(usbport, 9600) but the servo move to 180 angle and returns to main position, then error: Traceback (most recent call last): File “C:\Documents and Settings\Administrator\Pulpit\servo.py”, line 22, in ser = serial.Serial(usbport, 9600) File “C:\Python25\Lib\site-packages\serial\serialwin32.py”, line 30, in init SerialBase.init(self, *args, **kwargs) File “C:\Python25\lib\site-packages\serial\serialutil.py”, line 201, in init self.open() File “C:\Python25\Lib\site-packages\serial\serialwin32.py”, line 56, in open raise SerialException(“could not open port %s: %s” % (self.portstr, ctypes.WinError())) SerialException: could not open port COM5: [Error 13] Access denied.
@Flay: Is your Arduino really connected to COM5? Is that the port you have selected in your Arduino software? Is the Arduino software still running?
Yes, Ardunio is connected to COM5, Yes, that port is selected in my Ardunio software, and when i’m testing python software the ardunio software is not running.
The tutorial was an awesome start for my project. Was wondering if anything more was developed with the xbee wireless. I am trying to control a RC car with an arduino uno via touch screen and would like to use 2 series 2 xbees for my wireless link.
Brian, I have used your servo.py and multijoystick.py with great success on an animatronic project I’ve been working on. I added a small peice to servo.py to record movements…
logfile = file(“servolog.txt”, “a”) print >> logfile, “%d,%d” % (servo, angle) logfile.close()
then wrote servoplayback.py…
import time import servo
logfile = file(‘servolog.txt’) line = logfile.readline() for line in logfile: movmnt = line.strip() s = movmnt[0] serv = int(s) a = movmnt[2:5] angle = int(a) servo.move(serv,angle) time.sleep(.05) logfile.close()
to play the recorded movements back threw servo.py. As you can tell this is just a stack of serrvo movements with no timing and doesn’t allow for times when there is no input from the joy stick. My hope is that you might be able to point me in the direction of like minds, that could help me out with the timing issues involved in recording and playback of real time movements. Thanks in advance, and thanks for this great blog. You should be especially commended for patience and understanding with the less informed, and your willingness to help.
Matthew
@Matthew: Thanks for stopping by and thanks a bunch for the kind words. You project sounds awesome, and I’d definitely like to hear more about it. I’m not sure I can help link you up with others on similar projects — all I can think of is to try posting on the Arduino forum and see if you get any hits. Good luck and keep us posted!
excellent !!! great tutorial… can i use this programm for 7 servos after i modified it ? thank you..
Looks fantastic Brian, I’m hoping I can get this working on OS X, will have a go at the weekend. Many thanks for your detailed work!
hi there im trying to make a joystick button trigger a pin on my arduino to fire an airsoft gun. i see the button code but i don’t know how to get it to the the arduino via serial and have the arduino understand it to a point where it will power a pin on the board controlled by the trigger. If someone has already done this please share
Thanks a lot. This is a fine piece of work which helped me a lot to make a quadrirotor controlled by a joystick. Somehow using Matlab/Simulink just seemed wrong and this gave me a huge start….thanks a lot.
Thank you for the tutorial! I got a USB shield, but I have no idea how to utilize it. What I’m trying to do is to connect the USB joystick directly to Arduino and by powering it with batteries, I am able to control the servos without having it connected to a computer. Is there any helpful link that can help me to achieve that?
Thanks a million!
Hi Mr Brian,
Can you please post a new link to the Python interactive interpreter, the link on this page is broken.
Thank you for your great work.
Luke
@luke: Sorry about the broken link. The interactive interpreter or “shell” is included with any Python installation. If you’re on Mac or Linux, just type
pythonin your terminal window. If you’re on Windows, you’ll use the Command Prompt or Python (command line) under your Python 2.x folder in the programs menu. You might need to add python to your PATH variable (see the link above). A quick Google search should fill in the other details. Thanks for stopping by!Hi Im kind of new to this servo programing and need help getting my Arduino uno MC I know that you must be tired of hearing this but I want to know if theres a program like the joystick prog. for controlling an exoskeleton arm or somthing. It would be really helpful thanks.
I have adapted your program here to run a rover (tank steer) and pan tilt servo for camera running over 900 mhz xbee link…i just finished the prototype and intend on using a much larger frame later with many sensors and a wireless IP camera. I am creating a full tutorial and parts source list @ my website. my question to you is may I link your site and include pieces of your code as long as I link the crap our of you and give you credit every chance i get?…oh btw I love you for putting this out on the net …I hope to make a layman’s package for getting your app working , configuration and implementation into wireless rover from a PC…I am going to ask the GUI guy if he is interested in making a sensor front end. I would also give you my first born if you would produce some sample code to operate analog pins via buttons…Button events to servo location…things like that …(hit a button to start a servo sweep, or hit a button to put a pin high for relay use. email me if its ok if i can link your site and refer to your content. oh btw I am also into high powered rocketry and would love to collab with you on my xbee GPS rocket tracker/downlink.
@Ramsey: Links to this website are always appreciated, but they’re certainly not required to use the code posted here! I’d appreciate it if you’d keep my name in the comments somewhere, and of course distribute any derivative code under an open source license.
Your project sounds awesome, BTW, and I’m looking forward to reading your writeup and/or watching videos of the bot in action!
As far as altering
multijoystick.pyto handle button events, just look for the code block starting withand start messing around. You’ll come up with something in no time. Keep up the good work!
@Andy: I haven’t messed around with the USB shield, so I can’t answer your questions. You might try the forums at adafruit.com.
@Veronica: I’m sure you could make modifications to this code to control a robot arm of some kind, and there are lots of derivative projects out there which use this code for all kinds of bots.
Circuits@Home has a nice post and video demonstrating control of a robotic arm with a USB mouse using Arduino, a USB shield, and a servo shield.
Thank you very much, i am working on a total beginners approach, here is a video of my bot and a messy writeup that needs some work still, I will include wiring diagrams and more info as i go. http://www.somethingrisky.com/?p=38
@Ramsey: W-O-W ! ! ! Your tank-bot is easily one of the coolest projects using this code! Thanks a bunch for the props, but you’ve clearly taken it to the next level. Can’t wait to see the final version!
I did a writeup on how I got this program running wireless over Xbee for use in rovers/bots/turrets whatever you want. Arduino / Xbee wireless serial, I hope this can help someone.
Brian Is there a way i can have one of the servo outputs on the arduino board to start out at 50% DUTY CYCLE and decrease to 0 when you move the joystick one way and 100% when you move the joystick the other way. I am trying to control a solenoid with one of the axis on the joystick. i tried playin with the min and max position setup in the arduino code but no luck.
Thanks.
@luke: Yep, I’m sure it’s possible, but probably not with the current Arduino sketch presented here, which uses the Servo Library. You need to check the specs of your solenoid to see what range of PWM inputs it requires. The low end might be on the order of 250Hz, whereas the servo library is pulsing the servo every 20μs, or ~50Hz, which is probably why just changing the pulsewidth values isn’t working for you.
Try checking out this code, which uses the
digitalWrite()function to basically build the PWM signal manually, then change the refresh time and the min and max pulsewidth values to match those required by your solenoid. Then try to work that into a joystick application. Good luck and keep us posted!@luke you could use a motor controller to drive the coil on your solenoid quick and dirty it could work with some playing around. i might not understand what you are trying to do I will admit.
I have been playing with the code but can’t seem to figure out how to operate Pins on the arduino via button pushes…I understand how to add servos but cant seem to just set up a Boolean button to provide 5V on an arduino pin. Would i have to edit the sketch? the servo layer, and the multijoystick?…. I would be interested in operating servos during a duration of a button press in one direction. Operating a relay via a button would be nice too. Any help is welcome… I will keep plugging away.
I am trying to edit this part to have button 0 (the trigger ) light up the pin 13 LED on my Arduino, i figure this is simple enough and a good starting point.
elif e.type == pygame.JOYBUTTONDOWN: str = “Button: %d” % (e.dict['button']) # uncomment to debug output(str, e.dict['joy']) # Button 0 (trigger) to quit if (e.dict['button'] == 0): print “Pin 13 LED ON” // WHAT do i put here?
in the arduino sketch i have added
// Digital Pins int ledPin = 13; //built in LED on pin 13
pinMode(ledPin, OUTPUT); // Sets pin as output
digitalWrite(ledPin, HIGH) //what condition do i use to get this to work?
sorry for spamming found this …but his code seems inefficient, guess it works. :(
http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1294455774
UPDATE: Due to the sizable number of comments requesting help creating a joystick button control feature, I’ve upgraded the code to accommodate a simple LED on/off demo. This demo should be a good starting point for those wishing to control relays and other devices with the Arduino’s digital pins. More details can be found here. Hope that helps everybody, and thanks again for using this code in your projects!
LOL, thank you so much , i got a quick and dirty hack much like you posted working last night with PUSH ON / push OFF function on button 0 …thank you for your continued involvement, i hope to produce an Open Rover suite with your code that is heavily commented for quick adaptation.
I don’t really know how to thank you! I adapted your new button code and have it doing exactly what I wanted it to do. I Demo’ed your new code with some additions of my own.
http://www.somethingrisky.com/?p=164 video and code
you are right I love the update, but these updates are killing my sleep schedule!, i just cant stop tinkering. Thanks man, I never thought to check the pygame documentation … your time is appreciated, I think you are on to something big here. \
Random Thought: If you could develope a single board with bells and whistles, (motor controllers, transistors, relays, I/O’s) onto an Arduino compatible board with an Xbee socket. Eagle it out, have the PCB’s made online , populate them in a living room over drinks with friends. Sell them on sparkfun.com and provide a polished version of your coded…there is potential for some profit, or just release the Eagle file and schematics as open source and throw up a donation button.
Personally I scoured the internet for hours and hours before finding and testing your code…this setup is the easiest to implement on the net. (I have been looking for years)
hello guys! Its so good to hear people actually wanting to work this program out into a practical rover bot. I myself had been tinkering with this lately but instead of using servos nor motors with h bridges, i modified my Seiko PS050 servo into continuous rotation. So basically I’m planning to build a unmanned ground vehicle like what Ramsey is doing! I’ll continue tinkering!
@Brian thanks again for the help I learned alot about programing my friends and I got a better picture of where to start. I finally got the program for the servo motors when I tried to get the program to run the motors wouldn’t move I used this program:
#include Servo myservo; // create servo object to control a servo II These constants won't change. They're used to give names to the pins used: const int analog InPin = 0; // Analog input pin that the potentiometer is attached to const int analogOutPin = 13; // Analog output pin that the LED is attached to int sensorValue = 0; // value re ad from the pot int outputValue = 0; // value output to the PWM (analog out) void setup() // initialize serial communicatio ns at 9600 bps: { Serial. begin(9600); myservo. attach(9); // attaches the servo on pin 9 to the servo object } void loop () { sensorValue = analog Read(analaglnPin); if(sensorValue>100) { myservo. write (150); // tell servo to go to position in variable 'pos' delay(1000); // waits 15ms for the servo to reach the position } if(sensorValue< =100) { myservo. write(50); // tell servo to go to position in variable 'pos' delay(100); } outputValue = map(sensorValue, 0,1023,0,255); // map it to the range of the analog out: analogWrite(analogOutPin, outputValue); // change the analog out value: }I was wondering if I needed to download another program like the MultipleSerialServoControl.pde thank's for your help.
@Veronica: Yes, you need to download
MultipleSerialServoControl.pdeand upload it to your Arduino board. Then downloadservo.pyand follow the instructions outlined above.Brian, I am currently trying to connect a usb joystick controller to run three motors, four linear actuators and one servo. I am using a Seeduino Mega as my micro controller of choice. I have installed the python, pyserial + MultipleServoControl, pygame and I believe all are working. Is there a way to use the joystick controller to control the motors/actuators instead of servos as in this lab? This may be a trivial question but I will admit I am a newbie here. I understand the servo library and how it works, but when it comes to the other components such as the motors/actuators is there a way to ammend PWM and the joystick as well as linear actuator control extension/retraction? I am comfortable programming using Arduino software “C” but python is foreign to me. Thanks.
@Darren: Thanks for stopping by. Check out Ramsey Gill’s Open Rover project. He’s using a PWM motor controller with this code, apparently unmodified. As long as you’ve got PyGame, etc. working correctly with a garden-variety RC servo, Ramsey’s setup should be able to drive motors and actuators as well. He’s really taking this project to the next level. Good luck!
@Brian: Thank you for the link and the quick reply! My project is quite similar. I’m making a rc excavator and Gill’s open rover is the base to what I needed. This is awesome! Thanks again!
Hi, Wanted to thank you for the code and the good explanation. i’m a beginner about arduino and a EMC2 LinuxCNC user., and enjoyed very much in controlling my servos. wish i’m going to apply your code soon in some project!.
Hi Been tinkering with your code a couple of months. And i have to thank you for solving most of my underwater ROV problems. I have now full controll over my 4 esc’s, 2 relays and 1 servo. :D
(For your information. I have been testing different motorcontrollers (ESC’s) and found the Aeolian ESC’s to be superior to other more expensive ones. They work very very well with this setup and they are easy programable with the program card.)
Is there an easy way to implement other functions with the buttons? Like toggling on / off when pressing “buttondown” (some kind of “sticky” button without the “buttonup” function)
I’m also trying to solve moving the servos in a wished increment (Eg: 10degr on every push on a button) using the HAT. I will post code if i solve some of this.
Tnx again Brian for sharing this with all of us.
Karl
I am a senior electrical engineering student at The Citadel and for my groups capstone project we have created a multi-touch touch screen that controls an rc car and pan-tilt camera using this code for the base of our code. This was a great start for us. We now have a touch screen gui that controls the servos and esc on the car via Xbee 900Mhz wireless chips. The xbees are the easy to add to this software because you can just place them in between the pc and arduino using a regulator board for the pc and an arduino shield for the xbee. we got most of our equipment from sparkfun.
hi, can anyone please tell me if this code will work with XBOX 360 wired controller??
i need only the readings from the controller and not to control the servos.. how do i do this?
Hi there. I am working on a project to control a pan and tilt arm where I can fit “any” camera. if you want to see what this all about. see my blog.
Great system btw…
hi
i have got a new computer!
reinstalled python and pygame and and pyserial
i just dragged and dropped my exsisting files to the same folder but on the new computer and tried to run the servo program to test it and it showed this
Python 2.7.1 (r271:86832, Nov 27 2010, 18:30:46) [MSC v.1500 32 bit (Intel)] on win32 Type "copyright", "credits" or "license()" for more information. Traceback (most recent call last): File "C:\Python27\servo.py", line 20, in ser = serial.Serial(usbport, 9600, timeout=1) File "C:\Python27\lib\site-packages\serial\serialwin32.py", line 30, in init SerialBase.init(self, *args, **kwargs) File "C:\Python27\lib\site-packages\serial\serialutil.py", line 260, in init self.open() File "C:\Python27\lib\site-packages\serial\serialwin32.py", line 56, in open raise SerialException("could not open port %s: %s" % (self.portstr, ctypes.WinError())) SerialException: could not open port com3: [Error 2] The system cannot find the file specified.please help!
@matt: This code hasn’t been tested successfully on Python 2.7. I recently updated the tutorial with the following note on software versions:
Hope that helps. Good luck!
hi i’ve down graded to the versions you said!
but it shows this message
O the Traceback (most recent call last): File “C:\Python26\servo.py”, line 20, in ser = serial.Serial(usbport, 9600, timeout=1) File “C:\Python26\lib\site-packages\serial\serialwin32.py”, line 30, in init SerialBase.init(self, *args, **kwargs) File “C:\Python26\lib\site-packages\serial\serialutil.py”, line 260, in init self.open() File “C:\Python26\lib\site-packages\serial\serialwin32.py”, line 56, in open raise SerialException(“could not open port %s: %s” % (self.portstr, ctypes.WinError())) SerialException: could not open port com3: [Error 2] The system cannot find the file specified.
i think its something to do with the usb its plugged into? is there aways of determine what com(3?4?6?) port it is or does the usbport, 9600, timeout=1 need changing
cheersssss for the help
Try capitalizing the COM3 in the usbport variable, then just keep trying COM1, COM2, etc. until something works.
just thought! can’t remember!am i supposed to install a driver for the ardunio?
i made sure it was installed
andd played with the com port still not workin :(
Hi again, I have successfully managed to make all this work, however I am hitting a wall when it comes to try to pilot those servos using a web Form, any ideas?
I am a Perl expert and tried to create a script that does what the servo.py does, the code is ok talking to the Arduino but when I try to send a move command it fails… :-( I need to think about this further, but if you have an idea, let me know, one never know.
G.
@matt: Are you able to upload sketches to your Arduino board using the Arduino software? Are you able to send and receive messages with the Arduino serial monitor? Maybe try out the demo serial communication sketches that come with Arduino and see if you can get those working first.
@Gilbert: Sorry, I know nothing about Perl, although it should be relatively straightforward to call either a Perl or Python script from a web form.
Just a quick Thank You. Everything worked perfecto =) Next stop, doing it over XBee. Cheers.
Howdy Brian! I was able to find a way to communicate to an Arduino Mega 2560 using the official Ethernet shield on a local area network. If you are interested I am more than willing to share this information! Hit me up!
Great tutorial! I’m using the Python integration in my own program, but have run into a problem with the bytes
When I check the startByte (that is, startByte == 255) I discover that arduino interprets the 255 as 3 individual data points, so it sees 2, 5 and 5. Suggestions?
if (Serial.available()) { byte startByte = Serial.read(); Serial.print("byte found "); Serial.println(startByte, BYTE);@Wes: Thanks! Are you using Python’s
chr()function to send serial data to Arduino? That should solve your issue.e.g.:
ser.write(chr(255))I have a problem: when I write servo(2,0) servo.py sends chr(2) and chr(0) that is \x00 but arduino doesn’t understand. I try this code in serial monitor (arduino ide) but works only if I write 0. The same for 1,2, etc. Seems to be a difference beetween python ascii code and arduino ascii code. Can you help me, thanks?
@Roby: ASCII is ASCII, there is no difference between languages. When you type a character in the Arduino IDE serial monitor, the Arduino board receives the ASCII decimal equivalent. So, if you type “2″, the Arduino sees “50″.
See the Tom Igoe articles mentioned in the references section above for more details, or check out this ASCII table for character conversions.
If you’re using the Python and Arduino code here without modification, it should work as advertised.
when I write chr(2) python send code ‘\x02′ and arduino doesn’t understand. maybe this is the problem. I’m using your code without modification but it doesn’t work.
Another little question. When I push button 0 program exits but I receive an error: str object is not callable. What means? Thanks
Hi, just an update, I am having problem with the USB port, it keeps changing each time I send a command, when the PC is rebooted the port is ttyACM0 then each time I send a command, it works, then the servo goes back to position 90 by itself after a second or so and the other servos twitch also, then the port is on ttyACM1 I am at ttyACM22 now and shows no sign of abating, it’s a Linux box. It’s really annoying as all is working fine other than that, (and used to so I am at a loss as to why it keeps happening). Anyone’s got an idea?
mmh, ok sorted it, don’t use a usb cable that is too long! :-(
Just thought i’d share my new rover with netcam based on this code…Brian Thank You!. hope to have HUD or GUI for sensors made in processing this fall.
http://www.somethingrisky.com/?p=197
ok now that all is working I am trying to write a python variant that will take command line inputs, the script works but the servos aren’t moving?!:
!/usr/bin/env python
#
Module: servo.py
Created: 2 April 2008
Author: Brian D. Wendt
http://principialabs.com/
Version: 0.3
License: GPLv3
http://www.fsf.org/licensing/
”’ Provides a serial connection abstraction layer for use with Arduino “MultipleSerialServoControl” sketch. ”’
#
import serial import sys
Assign Arduino’s serial port address
Windows example
usbport = ‘COM3′
Linux example
usbport = ‘/dev/ttyUSB0′
MacOSX example
usbport = ‘/dev/tty.usbserial-FTALLOK2′
try: servo = int(sys.argv[1]) angle = int(sys.argv[2]) except IndexError: print (‘a servo and angle are required’) sys.exit(2)
Set up serial baud rate
usbport = ‘/dev/ttyACM0′ ser = serial.Serial(usbport, 9600, timeout=1) def move(servo, angle): ”’Moves the specified servo to the supplied angle.
move(servo, angle)
Hello Brian, nice work! I created a project in Python to control Arduino using Twitter. It’ll be cool to integrate with your project (my code needs more refactoring, but for now it is very simple and works fine). For more information, visit: https://github.com/turicas/tweetlamp
Cheers.
Brian, i know you have been covering this in Processing a bit…but is it possible to integrate firmata and this code to allows python joystick control and VB app control of pins? this app looks promising i would like to use it or replicate a similar app in processing. I would like to get GPS info displayed, analog pin info and digital control and status from the Arduino while also using a joystick for control…Possible?
Thanks, i know you are busy
link to VB firmata app http://www.acraigie.com/programming/firmatavb/default.html
Hey @Ramsey: Oh man that VB GUI looks cool. That is exactly the type of thing I want to do with Processing (or Python)!! I especially like the idea of displaying telemetry data (and even video) on a PC, while controlling the bot with a joystick.
I’ve been wondering lately if a rover/bot concept such as yours would almost need TWO microcontrollers: one for command and control, and another for collecting and transmitting sensor data, to simplify the coding and keep the memory and processor on the control Arduino free to receive commands. The PC would also have two (or more) USB-Xbee inputs, and the GUI would just tie everything together.
Unfortunately I’m bogged down with work and school, along with the myriad tasks of my primary project these days – the kitplane – so I haven’t really been focusing much on the Arduino/Processing stuff lately. If you have a go at it though, keep me posted!!
BWs
I was thinking exactly the same thing (2 Arduino’s) when I started to think about all the serial data I would be cramming down the Arduino’s throat. Currently i am using a java based DLink IP camera, I am sure there would be a way to tap into that java and embed the video into a program interface some way. Your kitplane looks awesome!!!, I have always wanted to build an experimental air craft, i always see ultra lights near our farm. . I just started working at a company called Frasca International http://www.frasca.com/. They manufacture flight simulators.
Hey Brian, You saved my nerves buddy! I was getting mad in my robotic project. I’m from Iran and it is crazy to say I’m the only one who uses Arduino for most projects, everyone here mostly offers to spend time designing PCB boards with AVR micro pro, don’t give rat ass! Just wanna to say: THANK YOU SO MUCH!
tanks for this the thing which i search from last one year to complete my project.thanks a lot for this
Thank you, this was exactly what I was looking for: controlling the arduino directly from the computer.
Though I’d like to know how to recieve data from the Arduino as well, can anyone throw me in the right direction for this? I want to use Python and preferably the ‘serial’ module. I know Python quite well but I know little to nothing about serial communication, but it seems simple enough to use in this example.
@Rasmus: Thanks for stopping by. You might want to check out Firmata, an Arduino-based communications protocol with tons of functionality already built in, so you don’t have to waste time writing your own (like I did! haha).
Howdy !
I am new to all this, but I am eager to learn, and have learned alot of your tut ! However, I would like to use several motors (RC kind with PWM adjustment), and a few servos, plus buttons on the joystick for on/off functions… I believe that this is just plug and play, but I want to make sure before I fry my PCBs… ;) Is it just to change “servo” to “motor” etc… in the program? And, I want to use ethernet from the laptop to the Arduino Ethernetcard (that is mounted on the Mega card…) How will this be with COM ports? Do I need a router between the laptop and Arduino side? (to get correct IP etc…?)
I really hope that you have time and interest to help me with this :)
Rob