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); } }