Library for using the TLC5940 as a servo controller.
TLC5940Servo.h@5:56daa8c0697d, 2014-10-21 (annotated)
- Committer:
- dudanian
- Date:
- Tue Oct 21 06:26:25 2014 +0000
- Revision:
- 5:56daa8c0697d
- Parent:
- 4:95305d4b0544
- Child:
- 6:b001282e967b
Added mbed official docs for the Server inner class as well as support for the position(float degrees) function from the official mbed class.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
dudanian | 0:9fc434ff7a03 | 1 | #ifndef TLC5940Servo_H |
dudanian | 0:9fc434ff7a03 | 2 | #define TLC5940Servo_H |
dudanian | 0:9fc434ff7a03 | 3 | |
dudanian | 0:9fc434ff7a03 | 4 | #include "FastPWM.h" |
dudanian | 2:1d2251574d35 | 5 | |
dudanian | 0:9fc434ff7a03 | 6 | /** |
dudanian | 0:9fc434ff7a03 | 7 | * SPI speed used by the mbed to communicate with the TLC5940 |
dudanian | 0:9fc434ff7a03 | 8 | * The TLC5940 supports up to 30Mhz. This should be kept as high |
dudanian | 0:9fc434ff7a03 | 9 | * as possible to ensure that data has time to be sent each reset cycle. |
dudanian | 0:9fc434ff7a03 | 10 | */ |
dudanian | 0:9fc434ff7a03 | 11 | #define SPI_SPEED 30000000 |
dudanian | 0:9fc434ff7a03 | 12 | |
dudanian | 0:9fc434ff7a03 | 13 | /** |
dudanian | 0:9fc434ff7a03 | 14 | * The rate at which the GSCLK pin is pulsed |
dudanian | 0:9fc434ff7a03 | 15 | * This also controls how often the reset function is called |
dudanian | 0:9fc434ff7a03 | 16 | * The rate at which the reset function is called can be calculated by: (1/GSCLK_SPEED) * 4096 |
dudanian | 2:1d2251574d35 | 17 | * |
dudanian | 2:1d2251574d35 | 18 | * Since the Servo period is 20ms (50Hz), we set this clock to 50*4096 = 204,800Hz according to the equation above |
dudanian | 2:1d2251574d35 | 19 | * Also, since this clock is so slow, there is almost no limit to the number of TLC5940s you can chain |
dudanian | 0:9fc434ff7a03 | 20 | */ |
dudanian | 0:9fc434ff7a03 | 21 | #define GSCLK_SPEED 204800 |
dudanian | 0:9fc434ff7a03 | 22 | |
dudanian | 0:9fc434ff7a03 | 23 | /** |
dudanian | 2:1d2251574d35 | 24 | * This class controls a TLC5940 PWM driver to control Servo motors. It supports sending grayscale PWM data calibrated for Servos, |
dudanian | 2:1d2251574d35 | 25 | * but it does not support error checking or writing the EEPROM. After 4096 pulses, the private member funciton reset is called by |
dudanian | 2:1d2251574d35 | 26 | * 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 |
dudanian | 2:1d2251574d35 | 27 | * is sent here. |
dudanian | 2:1d2251574d35 | 28 | * |
dudanian | 2:1d2251574d35 | 29 | * This class is a heavily modified versoin of the TLC5940 library created by Spencer Davis. This class also uses the FastPWM |
dudanian | 2:1d2251574d35 | 30 | * library by Erik Olieman to continuously pulse the GSLCK pin without CPU intervention. |
dudanian | 0:9fc434ff7a03 | 31 | */ |
dudanian | 2:1d2251574d35 | 32 | class TLC5940Servo { |
dudanian | 0:9fc434ff7a03 | 33 | public: |
dudanian | 2:1d2251574d35 | 34 | /* |
dudanian | 2:1d2251574d35 | 35 | * Servo inner class to abstract some of the details. Based off of the mbed official Servo class |
dudanian | 2:1d2251574d35 | 36 | */ |
dudanian | 2:1d2251574d35 | 37 | class Servo { |
dudanian | 2:1d2251574d35 | 38 | public: |
dudanian | 5:56daa8c0697d | 39 | /** |
dudanian | 5:56daa8c0697d | 40 | * Creat a servo object NOT connected to a specific PwmOut pin |
dudanian | 5:56daa8c0697d | 41 | */ |
dudanian | 2:1d2251574d35 | 42 | Servo(); |
dudanian | 5:56daa8c0697d | 43 | |
dudanian | 4:95305d4b0544 | 44 | /** |
dudanian | 4:95305d4b0544 | 45 | * Set the servo position, normalised to it's full range |
dudanian | 4:95305d4b0544 | 46 | * |
dudanian | 4:95305d4b0544 | 47 | * @param percent A normalised number 0.0-1.0 to represent the full range. |
dudanian | 4:95305d4b0544 | 48 | */ |
dudanian | 2:1d2251574d35 | 49 | void write(float percent); |
dudanian | 5:56daa8c0697d | 50 | |
dudanian | 5:56daa8c0697d | 51 | /** |
dudanian | 5:56daa8c0697d | 52 | * Read the servo motors current position |
dudanian | 5:56daa8c0697d | 53 | * |
dudanian | 5:56daa8c0697d | 54 | * @param returns A normalised number 0.0-1.0 representing the full range. |
dudanian | 5:56daa8c0697d | 55 | */ |
dudanian | 2:1d2251574d35 | 56 | float read(); |
dudanian | 5:56daa8c0697d | 57 | |
dudanian | 5:56daa8c0697d | 58 | /** |
dudanian | 5:56daa8c0697d | 59 | * Set the servo position |
dudanian | 5:56daa8c0697d | 60 | * |
dudanian | 5:56daa8c0697d | 61 | * @param degrees Servo position in degrees |
dudanian | 5:56daa8c0697d | 62 | */ |
dudanian | 5:56daa8c0697d | 63 | void position(float degrees); |
dudanian | 5:56daa8c0697d | 64 | |
dudanian | 5:56daa8c0697d | 65 | /** |
dudanian | 5:56daa8c0697d | 66 | * Allows calibration of the range and angles for a particular servo |
dudanian | 5:56daa8c0697d | 67 | * |
dudanian | 5:56daa8c0697d | 68 | * @param range Pulsewidth range from center (1.5ms) to maximum/minimum position in seconds |
dudanian | 5:56daa8c0697d | 69 | * @param degrees Angle from centre to maximum/minimum position in degrees |
dudanian | 5:56daa8c0697d | 70 | */ |
dudanian | 5:56daa8c0697d | 71 | void calibrate(float range=0.0005, float degrees=45.0); |
dudanian | 5:56daa8c0697d | 72 | |
dudanian | 5:56daa8c0697d | 73 | /** |
dudanian | 5:56daa8c0697d | 74 | * Read the servo motors current TLC5940 pw value |
dudanian | 5:56daa8c0697d | 75 | */ |
dudanian | 2:1d2251574d35 | 76 | int pulsewidth(); |
dudanian | 5:56daa8c0697d | 77 | |
dudanian | 5:56daa8c0697d | 78 | /** Shorthand for the write and read functions */ |
dudanian | 2:1d2251574d35 | 79 | Servo& operator= (float percent); |
dudanian | 5:56daa8c0697d | 80 | Servo& operator= (Servo& rhs); |
dudanian | 2:1d2251574d35 | 81 | operator float(); |
dudanian | 2:1d2251574d35 | 82 | private: |
dudanian | 2:1d2251574d35 | 83 | float _range; |
dudanian | 2:1d2251574d35 | 84 | float _degrees; |
dudanian | 5:56daa8c0697d | 85 | float _p; |
dudanian | 2:1d2251574d35 | 86 | int _pw; |
dudanian | 2:1d2251574d35 | 87 | }; |
dudanian | 5:56daa8c0697d | 88 | |
dudanian | 0:9fc434ff7a03 | 89 | /** |
dudanian | 2:1d2251574d35 | 90 | * Set up the TLC5940 |
dudanian | 2:1d2251574d35 | 91 | * |
dudanian | 2:1d2251574d35 | 92 | * @param MOSI - The MOSI pin of the SPI bus |
dudanian | 2:1d2251574d35 | 93 | * @param SCLK - The SCK pin of the SPI bus |
dudanian | 2:1d2251574d35 | 94 | * @param XLAT - The XLAT pin of the TLC5940(s) |
dudanian | 2:1d2251574d35 | 95 | * @param BLANK - The BLANK pin of the TLC5940(s) |
dudanian | 2:1d2251574d35 | 96 | * @param GSCLK - The GSCLK pin of the TLC5940(s) |
dudanian | 2:1d2251574d35 | 97 | * @param number - The number of TLC5940s (optional) |
dudanian | 0:9fc434ff7a03 | 98 | */ |
dudanian | 0:9fc434ff7a03 | 99 | TLC5940Servo(PinName MOSI, PinName SCLK, PinName XLAT, PinName BLANK, |
dudanian | 2:1d2251574d35 | 100 | PinName GSCLK, const int number = 1); |
dudanian | 2:1d2251574d35 | 101 | |
dudanian | 2:1d2251574d35 | 102 | /** |
dudanian | 2:1d2251574d35 | 103 | * Destructor used to delete memory |
dudanian | 2:1d2251574d35 | 104 | */ |
dudanian | 0:9fc434ff7a03 | 105 | ~TLC5940Servo(); |
dudanian | 0:9fc434ff7a03 | 106 | |
dudanian | 2:1d2251574d35 | 107 | /** |
dudanian | 2:1d2251574d35 | 108 | * Allows calibration of the range and angles for a particular servo |
dudanian | 0:9fc434ff7a03 | 109 | * |
dudanian | 0:9fc434ff7a03 | 110 | * @param range Pulsewidth range from center (1.5ms) to maximum/minimum position in seconds |
dudanian | 0:9fc434ff7a03 | 111 | * @param degrees Angle from centre to maximum/minimum position in degrees |
dudanian | 0:9fc434ff7a03 | 112 | */ |
dudanian | 0:9fc434ff7a03 | 113 | void calibrate(int index, float range, float degrees); |
dudanian | 2:1d2251574d35 | 114 | |
dudanian | 2:1d2251574d35 | 115 | /** |
dudanian | 2:1d2251574d35 | 116 | * Allows calibration of the range and angles for all servos |
dudanian | 0:9fc434ff7a03 | 117 | * |
dudanian | 0:9fc434ff7a03 | 118 | * @param range Pulsewidth range from center (1.5ms) to maximum/minimum position in seconds |
dudanian | 0:9fc434ff7a03 | 119 | * @param degrees Angle from centre to maximum/minimum position in degrees |
dudanian | 0:9fc434ff7a03 | 120 | */ |
dudanian | 2:1d2251574d35 | 121 | void calibrate(float range, float degrees); |
dudanian | 2:1d2251574d35 | 122 | |
dudanian | 0:9fc434ff7a03 | 123 | /** |
dudanian | 2:1d2251574d35 | 124 | * Array index operator for reading and writing from servos |
dudanian | 2:1d2251574d35 | 125 | * |
dudanian | 2:1d2251574d35 | 126 | * @param index Index of Servo in array |
dudanian | 0:9fc434ff7a03 | 127 | */ |
dudanian | 2:1d2251574d35 | 128 | Servo& operator[](int index); |
dudanian | 0:9fc434ff7a03 | 129 | |
dudanian | 0:9fc434ff7a03 | 130 | private: |
dudanian | 0:9fc434ff7a03 | 131 | // SPI port - only MOSI and SCK are used |
dudanian | 0:9fc434ff7a03 | 132 | SPI spi; |
dudanian | 0:9fc434ff7a03 | 133 | |
dudanian | 0:9fc434ff7a03 | 134 | // PWM output using the FastPWM library by Erik Olieman |
dudanian | 0:9fc434ff7a03 | 135 | FastPWM gsclk; |
dudanian | 0:9fc434ff7a03 | 136 | |
dudanian | 0:9fc434ff7a03 | 137 | // Digital out pins used for the TLC5940 |
dudanian | 0:9fc434ff7a03 | 138 | DigitalOut blank; |
dudanian | 0:9fc434ff7a03 | 139 | DigitalOut xlat; |
dudanian | 0:9fc434ff7a03 | 140 | |
dudanian | 0:9fc434ff7a03 | 141 | // Number of TLC5940s in series |
dudanian | 0:9fc434ff7a03 | 142 | const int number; |
dudanian | 0:9fc434ff7a03 | 143 | |
dudanian | 0:9fc434ff7a03 | 144 | // Call a reset function to manage sending data and GSCLK updating |
dudanian | 0:9fc434ff7a03 | 145 | Ticker reset_ticker; |
dudanian | 0:9fc434ff7a03 | 146 | |
dudanian | 0:9fc434ff7a03 | 147 | // Has new data been loaded? |
dudanian | 0:9fc434ff7a03 | 148 | volatile bool newData; |
dudanian | 0:9fc434ff7a03 | 149 | |
dudanian | 0:9fc434ff7a03 | 150 | // Do we need to send an XLAT pulse? (Was GS data clocked in last reset?) |
dudanian | 0:9fc434ff7a03 | 151 | volatile bool need_xlat; |
dudanian | 0:9fc434ff7a03 | 152 | |
dudanian | 0:9fc434ff7a03 | 153 | // Buffers to store data until it is sent |
dudanian | 3:3b04a122e508 | 154 | Servo* servos; |
dudanian | 0:9fc434ff7a03 | 155 | |
dudanian | 0:9fc434ff7a03 | 156 | // Function to reset the display and send the next chunks of data |
dudanian | 0:9fc434ff7a03 | 157 | void reset(); |
dudanian | 0:9fc434ff7a03 | 158 | }; |
dudanian | 0:9fc434ff7a03 | 159 | |
dudanian | 0:9fc434ff7a03 | 160 | #endif |