Yet another WS2812 driver, uses the BusrtSPI library. Less features than the PixelArray library but I felt like making my own version.

Dependencies:   BurstSPI

Dependents:   WS2812Text cylon

An alternative WS2811/2812 (NeoPixel) driver using the BusrtSPI library.

Credit for the inspiration goes to Jacob Bramley for his pixelArray library that can be found here: http://developer.mbed.org/users/JacobBramley/code/PixelArray/

This version was written mainly to help me understand what was going on rather than to overcome any shortcomings in the other library and as such it lacks some features (800kHz only, no callback on each pixel etc...)

Connect the SPI output to the LED data input, other SPI pins are unused.

Note: The voltage thresholds between the LEDs and mbed devices are on paper incompatible. The datasheet for the WS2812 indicated that running at 5V it requires 4V on Din to count it as a high (the threshold is 0.8*the supply voltage). Most mbeds are lucky to output much over 3.1V. In reality things normally work OK but it depends on the mBed and batch to batch variations in the LEDs, I've seen some combinations that start to fail at an LED supply voltage of 4.4V or more. If something odd is going on try dropping the LED power supply voltage, they run fine down to 4V.

Files at this revision

API Documentation at this revision

Comitter:
AndyA
Date:
Tue Nov 22 15:14:42 2016 +0000
Parent:
2:1f20efb81649
Child:
5:6aa3e7de65f9
Commit message:

Changed in this revision

wsDrive.cpp Show annotated file Show diff for this revision Revisions of this file
wsDrive.h Show annotated file Show diff for this revision Revisions of this file
--- a/wsDrive.cpp	Fri Nov 07 09:25:52 2014 +0000
+++ b/wsDrive.cpp	Tue Nov 22 15:14:42 2016 +0000
@@ -6,12 +6,21 @@
     format(12);
     pixArray = NULL;
     pixelLen = 0;
+    pixArray16 = NULL;
 }
 
 void wsDrive::setData(pixelInfo *dataStart, uint16_t dataLen)
 {
     pixArray = dataStart;
     pixelLen = dataLen;
+    pixArray16 = NULL;
+}
+
+void wsDrive::setData(pixelInfo16 *dataStart, uint16_t dataLen)
+{
+    pixArray16 = dataStart;
+    pixelLen = dataLen;
+    pixArray = NULL;
 }
 
 void wsDrive::sendData()
@@ -20,11 +29,16 @@
     format(12);
     setFormat();
 
-
     uint16_t pixIndex = 0;
+    if (pixArray)
     while (pixIndex < pixelLen) {
         sendPixel(pixArray + pixIndex++);
     }  
+    else
+    while (pixIndex < pixelLen) {
+        sendPixel(pixArray16 + pixIndex++);
+    }  
+    
 }
 
 // each bytes sent as two 12 bit messages (3 bits of data per LED bit).
@@ -52,3 +66,11 @@
     sendByte(pixToSend->B);
 }
 
+void wsDrive::sendPixel(pixelInfo16 *pixToSend)
+{
+    sendByte((unsigned char)pixToSend->G);
+    sendByte((unsigned char)pixToSend->R);
+    sendByte((unsigned char)pixToSend->B);
+}
+
+
--- a/wsDrive.h	Fri Nov 07 09:25:52 2014 +0000
+++ b/wsDrive.h	Tue Nov 22 15:14:42 2016 +0000
@@ -31,6 +31,12 @@
     unsigned char B;
 } pixelInfo;
 
+typedef struct pixelInfo16 {
+    int16_t G;
+    int16_t R;
+    int16_t B;
+} pixelInfo16;
+
 
 /** Drives a WS2812 LED chain
 *
@@ -150,6 +156,8 @@
     */
     void setData(pixelInfo *dataStart, uint16_t dataLen);
 
+    void setData(pixelInfo16 *dataStart, uint16_t dataLen);
+
 
     /** Sends the data to the LEDs
     * setData() must be called prior to this.
@@ -160,8 +168,10 @@
 
     void sendByte(unsigned char value);
     void sendPixel(pixelInfo *pixToSend);
+    void sendPixel(pixelInfo16 *pixToSend);
 
     pixelInfo *pixArray;
+    pixelInfo16 *pixArray16;
     uint16_t pixelLen;
 
 };