Thursday, 20 November 2008

Servo Motors with Arduino

Servo Motors are a kind of motor that can read its position, and turn to a position, rather than just 'run' until stopped. These are a good choice to include in my UAF project as the tools to move the fan.

The Arduino code that will control the motors is freely available on the internet...
/*
Two-servo control from an analog input

Moves two servos based on the value of one analog sensor,
in opposite directions.

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.

by Tom Igoe
Created 28 Jan. 2006
Repurposed for Dual Servos by Carlyn Maw
24 Mar. 2006
*/

int servoPinL = 2; // Control pin for servo motor - L
int servoPinR = 3; // Control pin for servo motor - R
int minPulse = 500; // Minimum servo position
int maxPulse = 2000; // Maximum servo position
long adjustedAV = 0; // Analog value adjusted for determining pulse values
int pulseL = 0; // Amount to pulse the servoL
int pulseR = 0; // Amount to pulse the servoR
int delayValueMax = 200; // the 20 microsecond maxiumum pulse range for the servo
int delayValue = 200; // 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

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

void loop() {
analogValue = analogRead(analogPin); // read the analog input (0-1024)
adjustedAV = (analogValue / 10) * 19; // convert the analog value to a number
// between 0-2000 (difference between min and max)

pulseL = adjustedAV + minPulse; // set value for left motor
pulseR = maxPulse - adjustedAV; // and the inverse for the right

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
}


Code from: www.tigoe.net
I edited the code to represent the timing for my specific motors, so the electrical pulse that the servo motors use to move and read position never goes too high or too fast. Here is the result using a potentiometer as the user input (as a method for easy testing)...

No comments: