Wednesday, 8 February 2017

mbed Servo Control - 0 to 180º fix - Thomas Murphy

Introduction

Controlling a servo motor is relatively straight forward where the servo position is controlled using Pulse Width Modulation (PWM). The PWM signal is applied to the signal wire (often white). Most servos have a minimum and maximum pulse width of 500μs - 2500μs but there some fluctuations in these values so look up these values for the servo you wish to use. Depending on the pulse width, the servo will go to a certain position. The simple PWM diagram below shows a pulse width of 1ms which turns to motor to 0º and a pulse width of 2ms which turns to motor to 180º. Sending a value between 1ms and 2ms, in this case, will turn the motor to an equivalent angle. The period of each pulse is 20ms.

Image result for pulse width modulation servo control


Current mbed Servo Library Issue and Fix

The current servo Hello World example code available from mbed was designed to limit the servo motor to 0º - 90º. Not sure why the code was developed to limit servo control in this way but I found a fix which allows the servos to rotate from 0º - 180º. It involves changing/ replacing the Servo.h and Servo.cpp files in the Servo library with the equivalent files found at:

Changing the Servo.h and Servo.cpp libraries allows for the PWM signal to span from 500μs - 2500μs so 0º - 180º. This works for the basic servo but other servos should operate around the same pulse width range. Below is a sample code which will sweep the servo through its full range on a continuous loop. Note: The angle is only set as high as 175º to avoid the servo reaching the end of the full range. This is just as a precaution to avoid any chance of the motor trying to go too far and burning itself out.

Send a Servo to Specific Positions

The code below shows sweeping the servo over its range but precise position control is not only possible but reasonably straight forward and intuitive. The servo can be sent a command to go to a certain position using the myservo.write(degree); line. based on the code below. Should you wish to send it to one position and then to another make sure to include a wait after the first sequence to allow the servo enough time to make it to the initial angle/position specified. There is no wait time that will suit all servos since each servo has a different speed to torque ratio where typically a large servo designed for high torque will be slower than one concerned more with rotation speed. Common sense really but still important to remember the wait so adjust the wait time to what seems best for your design. If you were to write the code for changing to set positions in a loop but the positions are never reached, the servo would seem to act erratically or maybe not at all. Before getting concerned thinking that you have burnt out the motor, make the wait longer and if there is no wait put one in. Note: When controlling the motors in threads for an RTOS, don't use the wait(); function because this stops the processor. The Thread::wait(); function should be used to give the servo the time it needs to reach a position.


No comments:

Post a Comment