Servo module reference#include <Servo.h>Makefile :
MODULES+=tc UTILS_MODULES+=Servo
This class is a shallow layer above the TC module which makes controlling servomotors easier.
Each servo output uses a TC channel to generate the PWM output. This channel must not be used for other purposes. See the TC module reference for more information on TC channels.
When using servos, be careful about the way you power them. The 3.3V output is too low for most servos to operate properly, and is limited to 300mA, which is easily reached except maybe by the smallest servos with no load. If a battery is plugged in and properly charged, Vbat might provide enough voltage and current for small to medium servos. The best solution is to power the servo externally, such as from an RC BEC circuit which is designed for this exact purpose and easily available in the same stores as the servos themselves.
pin is given, GPIO::setPin() is called to set the pin used by this channel, otherwise the default pin is used (see the Pin muxing tutorial).This class is extremely simple and the PWM format used to control servomotors is fairly straightforward, there isn't much room for customization.
#ifndef _SERVO_H_
#define _SERVO_H_
#include <tc.h>
#include <gpio.h>
// This class is a shallow helper to use a TC channel as a PWM generator to control a servomotor
class Servo {
private:
TC::Channel _tcChannel;
GPIO::Pin _pin;
unsigned int _period;
unsigned int _highTime0;
unsigned int _highTime100;
unsigned int _percent;
bool _disabled;
static const unsigned int DEFAULT_PERIOD = 10000;
static const unsigned int DEFAULT_HIGH_TIME_0 = 1000;
static const unsigned int DEFAULT_HIGH_TIME_100 = 2000;
public:
// Constructor : must specify the underlying TC channel to use
Servo(TC::Channel tcChannel, GPIO::Pin pin={GPIO::Port::A, 0xFF});
// Set the servo position in percent
// This will translate to differant angles according to the exact servo angular range
void set(unsigned int percent);
void disable();
// Customize the PWM timings
// Passing no argument resets the default values
void setPWMTimings(unsigned int highTime0=DEFAULT_HIGH_TIME_0, unsigned int highTime100=DEFAULT_HIGH_TIME_100, unsigned int period=DEFAULT_PERIOD);
};
#endif
#include "Servo.h"
// Constructor : must specify the underlying TC channel to use
Servo::Servo(TC::Channel tcChannel, GPIO::Pin pin) {
// Save the parameters
_tcChannel = tcChannel;
_pin = pin;
// Default values
_percent = 50;
_disabled = true;
// If a custom pin is specified, set it
if (pin.number != 0xFF) {
TC::setPin(tcChannel, TC::PinFunction::OUT, pin);
}
// Initialize the TC channel to output the PWM signal
TC::init(tcChannel, DEFAULT_PERIOD, 0, true);
// Set default timings
setPWMTimings();
}
// Set the servo position in percent
// This will translate to different angles according to the angular range of the servo
void Servo::set(unsigned int percent) {
// Check value
if (percent > 100) {
percent = 100;
}
// Save the value
_disabled = false;
_percent = percent;
// Compute and set the hightime
TC::setHighTime(_tcChannel, _highTime0 + percent * (_highTime100 - _highTime0) / 100);
}
void Servo::disable() {
_disabled = true;
TC::setHighTime(_tcChannel, 0);
}
// Customize the PWM timings
// Passing no argument resets the default values
void Servo::setPWMTimings(unsigned int highTime0, unsigned int highTime100, unsigned int period) {
// Save the timings
_highTime0 = highTime0;
_highTime100 = highTime100;
_period = period;
// Reset the high time
TC::setHighTime(_tcChannel, 0);
// Set the period
TC::setPeriod(_tcChannel, period);
// Recalculate the hightime based on the new timings
if (!_disabled) {
set(_percent);
}
}