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:24:15 2015 +0000
Revision:
2:6e647820f587
Parent:
1:aadbf08c62a2
Updated docs

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 2:6e647820f587 65 * Writes the given buffer to the LED strip with the given offsets.
bridadan 2:6e647820f587 66 * NOTE: This function is timing critical, therefore interrupts are disabled during the transmission section.
bridadan 1:aadbf08c62a2 67 *
bridadan 1:aadbf08c62a2 68 * @param buf Pointer to the PixelArray buffer
bridadan 1:aadbf08c62a2 69 * @param r_offset The offset where each each pixel pulls its red component. Wraps to beginning if end is reached.
bridadan 1:aadbf08c62a2 70 * @param g_offset The offset where each each pixel pulls its green component. Wraps to beginning if end is reached.
bridadan 1:aadbf08c62a2 71 * @param b_offset The offset where each each pixel pulls its blue component. Wraps to beginning if end is reached.
bridadan 1:aadbf08c62a2 72 *
bridadan 1:aadbf08c62a2 73 */
bridadan 1:aadbf08c62a2 74 void write_offsets(int buf[], int r_offset = 0, int g_offset = 0, int b_offset = 0);
bridadan 1:aadbf08c62a2 75
bridadan 1:aadbf08c62a2 76
bridadan 1:aadbf08c62a2 77 /**
bridadan 2:6e647820f587 78 * Writes the given buffer to the LED strip
bridadan 2:6e647820f587 79 * NOTE: This function is timing critical, therefore interrupts are disabled during the transmission section.
bridadan 1:aadbf08c62a2 80 *
bridadan 1:aadbf08c62a2 81 * @param buf Pointer to the PixelArray buffer
bridadan 1:aadbf08c62a2 82 *
bridadan 1:aadbf08c62a2 83 */
bridadan 0:0b79cafcb387 84 void write(int buf[]);
bridadan 1:aadbf08c62a2 85
bridadan 1:aadbf08c62a2 86 /**
bridadan 1:aadbf08c62a2 87 * Sets the brightness mode
bridadan 1:aadbf08c62a2 88 *
bridadan 1:aadbf08c62a2 89 * @param bc The brightness control. Defaults to OFF. Possible values include OFF, GLOBAL, and PER_PIXEL
bridadan 1:aadbf08c62a2 90 *
bridadan 1:aadbf08c62a2 91 */
bridadan 1:aadbf08c62a2 92 void useII(BrightnessControl bc);
bridadan 1:aadbf08c62a2 93
bridadan 1:aadbf08c62a2 94 /**
bridadan 1:aadbf08c62a2 95 * Sets the global brightness level.
bridadan 1:aadbf08c62a2 96 *
bridadan 1:aadbf08c62a2 97 * @param II The brightness level. Possible values include 0 - 255 (0x00 - 0xFF).
bridadan 1:aadbf08c62a2 98 *
bridadan 1:aadbf08c62a2 99 */
bridadan 0:0b79cafcb387 100 void setII(unsigned char II);
bridadan 0:0b79cafcb387 101
bridadan 0:0b79cafcb387 102
bridadan 0:0b79cafcb387 103
bridadan 0:0b79cafcb387 104 private:
bridadan 0:0b79cafcb387 105
bridadan 0:0b79cafcb387 106 int __size;
bridadan 0:0b79cafcb387 107 int __zeroHigh, __zeroLow, __oneHigh, __oneLow;
bridadan 0:0b79cafcb387 108 unsigned char __II;
bridadan 1:aadbf08c62a2 109 BrightnessControl __use_II;
bridadan 0:0b79cafcb387 110 bool *__transmitBuf;
bridadan 0:0b79cafcb387 111 void __loadBuf(int buf[],int r_offset=0, int g_offset=0, int b_offset=0);
bridadan 0:0b79cafcb387 112 PinName __outPin;
bridadan 0:0b79cafcb387 113 DigitalOut __gpo;
bridadan 0:0b79cafcb387 114 };
bridadan 0:0b79cafcb387 115
bridadan 0:0b79cafcb387 116 #endif