Library for the WS2812 LED Driver. Uses bit banging and nops for precise timing. Number of nops executed are configurable at run time.

Dependents:   WS2812_Example WS2812_Example_fade Lamp_03 Lamp_04 ... more

This library uses bit banging to control the LED strip. Because the mbed platform doesn't have a timer standardized that doesn't have a resolution lower a microsecond, we have to use NOPs. Also, the time it takes to toggle a GPIO pin is not consistent across platforms and it does not correlate to the system clock in any way. It is completely dependent on the platform's implementation.

I have a found the timings for a few boards. They are currently listed on the example program page below.

Import programWS2812_Example

Example for WS2812 Library

When using this on a new platform, you'll need to use a logic analyzer to determine the timings.

/media/uploads/bridadan/k64f_ws2812_timing_v2.png

Above is a screenshot from a Saleae logic analyzer. You'll notice that the "1" pulse is longer than the "0" pulse. The "Data low" pulses should be consistent. The timing requirements for these pulses can be found below (Source: http://wp.josh.com/2014/05/13/ws2812-neopixels-are-not-so-finicky-once-you-get-to-know-them/).

/media/uploads/bridadan/ws2812_timings.png

If you find timings for a new board you're using, please PM me or start a discussion below and I'll add it to this page!

For more on the timings and data format of the WS2812 drivers, you should read the datasheet and the article "NeoPixels Revealed: How to (not need to) generate precisely timed signals" listed below.

References:

WS2812B Datasheet: https://www.adafruit.com/datasheets/WS2812B.pdf

"NeoPixels Revealed: How to (not need to) generate precisely timed signals": http://wp.josh.com/2014/05/13/ws2812-neopixels-are-not-so-finicky-once-you-get-to-know-them/

Committer:
bridadan
Date:
Thu Feb 12 20:20:10 2015 +0000
Revision:
1:aadbf08c62a2
Parent:
0:0b79cafcb387
Child:
2:6e647820f587
Updated documentation and cleaned up code

Who changed what in which revision?

