A simple library for driving RC servos without using the mbed's PWM functions. This allows the mbed to drive as many servos as there are DigitalOut pins, and additionally allows for the PWM functions to be used at a different frequency than the 50Hz used for servos.

Servo.cpp

Committer:
UCSBRobotics
Date:
2012-08-03
Revision:
5:94cdc85bf1ae
Parent:
2:19f995979c6a
Child:
6:6af888a91e23

File content as of revision 5:94cdc85bf1ae:

#include "Servo.h"
#include "mbed.h"


// The next line determines the maximum number of servo objects 
// that can be successfully created.
// By default, this is set to 26, as there are only 26 unique 
// DigitalOut pins provided by the mbed.
Servo *Servo::servos[26];
unsigned int Servo::numServos = 0;
Ticker Servo::refreshTicker;



// The pin must be specified when the object is initialized, but 
// the initial pulse width can be omitted, giving a default of 
// 1500 us. 
// This should be at about half the range of most servos.
Servo::Servo(PinName pin, unsigned int width) : signalPin(pin)
{
    pulseWidth = width;
    
    if (numServos == 0)
    {
        // Start the timeout that refreshes all servos
        refreshTicker.attach_us(&Servo::refresh, period);
    }
    
    servos[numServos++] = this;
}



void Servo::write(int width)
{
    // Make sure that the pulse width is less than the refresh period
    pulseWidth = width < period ? width : period;
}



int Servo::read()
{
    return pulseWidth;
}



void Servo::operator=(int width)
{
    write(width);
}



Servo::operator int()
{
    return read();
}



void Servo::refresh()
{
    // Restart the refresh timeout
    refreshTicker.attach_us(&Servo::refresh, period);
    
    // Start all of the individual servo width timeouts and write a logical 1 to their signal pins
    for (int i = 0; i < numServos; i++)
    {
        servos[i]->servoTimeout.attach_us(servos[i], &Servo::timeout, servos[i]->pulseWidth);
        Servo::servos[i]->signalPin.write(1);
    }
}



void Servo::timeout()
{
    // Write a logical zero to the servo's signal pin
    signalPin = 0;
}