Pwm signals – Servo motor

Objective

Learn how to control a servo motor.

How a servo motor works

Servo motors has 3 cables:

  • Power supply: Normally red (4.8 to 6V)
  • Ground: Black or brown (GND)
  • Signal: White or yellow

To move the axle in a position you need to send a pulse through signal cable. Controlling the duration of the pulse you can move the servo into a different positions. Most of the servos can handle timings between 1 to 2 milliseconds, check your servo model for timming details. Normally servo motors need to be a 20 ms period (approximately) like is shown of the image below.

servo_pwm_signal

This means that we need to set the PWMs period to be 20 ms. In mbed we have some options to do it, you can look for more information here. Im going to explain the one that I think is the best. PwmOut has some functions like “period_ms(time)” in wich you need to indicate the period time un miliseconds (only intiger numbers). In order to implement this code you need to write:

[cpp]

// Declare the pin as PWM
PwmOut servo_motor(PTD4); // For KL25Z, look the pinout for other boards

int main(){
servo_motor.period_ms(20); // Set period to 20 ms this has to be setted only one time
while (1){
… // Your program goes here
}
}
[/cpp]

Assuming that your servo has 1 – 2 ms pulse width control signal, next graph show the relation between time (x-axis) and position (y-axis).

servo_pos

So to controll your servo position you most indicate the duty cicle, but it would be easier if we can indicate in time instead of percentage. Pwm has a function wich let you specify the duty cicle in ms, but it only accepts integer number so the only two options would be 1 and 2 miliseconds, other option could be to specify the time in microseconds and we know that 1 ms is 1000 us. So using “pulsewidth_us(time)” let us to control the servo position by specifing the time in microseconds like this example:

[cpp]
… // variables, main program, etc.
// Remember that our object is called servo_motor() from above example
servo_motor.pulsewidth_us(1000); // move servo to 0° position
wait(3); // wait 3 seconds in this position
servo_motor.pulsewidth_us(1500); // move servo to ~90° position
wait(3); // wait 3 seconds in this position
… // program continues
[/cpp]

Full basic example

The complete code would look like:

[cpp]
#include "mbed.h"

PwmOut servo_motor(PTD4); // KL25Z pinout

int main(){
servo_motor.period_ms(20);
while(1){
servo_motor.pulsewidth_us(1000);
wait(3);
servo_motor.pulsewidth_us(1500);
wait(3);
}
}
[/cpp]

Leave a comment