UserRevisionLine numberNew contents of line
bridadan 0:0b79cafcb387 1 /* Copyright (c) 2012 cstyles, MIT License
bridadan 0:0b79cafcb387 2 *
bridadan 0:0b79cafcb387 3 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
bridadan 0:0b79cafcb387 4 * and associated documentation files (the "Software"), to deal in the Software without restriction,
bridadan 0:0b79cafcb387 5 * including without limitation the rights to use, copy, modify, merge, publish, distribute,
bridadan 0:0b79cafcb387 6 * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
bridadan 0:0b79cafcb387 7 * furnished to do so, subject to the following conditions:
bridadan 0:0b79cafcb387 8 *
bridadan 0:0b79cafcb387 9 * The above copyright notice and this permission notice shall be included in all copies or
bridadan 0:0b79cafcb387 10 * substantial portions of the Software.
bridadan 0:0b79cafcb387 11 *
bridadan 0:0b79cafcb387 12 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
bridadan 0:0b79cafcb387 13 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
bridadan 0:0b79cafcb387 14 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
bridadan 0:0b79cafcb387 15 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
bridadan 0:0b79cafcb387 16 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
bridadan 0:0b79cafcb387 17 */
bridadan 0:0b79cafcb387 18
bridadan 0:0b79cafcb387 19 #ifndef WS2812_H
bridadan 0:0b79cafcb387 20 #define WS2812_H
bridadan 0:0b79cafcb387 21
bridadan 0:0b79cafcb387 22 #include "mbed.h"
bridadan 0:0b79cafcb387 23
bridadan 0:0b79cafcb387 24 #define FRAME_SIZE 24
bridadan 0:0b79cafcb387 25
bridadan 0:0b79cafcb387 26 //!Library for the WS2812 RGB LED with integrated controller
bridadan 0:0b79cafcb387 27 /*!
bridadan 0:0b79cafcb387 28 The WS2812 is controller that is built into a range of LEDs
bridadan 0:0b79cafcb387 29 */
bridadan 0:0b79cafcb387 30 class WS2812
bridadan 0:0b79cafcb387 31 {
bridadan 0:0b79cafcb387 32 public:
bridadan 1:aadbf08c62a2 33 enum BrightnessControl { OFF, GLOBAL, PER_PIXEL };
bridadan 1:aadbf08c62a2 34
bridadan 1:aadbf08c62a2 35 /**
bridadan 1:aadbf08c62a2 36 * Constructor
bridadan 1:aadbf08c62a2 37 *
bridadan 1:aadbf08c62a2 38 * @param pin Output pin. Connect to "Din" on the first WS2812 in the strip
bridadan 1:aadbf08c62a2 39 * @param size Number of LEDs in your strip
bridadan 1:aadbf08c62a2 40 * @param zeroHigh How many NOPs to insert to ensure TOH is properly generated. See library description for more information.
bridadan 1:aadbf08c62a2 41 * @param zeroLow How many NOPs to insert to ensure TOL is properly generated. See library description for more information.
bridadan 1:aadbf08c62a2 42 * @param oneHigh How many NOPs to insert to ensure T1H is properly generated. See library description for more information.
bridadan 1:aadbf08c62a2 43 * @param oneLow How many NOPs to insert to ensure T1L is properly generated. See library description for more information.
bridadan 1:aadbf08c62a2 44 *
bridadan 0:0b79cafcb387 45 */
bridadan 1:aadbf08c62a2 46 WS2812(PinName pin, int size, int zeroHigh, int zeroLow, int oneHigh, int oneLow);
bridadan 0:0b79cafcb387 47
bridadan 0:0b79cafcb387 48 /*!
bridadan 0:0b79cafcb387 49 Destroys instance.
bridadan 0:0b79cafcb387 50 */
bridadan 0:0b79cafcb387 51 ~WS2812();
bridadan 0:0b79cafcb387 52
bridadan 1:aadbf08c62a2 53 /**
bridadan 1:aadbf08c62a2 54 * Sets the timing parameters for the bit-banged signal
bridadan 1:aadbf08c62a2 55 *
bridadan 1:aadbf08c62a2 56 * @param zeroHigh How many NOPs to insert to ensure TOH is properly generated. See library description for more information.
bridadan 1:aadbf08c62a2 57 * @param zeroLow How many NOPs to insert to ensure TOL is properly generated. See library description for more information.
bridadan 1:aadbf08c62a2 58 * @param oneHigh How many NOPs to insert to ensure T1H is properly generated. See library description for more information.
bridadan 1:aadbf08c62a2 59 * @param oneLow How many NOPs to insert to ensure T1L is properly generated. See library description for more information.
bridadan 1:aadbf08c62a2 60 *
bridadan 1:aadbf08c62a2 61 */
bridadan 0:0b79cafcb387 62 void setDelays(int zeroHigh, int zeroLow, int oneHigh, int oneLow);
bridadan 0:0b79cafcb387 63
bridadan 1:aadbf08c62a2 64 /**
bridadan 1:aadbf08c62a2 65 * Sets the timing parameters for the bit-banged signal
bridadan 1:aadbf08c62a2 66 *
bridadan 1:aadbf08c62a2 67 * @param buf Pointer to the PixelArray buffer
bridadan 1:aadbf08c62a2 68 * @param r_offset The offset where each each pixel pulls its red component. Wraps to beginning if end is reached.
bridadan 1:aadbf08c62a2 69 * @param g_offset The offset where each each pixel pulls its green component. Wraps to beginning if end is reached.
bridadan 1:aadbf08c62a2 70 * @param b_offset The offset where each each pixel pulls its blue component. Wraps to beginning if end is reached.
bridadan 1:aadbf08c62a2 71 *
bridadan 1:aadbf08c62a2 72 */
bridadan 1:aadbf08c62a2 73 void write_offsets(int buf[], int r_offset = 0, int g_offset = 0, int b_offset = 0);
bridadan 1:aadbf08c62a2 74
bridadan 1:aadbf08c62a2 75
bridadan 1:aadbf08c62a2 76 /**
bridadan 1:aadbf08c62a2 77 * Write the given buffer to the LED strip
bridadan 1:aadbf08c62a2 78 *
bridadan 1:aadbf08c62a2 79 * @param buf Pointer to the PixelArray buffer
bridadan 1:aadbf08c62a2 80 *
bridadan 1:aadbf08c62a2 81 */
bridadan 0:0b79cafcb387 82 void write(int buf[]);
bridadan 1:aadbf08c62a2 83
bridadan 1:aadbf08c62a2 84 /**
bridadan 1:aadbf08c62a2 85 * Sets the brightness mode
bridadan 1:aadbf08c62a2 86 *
bridadan 1:aadbf08c62a2 87 * @param bc The brightness control. Defaults to OFF. Possible values include OFF, GLOBAL, and PER_PIXEL
bridadan 1:aadbf08c62a2 88 *
bridadan 1:aadbf08c62a2 89 */
bridadan 1:aadbf08c62a2 90 void useII(BrightnessControl bc);
bridadan 1:aadbf08c62a2 91
bridadan 1:aadbf08c62a2 92 /**
bridadan 1:aadbf08c62a2 93 * Sets the global brightness level.
bridadan 1:aadbf08c62a2 94 *
bridadan 1:aadbf08c62a2 95 * @param II The brightness level. Possible values include 0 - 255 (0x00 - 0xFF).
bridadan 1:aadbf08c62a2 96 *
bridadan 1:aadbf08c62a2 97 */
bridadan 0:0b79cafcb387 98 void setII(unsigned char II);
bridadan 0:0b79cafcb387 99
bridadan 0:0b79cafcb387 100
bridadan 0:0b79cafcb387 101
bridadan 0:0b79cafcb387 102 private:
bridadan 0:0b79cafcb387 103
bridadan 0:0b79cafcb387 104 int __size;
bridadan 0:0b79cafcb387 105 int __zeroHigh, __zeroLow, __oneHigh, __oneLow;
bridadan 0:0b79cafcb387 106 unsigned char __II;
bridadan 1:aadbf08c62a2 107 BrightnessControl __use_II;
bridadan 0:0b79cafcb387 108 bool *__transmitBuf;
bridadan 0:0b79cafcb387 109 void __loadBuf(int buf[],int r_offset=0, int g_offset=0, int b_offset=0);
bridadan 0:0b79cafcb387 110 PinName __outPin;
bridadan 0:0b79cafcb387 111 DigitalOut __gpo;
bridadan 0:0b79cafcb387 112 };
bridadan 0:0b79cafcb387 113
bridadan 0:0b79cafcb387 114 #endif