Go Down

Topic: code for controlling a servo with Arduino (Read 5202 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
 


Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

Arduino
via Egeo 16
Torino, 10131
Italy