Library for using the TLC5940 as a servo controller.
TLC5940Servo.h
- Committer:
- dudanian
- Date:
- 2014-10-21
- Revision:
- 6:b001282e967b
- Parent:
- 5:56daa8c0697d
File content as of revision 6:b001282e967b:
#ifndef TLC5940Servo_H #define TLC5940Servo_H #include "FastPWM.h" /** * SPI speed used by the mbed to communicate with the TLC5940 * The TLC5940 supports up to 30Mhz. This should be kept as high * as possible to ensure that data has time to be sent each reset cycle. */ #define SPI_SPEED 30000000 /** * The rate at which the GSCLK pin is pulsed * This also controls how often the reset function is called * The rate at which the reset function is called can be calculated by: (1/GSCLK_SPEED) * 4096 * * Since the Servo period is 20ms (50Hz), we set this clock to 50*4096 = 204,800Hz according to the equation above * Also, since this clock is so slow, there is almost no limit to the number of TLC5940s you can chain */ #define GSCLK_SPEED 204800 /** * This class controls a TLC5940 PWM driver to control Servo motors. It supports sending grayscale PWM data calibrated for Servos, * but it does not support error checking or writing the EEPROM. After 4096 pulses, the private member funciton reset is called by * the ticker. It resets the driver by pulsing the BLANK pin. If new data has been set to be sent by the function setNewData, it * is sent here. * * This class is a heavily modified versoin of the TLC5940 library created by Spencer Davis. This class also uses the FastPWM * library by Erik Olieman to continuously pulse the GSLCK pin without CPU intervention. */ class TLC5940Servo { public: /* * Servo inner class to abstract some of the details. Based off of the mbed official Servo class */ class Servo { public: /** * Creat a servo object NOT connected to a specific PwmOut pin */ Servo(); /** * Set the servo position, normalised to it's full range * * @param percent A normalised number 0.0-1.0 to represent the full range. */ void write(float percent); /** * Read the servo motors current position * * @param returns A normalised number 0.0-1.0 representing the full range. */ float read(); /** * Set the servo position * * @param degrees Servo position in degrees */ void position(float degrees); /** * Allows calibration of the range and angles for a particular servo * * @param range Pulsewidth range from center (1.5ms) to maximum/minimum position in seconds * @param degrees Angle from centre to maximum/minimum position in degrees */ void calibrate(float range=0.0005, float degrees=45.0); /** * Read the servo motors current TLC5940 pw value */ int pulsewidth(); /** Shorthand for the write and read functions */ Servo& operator= (float percent); Servo& operator= (Servo& rhs); operator float(); private: float _range; float _degrees; float _p; int _pw; }; /** * Set up the TLC5940 * * @param MOSI - The MOSI pin of the SPI bus * @param SCLK - The SCK pin of the SPI bus * @param XLAT - The XLAT pin of the TLC5940(s) * @param BLANK - The BLANK pin of the TLC5940(s) * @param GSCLK - The GSCLK pin of the TLC5940(s) * @param number - The number of TLC5940s (optional) */ TLC5940Servo(PinName MOSI, PinName SCLK, PinName XLAT, PinName BLANK, PinName GSCLK, const int number = 1); /** * Destructor used to delete memory */ ~TLC5940Servo(); /** * Allows calibration of the range and angles for all servos * * @param range Pulsewidth range from center (1.5ms) to maximum/minimum position in seconds * @param degrees Angle from centre to maximum/minimum position in degrees */ void calibrate(float range, float degrees); /** * Array index operator for reading and writing from servos * * @param index Index of Servo in array */ Servo& operator[](int index); private: // SPI port - only MOSI and SCK are used SPI spi; // PWM output using the FastPWM library by Erik Olieman FastPWM gsclk; // Digital out pins used for the TLC5940 DigitalOut blank; DigitalOut xlat; // Number of TLC5940s in series const int number; // Call a reset function to manage sending data and GSCLK updating Ticker reset_ticker; // Has new data been loaded? volatile bool newData; // Do we need to send an XLAT pulse? (Was GS data clocked in last reset?) volatile bool need_xlat; // Buffers to store data until it is sent Servo* servos; // Function to reset the display and send the next chunks of data void reset(); }; #endif