Yet another WS2812 driver, uses the BusrtSPI library. Less features than the PixelArray library but I felt like making my own version.
wsDrive.h
00001 #ifndef __wsDrive_h__ 00002 #define __wsDrive_h__ 00003 00004 #include "BurstSPI.h" 00005 00006 /**************************************************************** 00007 * An alternative WS2811/2812 driver using the BusrtSPI library 00008 * Credit for the inspiration goes to Jacob for his pixelArray library 00009 * http://developer.mbed.org/users/JacobBramley/code/PixelArray/ 00010 * 00011 * This version was written mainly to help me understand what was going on 00012 * While the end result is the same the code is completely from scratch. 00013 * 00014 *****************************************************************/ 00015 00016 00017 /** A structure used to hold a single pixel or a pixel colour 00018 * 00019 * Each colour can be set to any value between 0 and 255. 00020 * 0 = off, 255 = full brightness. 00021 * 00022 * Note, lots of LEDs on bright will use a lot of power, make sure your supply can cope. 00023 * 00024 * @param G The green component 00025 * @param R The red component 00026 * @param B The blue component 00027 */ 00028 typedef struct pixelInfo { 00029 unsigned char G; 00030 unsigned char R; 00031 unsigned char B; 00032 } pixelInfo; 00033 00034 typedef struct pixelInfo16 { 00035 int16_t G; 00036 int16_t R; 00037 int16_t B; 00038 } pixelInfo16; 00039 00040 00041 /** Drives a WS2812 LED chain 00042 * 00043 * An alternative WS2811/2812 driver using the BusrtSPI library 00044 * 00045 * Credit for the inspiration goes to Jacob for his pixelArray library 00046 * http://developer.mbed.org/users/JacobBramley/code/PixelArray/ 00047 * 00048 * This version was written mainly to help me understand what was going on and is a little more basic. 00049 * While the end result is muc the same the code is completely from scratch. 00050 * 00051 * BurstSPI is used to generate the timing so support is limited to the parts supported by that library. 00052 * 00053 * Also note that while all 3 SPI pins are specified only the MOSI pin is actually needed and should connect to the data in on the LEDs 00054 * 00055 * Example code to run a single lit led along a chain 00056 * 00057 * @code 00058 * 00059 * #include "mbed.h" 00060 * #include "wsDrive.h" 00061 * 00062 * // update period in ms 00063 * #define updatePeriod 100 00064 * // number of LEDs 00065 * #define chainLen 8 00066 * 00067 * DigitalIn dummy(MOSI,PullDown); // first activate the pulldown on the pin. 00068 * wsDrive ledDriver(MOSI,MISO,CLK); // create the SPI bus. You can normally list the MISO and CLK as NC but some mbed library versions don't like that 00069 * 00070 * // pixel storage buffer 00071 * pixelInfo pixelData[chainLen]; 00072 * 00073 * Timer updateRateTimer; 00074 * 00075 * void blankBuffer(pixelInfo *Ptr) 00076 * { 00077 * memset( (void *)Ptr, 0, chainLen*sizeof(pixelInfo) ); 00078 * } 00079 * 00080 * void setPixel(unsigned int index, pixelInfo *colourToUse) { 00081 * if (index < chainLen) { 00082 * pixelData[index].R = colourToUse->R; 00083 * pixelData[index].G = colourToUse->G; 00084 * pixelData[index].B = colourToUse->B; 00085 * } 00086 * } 00087 * 00088 * void clearPixel(unsigned int index) { 00089 * if (index < chainLen) { 00090 * pixelData[index].R = 0; 00091 * pixelData[index].G = 0; 00092 * pixelData[index].B = 0; 00093 * } 00094 * } 00095 * 00096 * int main () { 00097 * 00098 * int litLed = 0; 00099 * 00100 * pixelInfo colour; 00101 * colour.R = 0x80; 00102 * colour.G = 0x00; 00103 * colour.B = 0x00; 00104 * 00105 * // Tell the driver where the data is stored 00106 * ledDriver.setData(pixelData, chainLen); 00107 * 00108 * // Set the buffer to the pattern we want 00109 * blankBuffer(pixelData); 00110 * setPixel(litLed, &colour); 00111 * 00112 * updateRateTimer.start(); 00113 * while (true) { 00114 * 00115 * ledDriver.sendData(); // send the LED data 00116 * 00117 * // modify the buffer ready for the next update 00118 * clearPixel(litLed); 00119 * litLed++; 00120 * if (litLed == chainLen) 00121 * litLed = 0; 00122 * setPixel(litLed, &colour); 00123 * 00124 * // wait until the correct time since the last update... 00125 * while (updateRateTimer.read_ms() < updatePeriod) { 00126 * } 00127 00128 * updateRateTimer.reset(); 00129 * } 00130 * } 00131 * @endcode 00132 * 00133 * Troubleshooting: 00134 * 00135 * If the LEDs aren't lighting up correctly then check that your power supply is up to the job (or decrease the brightness you are using) 00136 * 00137 * Also check the supply voltage, on paper when running off 5V the WS2812 needs 4V on the data in pin to detect a high. Mbed based boards rarely output much over 3.1V. 00138 * This problem is normally indicated by the very first pattern send on power up being displayed but then no further updates being recieved. Dropping the supply voltage 00139 * to about 4.2 - 4.3 V will normally fix this problem without any meaningful impact on the LED output. 00140 * 00141 */ 00142 class wsDrive : private BurstSPI 00143 { 00144 public: 00145 /** create the driver 00146 */ 00147 wsDrive(PinName mosi, PinName miso, PinName clk); 00148 00149 /** Set the data pointer 00150 00151 Before data can be sent the driver must be given a pointer to the pixel data to use. 00152 Setting this is normally a one time operation unless you want to switch between buffers. 00153 00154 @param dataStart The start of an array of pixelInfo items. This will be sent to the chain in order. 00155 @param dataLen The length of the array. 00156 */ 00157 void setData(pixelInfo *dataStart, uint16_t dataLen); 00158 00159 void setData(pixelInfo16 *dataStart, uint16_t dataLen); 00160 00161 00162 /** Sends the data to the LEDs 00163 * setData() must be called prior to this. 00164 */ 00165 void sendData(); 00166 00167 private: 00168 00169 void sendByte(unsigned char value); 00170 void sendPixel(pixelInfo *pixToSend); 00171 void sendPixel(pixelInfo16 *pixToSend); 00172 00173 pixelInfo *pixArray; 00174 pixelInfo16 *pixArray16; 00175 uint16_t pixelLen; 00176 00177 }; 00178 00179 #endif
Generated on Fri Jul 15 2022 00:11:46 by 1.7.2