Go Down

Topic: code for controlling a servo with Arduino (Read 4 times) previous topic - next topic

eighthave


Does anyone have code for controlling a servo with Arduino?  I know that you usually send it a pulse train where the pulses vary between 1 and 2 ms.  But completed and debugged code is always nice.

.hc


David Cuartielles

Hej,

today I got a question by email and I actually solved it to work with Puredata (I bet that is your interest in the end ;-) ) So please take a look at the following:

Code: [Select]

/* Servo Motors
* ------------
*
* This program controls 2 servo motors through sending commands over
* the serial port. The motors will be connected to pins 2 and 3. It
* motors will be controlled with a single byte. The first nibble will
* control the motor, while the second will control the postion. Thus
* each motor will have 16 positions.
*
*
* (cleft) 2006 David Cuartielles for K3, Sweden
* http://www.arduino.cc
*
* @idea: T. Igoe, J. Gray
* @code: T. Igoe, J. Gray, D. Cuartielles
* @PD patch: D. Cuartielles
*
*/

int servoPinL = 2; // Control pin for servo motor - L
int servoPinR = 3; // Control pin for servo motor - R
int pulseL = 0; // Amount to pulse the servoL
int pulseR = 0; // Amount to pulse the servoR
int delayValueMax = 20000; // the 2 millisecond maxiumum pulse range for the servo
int delayValue = 20000; // the actual value the code should wait,  determined later
int analogValue = 0; // the value returned from the analog sensor
int analogPin = 0; // the analog pin that the sensor's on
char c, servoNumber, servoValue;

void setup(void)
{
 pinMode(servoPinL, OUTPUT); // Set servo pins as an output pins
 pinMode(servoPinR, OUTPUT);
 pulseL = 1000; // Set the motor position values to the minimum
 pulseR = 1000;
 beginSerial(9600);
}

void loop(void)
{
 c = serialRead();
 if (c != -1)
 {
   servoNumber = (c & 0xF0) >> 4; // servo ID is in high nibble
   servoValue = (c & 0x0F); // servo angle is in low nibble
   if (servoNumber%2 == 0) pulseL = (servoValue*62) + 1000; // make a pulse 1000-2000 us
   else if (servoNumber%2 == 1) pulseR = (servoValue*62) + 1000; //  make a pulse 1000-2000 us
   // print values on the screen
   // for a terminal window
   //printString("\n\r Numer: ");
   //printInteger(servoNumber%2);
   //printString(" - Value: ");
   //printInteger(servoValue);
   // print values on the screen
   // for debugging in PD
   serialWrite(c);
 }

 digitalWrite(servoPinL, HIGH); // Turn the L motor on
 delayMicroseconds(pulseL); // Length of the pulse sets the motor position
 digitalWrite(servoPinL, LOW); // Turn the L motor off

 digitalWrite(servoPinR, HIGH); // Turn the R motor on
 delayMicroseconds(pulseR); // Length of the pulse sets the motor  position
 digitalWrite(servoPinR, LOW); // Turn the R motor off

 delayValue = delayValueMax - pulseL - pulseR; // determine how   much time you have before the 20 ms is over...
 delayMicroseconds(delayValue); // 20 millisecond delay is needed between pulses to keep the servos in sync
}


The PD patch looks like follows (remember that you need a revised version of comport):

Code: [Select]

#N canvas -2 0 1007 671 10;
#X obj 14 92 cnv 15 1000 20 empty empty arduino_section 20 12 0 11
-260481 -258049 0;
#X obj -144 -139 cnv 15 1000 20 empty empty PD_section 20 12 0 11 -199397
-145298 0;
#X obj 880 -86 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0
1;
#X obj 880 268 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0
1;
#X text 879 -103 debug;
#X text 879 284 debug;
#X obj 892 48 s to_comport;
#X text 6 301 On Mac OS X \, set this to the right value:;
#X msg -61 273 open \$1;
#N canvas 162 133 530 380 serin 0;
#X obj 120 61 cnv 15 15 15 empty \$0-number-canvas 2 4 7 0 14 -233017
-1 0;
#X obj 200 225 s \$0-number-canvas;
#X obj 60 61 hradio 15 1 0 4 empty empty empty 0 -6 0 8 -225271 -1
-1 2;
#X obj 59 147 outlet;
#X obj 60 13 inlet;
#X msg 200 202 label \$1;
#X obj 200 180 makefilename %d;
#X obj 59 108 float;
#X connect 2 0 7 0;
#X connect 4 0 2 0;
#X connect 5 0 1 0;
#X connect 6 0 5 0;
#X connect 7 0 3 0;
#X connect 7 0 6 0;
#X coords 0 -1 1 1 76 17 1;
#X restore -61 250 pd serin;
#X text 20 251 serial port #;
#X msg -1 273 close;
#X obj -61 381 comport 0 9600;
#X msg 6 319 devicename /dev/tty.usbserial-1B1;
#X obj 27 349 r to_comport;
#X obj -144 206 cnv 15 1000 20 empty empty serialport_section 20 12
0 11 -150642 -39136 0;
#X text 899 501 jasch_20060503;
#X obj -63 422 spigot;
#X obj -13 424 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1
1;
#X obj -63 449 print;
#X floatatom -63 -89 5 0 0 0 - - -;
#X floatatom -18 -89 5 0 1000 0 - - -;
#X text -86 -107 servo ID;
#X text -18 -107 value;
#X obj -88 -1 t b;
#X floatatom -63 145 5 0 0 0 - - -;
#X floatatom -18 145 5 0 0 0 - - -;
#X text -84 160 servo ID;
#X text -11 160 value;
#X obj -144 92 cnv 15 1000 20 empty empty arduino_section 20 12 0 11
-260481 -258049 0;
#X obj -55 29 s to_comport;
#X text 28 113;
#X obj -18 -45 % 16;
#X obj -63 -1 +;
#X obj -63 -45 << 4;
#X text -130 113;
#X text 168 -82 comment;
#X connect 2 0 3 0;
#X connect 2 0 6 0;
#X connect 8 0 12 0;
#X connect 9 0 8 0;
#X connect 11 0 12 0;
#X connect 12 0 17 0;
#X connect 13 0 12 0;
#X connect 14 0 12 0;
#X connect 17 0 19 0;
#X connect 18 0 17 1;
#X connect 20 0 34 0;
#X connect 20 0 25 0;
#X connect 21 0 32 0;
#X connect 24 0 33 0;
#X connect 32 0 24 0;
#X connect 32 0 33 1;
#X connect 32 0 26 0;
#X connect 33 0 30 0;
#X connect 34 0 33 0;

Go Up
 

Quick Reply

With Quick-Reply you can write a post when viewing a topic without loading a new page. You can still use bulletin board code and smileys as you would in a normal post.

Warning: this topic has not been posted in for at least 120 days.
Unless you're sure you want to reply, please consider starting a new topic.

Note: this post will not display until it's been approved by a moderator.
Name:
Email:

shortcuts: alt+s submit/post or alt+p preview