Controlling RC servo motors

Controlling RC servos with a microcontroller is rather simple, due to the minimalistic communication protocol used by these motors.

The diagram below is a mostly complete description of this protocol:

5V  ┌────┬┄┄┄┄┐               ┌───
    │    │    ┆               │
0V ─┘    └────┴───────────────┘
    0ms  1ms  2ms             20ms

The angle the servo is set to is controlled by the pulse length seen in the diagram.

  • A pulse length of 1ms means turn all the way in one direction
  • A pulse length of 2ms means turn all the way in the other direction
  • A pulse length of 1.5ms means move to the origin

To generate these pulses we will use the pwm module. Below are two functions to controll the servos.

  • servo_setup performs the necessary setup to control a servo motor on pin 2 of the microcontroller
  • servo_set sets the position of the servo on a scale from 0-100
function servo_setup()
    pwm.setup(2, 50, 75)
    pwm.start(2)
end

function servo_set(pos)
    local pos_clip = math.max(math.min(pos, 100), 0)
    local duty = (1 + pos_clip/100) / 20 * 1023

    pwm.setduty(2, duty)
end

The servo is connected using three wires:

  • The black wire is connected to GND
  • The red wire is connected to 5V
  • The white wire is connected to pin D2

Task: Connect a servo and write a program that toggles between the to endpoints once a second.