code for controlling a servo with Arduino

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

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 :wink: ) So please take a look at the following:

/* 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):

#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;