-
Notifications
You must be signed in to change notification settings - Fork 65
R C Servo
R/C Servos are a particular kind of motor commonly used in radio-controlled vehicles. They can be precisely positioned at particular angles by sending them varying electrical signals.
View an annotated version of this picture on Flickr.
Radio-controlled vehicles use servos for steering, wing flap positioning, and other small-scale precision movements. Robot builders use them to move arms. Stop-motion animators use them to move characters and for repeatable frame-by-frame camera control. While they are best suited to accurate fine movements of relatively light objects, they can also be modified to power wheels for locomotion.
Servos have three wires: one each for power and ground and one for control. Plug the power (usually red) and ground (brown or black) wires into the appropriate places on your circuit or to the Arduino’s 5V and GND pins directly. Then connect the remaining (orange or yellow) wire to one of the Arduino’s data pins. The Arduino will tell the servo what position to move to by turning the data pin on and off at different rates (see ‘How It Works’ below for more detail). We’ll use the RAD servo library so we don’t have to worry about the specifics of how the Arduino actually sends the desired position to the servo. All we have to do is give the Arduino the angle to which we want the servo moved in degrees (i.e. an integer from 0 to 180) and do a little bit of other overhead to make sure the communication link between the Arduino and the servo is not broken.
(axis diagram)
Here’s a basic RAD sketch that moves a servo to the middle point in its range of motion.
class Servo < ArduinoSketch
output_pin 11, :as => :servo, :device => :servo
def loop
servo_refresh
servo.position 90
end
end
The first thing we do is configure pin 11 as an output_pin. In addition to the normal options, we pass :device => :servo, so that RAD will configure this output to work with the Arduino Servo library, providing a series of functions for doing common servo tasks.
Now, within our loop, the first thing we do is call servo_refresh. If the Arduino does not send some signal to the servo every 20ms or so, the motor will lose its position, servo_refresh sends this check-in signal if necessary and does nothing if not. On the first run through the loop when the Arduino wakes up, servo_refresh will prepare the servo for further messages that we are going to send it.
The next line tells the servo to move to a particular position. The number 90 represents the halfway point in the servo’s range of motion with 0 and 180 the extremes. Once the servo is at position 90 (i.e. after the first time through loop), this line will do nothing visible, just cause the servo to remain where it is. Similarly, if you re-upload this sketch to your Arduino multiple times you will get different results. While the servo does relax away from its given position when not given a control signal from the Arduino, it doesn’t move too far, so when the loop runs again and servo.position gets called, the servo will only move the small distance necessary to re-align itself to the middle of its range of motion. These position numbers are absolute to that range, not relative to the current position of the servo. Similarly, as the Arduino is starting up after being re-connected to power (or when it is being re-programmed), you might see the servo jitter a bit as the Arduino temporarily sends out arbitrary electronic signals on the output pin during its startup phase.
If you change the number being passed to servo.position (to any integer between 0 and 180) and re-upload your sketch, you’ll see the servo move to the new position. Repeat this with various positions to explore its full range of motion.
You can use this sketch to calibrate your servo, getting whatever hardware you plan to attach to the servo correctly oriented so that it will be positioned correctly when your servo moves to wherever you send it. For example, if you’re using the servo as an applause-o-meter, displaying the level of ambient noise in the room, you might want to calibrate it so that it would be completely horizontal to the left at 0 and would rise through your applause gauge as you sent it higher and higher values approaching 180.
From the Servomechanism article on Wikipedia:
RC servos are composed of a DC motor mechanically linked to a potentiometer. Pulse-width modulation (PWM) signals sent to the servo are translated into position commands by electronics inside the servo. When the servo is commanded to rotate, the DC motor is powered until the potentiometer reaches the value corresponding to the commanded position.
alternate between two positions
class Servo < ArduinoSketch
output_pin 11, :as => :my_servo, :device => :servo
def loop
servo_refresh
my_servo.position 180
servo_delay 1000
my_servo.position 0
servo_delay 1000
end
def servo_delay(t)
t.times do
delay 1
servo_refresh
end
end
end
move to one of three positions according to serial input; provide feedback, via serial, on current position:
class SerialIntegration < ArduinoSketch
output_pin 11, :as => :my_servo, :device => :servo
serial_begin
@val = int
def loop
if serial_available
servo_refresh
@val = serial_read
if @val == 'a'
my_servo.position 180
serial_println "moving"
end
if @val == 'b'
my_servo.position 90
serial_println "moving"
end
if @val == 'c'
my_servo.position 0
serial_println "moving"
end
servo_delay 600
serial_print "at position: "
serial_println my_servo.read
serial_println " "
serial_println "ready"
end
end
def servo_delay(t)
t.times do
delay 1
servo_refresh
end
end
end
Dynam Micro Servo pictured above: http://www.dynam-rc.com/products/servos/servos.htm
http://www.societyofrobots.com/actuators_servos.shtml
http://en.wikipedia.org/wiki/Servomechanism#RC_servos