RC Servo Motors

In the Arduino enviroment, the PWM signal (analogWrite) is most commonly used to control something i.e. a DC motor, solenoid or RC Servo. With DC motors, you can control if they are on or off, and the speed – although controlling the direction and position of the motor is a bit more involved and requires more components. RC Servo motors are designed for use in radio-controlled (RC) cars, boats and planes. These motors have the additional components needed to control the motor’s direction and position – built into them.

The servo contains a combination of gears, a potentiometer and additional circuitry which allows you to control its direction and position – within a 180 degree range of travel. Servos are quite easy to setup and control, they have three wires: VCC (4 – 6V), GND and the Control or Signal Line. Ensure that your power supply can provide at least 1A of current. Don’t use the Arduino to drive your servo motor, as the Arduino output pins (40mA) do not provide the needed current for the servo (~150mA) to work.

Once you have connected the servo motor, the Arduino will send a series of pulses to the motor through the Signal Line. The signal consists of positive pulses (PWM) in the range of 0.5mS to 2.5mS long, this is done 50 times per second (every 20mS). The servo will position its output shaft in proportion to the width of the pulse. Most servos can travel through 180 degree range, although some servos can be damaged if commanded beyond mechanical limitations.

If you are unsure of the servos possible range, set your MIN_PULSE and MAX_PULSE to operate within a 90 degree range (0.9mS to 2.1mS) – then patiently observe when the pulse value no longer results in additional servo output. These are now the servos MIN_PULSE and MAX_PULSE positions.

Servo Motors
Servo Motors

Analog Servo Motor Controller:

/*
 Servo Motor Control by Tom Igoe.

The minimum (minPulse) and maxiumum (maxPuluse) values
will be different depending on your specific servo motor.
Ideally, it should be between 1 and 2 milliseconds, but in practice,
0.5 - 2.5 milliseconds works well for me.
Try different values to see what numbers are best for you.

This program uses the millis() function to keep track of when the servo was
last pulsed.  millis() produces an overflow error (i.e. generates a number
that's too big to fit in a long variable) after about 5 days. if you're
making a program that has to run for more than 5 days, you may need to
account for this.

Addition by Carlyn Maw & Rob Faludi
Addition Elio Bidinost
Created 28 Jan. 2006
Updated 10 Jun. 2008
Updated 4 Nov 2008
*/

// Servo Control Pins
#define SERVO_PIN_1 3
#define SERVO_PIN_2 10

// Analog Sensor Input Pins
#define ANA_PIN_0 0
#define ANA_PIN_1 1

// Define Servo Min & Max Pulse
#define MIN_PULSE 500
#define MAX_PULSE 2500

// Servo Control Variables
int servo_pulse_1 = 0;
int servo_pulse_2 = 0;

int servo_pulse_temp_1 = 0;
int servo_pulse_temp_2 = 0;

int servo_lpulse_1 = 0;
int servo_lpulse_2 = 0;

// Analog Sensor Value
int analog_1 = 0;
int analog_2 = 0;

long lastPulse = 0;    // the time in milliseconds of the last pulse
int refreshTime = 20; // the time needed in between pulses

void setup() 
{
  Serial.begin(9600);
  
  pinMode(SERVO_PIN_1, OUTPUT);  // Set servo pin as an output pin
  pinMode(SERVO_PIN_2, OUTPUT);  // Set servo pin as an output pin
  
  // Set the motor position value to the minimum
  servo_pulse_1 = servo_pulse_2 = MIN_PULSE;  
}


void pulseServo(int servo, int pulse, int lpulse)
{
  // pulse the servo again if rhe refresh time (20 ms) have passed:
  if (millis() - lpulse >= refreshTime) 
  {
    digitalWrite(servo, HIGH);  // Turn the motor on
    delayMicroseconds(pulse); // Length of the pulse sets the motor position
    digitalWrite(servo, LOW);  // Turn the motor off
    lastPulse = millis();          // save the time of the last pulse
  } 
}

void loop()
{
  analog_1 = analogRead(ANA_PIN_0);      // read the analog input
  servo_pulse_1 = map(analog_1, 0, 1023, MIN_PULSE, MAX_PULSE);
 
  if (servo_pulse_1 != servo_pulse_temp_1)
  {
    pulseServo(SERVO_PIN_1, servo_pulse_1, servo_lpulse_1);
    servo_pulse_temp_1 = servo_pulse_1;
    servo_lpulse_1 = lastPulse;
  }

  /* To add another Servo - copy 
  analog_2 = analogRead(ANA_PIN_1);      // read the analog input
  servo_pulse_2 = map(analog_2, 0, 1023, MIN_PULSE, MAX_PULSE);
 
  if (servo_pulse_2 != servo_pulse_temp_2)
  {
    pulseServo(SERVO_PIN_2, servo_pulse_2, servo_lpulse_2);
    servo_pulse_temp_2 = servo_pulse_2;
    servo_lpulse_2 = lastPulse;
  }
  and config the code block... 
*/ 

}