Introduction: Arduino Based Serial Servo Controller
This is a simple serial controller for multiple servos based on the Arduino. (my first instructable too :) )
Most of the work in this came from getting the software to talk with the arduino and making a protocol for the data to be passed over. As for the hardware aspect all that I used was two servos (Parallax standard servo here.) A Sparkfun Arduino ProtoShield and an Arduino Duemilanove with ATMEGA328, but most of these parts can be substituted with similar items.
I thought up this project as part of a RC system, but setting up the communication took a lot of time. If anyone has any improvements, ideas, or bugs please feel free to comment.
EDIT: I wrote this awhile ago, just got to publishing it recently.
Step 1: Things You May Need...
Some things you will need to build this.
1. Arduino board (you choose)
2. two (or one) servos
3. jumper wires
4. Visual Studio 2008 Express -- link (optional)
5. Arduino IDE -- link
Sorry Linux and Apple fans, my program only runs on windows for now, but you can still manually send serial commands to the arduino without changing the code.
Step 2: Connect the Hardware.
Nothing very complex to this step.
Just connect one servo to pin 9 and the other to pin 10.
Step 3: Program the Arduino
now you can upload the sketch onto the arduino.
Here is a simple breakdown to the code:
#include
Servo myservo; // create servo object to control a servo
Servo myservo1;
int incomingByte = 0, datacount = 0, counter = 0, ready = 0; // for incoming serial data
char data[10];
const char verify[8] = "ma11hew";
char command[3];
void setup() {
myservo.attach(9);
myservo1.attach(10);
Serial.begin(38400); // opens serial port, sets data rate
Serial.println("Hi Arduino Here!"); // added to help identify the serial port
This just sets up the serial port and servos.
int i;
for(i = 0; i<180;i++)
{
myservo.write(i);
delay(15);
}
myservo.write(5);
for(i = 0; i<180;i++)
{
myservo1.write(i);
delay(15);
}
myservo1.write(5);
}
Simple sweeping movement to verify the servos work correctly.
void loop() {
ready = 0;
counter = 0;
while (1==1)
{
if (Serial.read() != verify[counter])
{
break;
}
if(counter == 6)
{
delay(20);
command[0] = Serial.read();
command[1] = Serial.read();
//if (Serial.read() == ((command[1] * 12) % 8))
// {
ready = 1;
//}
Serial.println("saved command");
}
counter ++;
delay(2);
}
this checks the serial buffer for the correct authorization string then grabs two bytes for the command.
the commented if statement allows for a makeshift checksum but would make manual interfacing hard.
ready can be set to 0 so commands will not be parsed such as in the case of corrupted data.
//search through commands
if (ready == 1)
{
if (command[0] == 'T')
{
command[0] = 0;
Serial.print("throttle control on pin 9 to: ");
Serial.println(map(command[1], 32, 126, 2, 180), DEC);
myservo.write(map(command[1], 32, 126, 2, 180));
}
if (command[0] == 'S')
{
command[0] = 0;
Serial.print("throttle control on pin 10 to: ");
Serial.println(map(command[1], 32, 126, 2, 180), DEC);
myservo1.write(map(command[1], 32, 126, 2, 180));
}
}
}
the rest of the code is to search command[] for valid commands (T or S.)
if either match it takes the next byte and sends it to the servo.
more on the map(command[1], 32, 126, 2, 180) later...
the code here is expandable for whatever else you may need (eg. lights, motors, IR, etc.)
this code should work fine with no modifications.
Attachments
Step 4: Install Software
I have two ways to install this...
nsis installer:
Download the self extracting installer below and run it.
You will have the option to install sources during the install.
the installer binary package installs core c++ dlls so it can be run on a computer without visual c++ installed already.
Once the installer finishes you can run it from the desktop or start menu.
zip way (unverified):
Download and run, it should work. maybe.
(The zip archive has the same folder structure created by the installer, without sources. I don't have a machine without visual studio to test it on so it may not work.)
Step 5: Use the Interface Program
To use the program first select the baud rate defined in the arduino sketch.
The unmodified sketch defaults to 38400 baud but can be changed to suit your needs for things like a slower radio link. note: baud rates higher than 38400 have not been very stable, I think this is because the uart fills up before the data can be processed.
Next, select the COM port to use. the program defaults to COM4 be sure to change it or the program will crash.
Finally, click open. If all went well the program will open the selected serial port at selected baud rate.
If not the program will probably crash with an unhandled exception. make sure the port is correct and try again.
Use the textboxes to submit direct commands to the arduino. The "map(command[1], 32, 126, 2, 180)" scales all the 94 possible commands, *space* through ~, readable by the arduino in ASCII to 2 through 180 for the servo. any byte less than ASCII 32 (space) or above 126 (~) defaults to 63 (?)
The track bars provide an eaiser interface for direct commands. each step sends a serial command to the arduino incrementally.
Step 6: Get Creative!
Think of cool things to make with this. Some ideas:
1. Remote throttle for a car.
2. 3D camera mount
3. underwater rover
Have fun!!
12 Comments
10 years ago on Introduction
How do you control 2 different servos with the same serial port? I've been tryig to do that but i can't make it work....
11 years ago on Introduction
Much as I detest mono and .net, It would have been nice to see your mswindows source code to see if it could be ported to either linux or osx.
12 years ago on Step 6
quick question i have 2 servos controlled by a serial write and read system. do i have to have the arduino plugged into a computer or can i use an external power source(9v with barrel jack slot)?
Reply 12 years ago on Introduction
Well, for the serial write and read to work, you'll need the USB connection (or another device to forward the serial data, be it bluetooth, Xbee, etc.)... so yes, it'll need to be connected to the computer somehow (if that's what you're doing).
However, as far as power is concerned.. it'll work as long as the servos aren't too big for the 5v regulator on the Arduino (although, even then it's not a bad idea to use a larger regulator separate from the Arduino's to run just the servos, I've seen some odd things happen when the servos get to be too much for the Arduino's power supply, but not enough to actually shut it down)
If it does need a larger regulator, you can use something like a LM317 regulator to supply power to the servos (or another regulator, I just happen to like the 317)
Thanks, Matt
Reply 12 years ago on Introduction
Thanks it is not a power problem im just tryimg to end the dependance on my laptop but I guess it will take comeplete reprogramming :/
13 years ago on Step 3
Hi there :) First, thanks!, for posting this mattie95, and regarding the issue that Dannne11 has (or had) to compile the code is because the first line of the code posted in the page says only " #include " instead of " #include <Servo.h> " (without quotes), but this should be added only if you copy the code from the page, if you download the file attached "radio_protocol_fix.pde", it should compile just fine. Just thought to point it out for someone else doing copy/paste from the code. :) Janux
13 years ago on Step 3
10: error: #include expects "FILENAME" or In function 'void setup()': At global scope: In function 'void setup()': Bad error line: -5 This is the code. posted the wrong code first srry
13 years ago on Step 3
the error code is "10: error: #include expects "FILENAME" or In function 'void setup()': At global scope: Bad error line: -3 "
13 years ago on Step 3
the code do not work with the arduino software :(
Reply 13 years ago on Step 3
what's the error? I'm away from home so I can't test it out, but it definitely compiles fine in arduino 18.. Sorry for the trouble, Matt
13 years ago on Introduction
dont you mean instructable?
13 years ago on Introduction
Would you mean something like: "Serial.println("Hi Arduino Here!");"
right after the Serial.begin(38400)?
When the port is opened it will usually reset the arduino so it should work when the port is first selected.
I will update the current file here to support this.
--matt