Andrew Duda / TLC5940Servo

Dependencies:   FastPWM

Dependents:   TLC5940ServoTest

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers TLC5940Servo.h Source File

TLC5940Servo.h

00001 #ifndef TLC5940Servo_H
00002 #define TLC5940Servo_H
00003 
00004 #include "FastPWM.h"
00005 
00006 /**
00007   * SPI speed used by the mbed to communicate with the TLC5940
00008   * The TLC5940 supports up to 30Mhz. This should be kept as high
00009   * as possible to ensure that data has time to be sent each reset cycle.
00010   */
00011 #define SPI_SPEED 30000000
00012 
00013 /**
00014   * The rate at which the GSCLK pin is pulsed
00015   * This also controls how often the reset function is called
00016   * The rate at which the reset function is called can be calculated by: (1/GSCLK_SPEED) * 4096
00017   *
00018   * Since the Servo period is 20ms (50Hz), we set this clock to 50*4096 = 204,800Hz according to the equation above
00019   * Also, since this clock is so slow, there is almost no limit to the number of TLC5940s you can chain
00020   */
00021 #define GSCLK_SPEED 204800
00022 
00023 /**
00024   *  This class controls a TLC5940 PWM driver to control Servo motors. It supports sending grayscale PWM data calibrated for Servos,
00025   *  but it does not support error checking or writing the EEPROM. After 4096 pulses, the private member funciton reset is called by
00026   *  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
00027   *  is sent here.
00028   *  
00029   *  This class is a heavily modified versoin of the TLC5940 library created by Spencer Davis. This class also uses the FastPWM
00030   *  library by Erik Olieman to continuously pulse the GSLCK pin without CPU intervention. 
00031   */
00032 class TLC5940Servo {
00033 public:
00034     /* 
00035      * Servo inner class to abstract some of the details. Based off of the mbed official Servo class
00036      */
00037     class Servo {
00038     public:
00039         /**
00040          * Creat a servo object NOT connected to a specific PwmOut pin
00041          */
00042         Servo();
00043 
00044         /** 
00045          * Set the servo position, normalised to it's full range
00046          *
00047          * @param percent A normalised number 0.0-1.0 to represent the full range.
00048          */
00049         void write(float percent);
00050 
00051         /**  
00052          * Read the servo motors current position
00053          *
00054          * @param returns A normalised number 0.0-1.0  representing the full range.
00055          */
00056         float read();
00057         
00058         /** 
00059          * Set the servo position
00060          *
00061          * @param degrees Servo position in degrees
00062          */
00063         void position(float degrees);
00064     
00065         /**
00066          * Allows calibration of the range and angles for a particular servo
00067          *
00068          * @param range Pulsewidth range from center (1.5ms) to maximum/minimum position in seconds
00069          * @param degrees Angle from centre to maximum/minimum position in degrees
00070          */
00071         void calibrate(float range=0.0005, float degrees=45.0);
00072         
00073         /**
00074          * Read the servo motors current TLC5940 pw value
00075          */
00076         int pulsewidth();
00077         
00078         /**  Shorthand for the write and read functions */
00079         Servo& operator= (float percent);
00080         Servo& operator= (Servo& rhs);
00081         operator float();
00082     private:
00083         float _range;
00084         float _degrees;
00085         float _p;
00086         int _pw;
00087     };
00088 
00089     /**
00090       * Set up the TLC5940
00091       *
00092       * @param MOSI - The MOSI pin of the SPI bus
00093       * @param SCLK - The SCK pin of the SPI bus
00094       * @param XLAT - The XLAT pin of the TLC5940(s)
00095       * @param BLANK - The BLANK pin of the TLC5940(s)
00096       * @param GSCLK - The GSCLK pin of the TLC5940(s)
00097       * @param number - The number of TLC5940s (optional)
00098       */
00099     TLC5940Servo(PinName MOSI, PinName SCLK, PinName XLAT, PinName BLANK,
00100                  PinName GSCLK, const int number = 1);
00101 
00102     /**
00103      * Destructor used to delete memory
00104      */
00105     ~TLC5940Servo();
00106 
00107     /**
00108      * Allows calibration of the range and angles for all servos
00109      *
00110      * @param range Pulsewidth range from center (1.5ms) to maximum/minimum position in seconds
00111      * @param degrees Angle from centre to maximum/minimum position in degrees
00112      */
00113     void calibrate(float range, float degrees);
00114 
00115     /**
00116       * Array index operator for reading and writing from servos
00117       *
00118       * @param index Index of Servo in array
00119       */
00120     Servo& operator[](int index);
00121 
00122 private:
00123     // SPI port - only MOSI and SCK are used
00124     SPI spi;
00125 
00126     // PWM output using the FastPWM library by Erik Olieman
00127     FastPWM gsclk;
00128 
00129     // Digital out pins used for the TLC5940
00130     DigitalOut blank;
00131     DigitalOut xlat;
00132 
00133     // Number of TLC5940s in series
00134     const int number;
00135 
00136     // Call a reset function to manage sending data and GSCLK updating
00137     Ticker reset_ticker;
00138 
00139     // Has new data been loaded?
00140     volatile bool newData;
00141 
00142     // Do we need to send an XLAT pulse? (Was GS data clocked in last reset?)
00143     volatile bool need_xlat;
00144 
00145     // Buffers to store data until it is sent
00146     Servo* servos;
00147 
00148     // Function to reset the display and send the next chunks of data
00149     void reset();
00150 };
00151 
00152 #endif