FastLED with RGBW NeoPixels (SK6812)

Last fall when I was working on the now-defunct ‘Footwell NeoPixels’ project I wrote a short post talking the fact that you cannot use the FastLED library with RGBW leds, and have to deal with the clunkier Adafruit NeoPixels library.

Well last week, a man named Jim Bumgardner commented on that post and shared his method for doing just that: using the FastLED library with RGBW leds.

Preface

Before we get started, you should know one thing: this is a hackIt is not a supported part of the library, it only works with SK6812 leds (that I’m aware of), and it does not work perfectly. But, it does work!

Daniel Garcia and the rest of the FastLED team have said that they are working on an RGBW upgrade behind the scenes, but they have no time table for when it will be completed. In the meantime, this is a quick and dirty fix.

The Hack

This hack works by exploiting the fact that WS2812B LEDs and SK6812 LEDs have similar data timing. It’s not identical, but it’s close enough to make this work. The trick is to tell FastLED that we’re writing to a WS2812B strip, but insert an extra ‘white’ byte between each RGB group.

To do this, we create a special ‘CRGBW’ struct that adds the extra byte, and a few helper functions to integrate with FastLED. I rewrote Jim’s code a bit so the assignment methods more closely match their FastLED counterparts, and I also added an operator overwrite so you can assign CRGB colors directly. Here’s the code, in full:

Download and save this file as “FastLED_RGBW.h”, and place it the same folder as your sketch. Then include it in your sketch by typing:

When defining the LED array, we also need a CRGB pointer to send to the  addLEDs function. We do this like so:

Lastly, when we create the FastLED controller we need to inflate the number of LEDs to account for the extra bytes. The header file has a helper function for this, named getRGBWsize . The function takes the number of RGBW LEDs as an argument and returns the number of CRGB elements that cover that many bytes.

Now when we create the FastLED controller in the setup  function, we use both the CRGB pointer and the size function:

Once the strip is set up, you can set LED colors just like you would normally:

Example Sketch

Here is a basic example sketch that works with SK6812 strips. It does a color wipe for each channel (red, green, blue, and white), then does a rainbow pattern for a 5 seconds and repeats.

Limitations

FastLED is a huge library, and unfortunately not all of its helper functions work with this hack. From my testing, while the basic features of the library work the more advanced ones do not. For instance – while non-desctructive brightness works perfectly, the color temperature functions do not work at all.

These problems come down to the additional bytes added by the CRGBW struct, in combination with the hard-coded color order. Any function that references the raw array members will be cyclically referencing the wrong color channels.

The other obvious limitation is that this only works with RGBW strips that share protocols already in the FastLED library. SK6812 strips (RGBW NeoPixels) work fine using the WS2812B protocol, but you may need to write your own protocol class if you cannot find one already supported.

Lastly, a not-so-obvious limitation is that for LED byte counts that are not factors of 12, junk data is sent past the defined LED array, causing stray colors to show up on the next LED. This is only an issue if the number of LEDs in the code is less than the number of physical LEDs. You can also get around this by defining the CRGBW array as one element larger than necessary, and leaving those last four bytes at 0.

Conclusion

This is mostly a proof of concept, rather than a turn-key solution. But if you have some color patterns generated using the FastLED library, this will let you use those patterns with RGBW strips until the library properly supports RGBW strips.

A huge thanks to Jim Bumgardner for sharing his method. If you found this post useful, please check out his website at http://krazydad.com/.

6 thoughts on “FastLED with RGBW NeoPixels (SK6812)”

  1. Thanks a lot for your article!
    However the script doesn’t compile and gives me that error:

    sketch\FastLED_RGBW.h:45:64: error: ISO C++ forbids declaration of ‘operator=’ with no type [-fpermissive]

    What could cause the issue?

    1. What compiler are you using? This compiles fine for me using the Arduino IDE (1.8.2).

      Trying adding the keyword ‘void’ between ‘inline’ and ‘operator’ in the header file. That might be an oversight on my part.

      1. I’m using the IDEversion 1.8.5. Declaring it as void helped.

        Now I tried running your demo script, but the LEDs (SK6812 RGBW) do nothing.
        Everything works fine with the Neopixel Library.
        What else could have gone wrong?

        Thanks in advance!

        1. I’m not sure. I just tried using the code above and it works perfectly for me.

          Make sure you have the latest version of FastLED installed, and then check the hardware. My hardware setup for the RGBW strips is an Arduino Uno connected through a 470 Ω resistor, with everything powered directly by USB (only 8 LEDs on my demo board). Check that the voltages are as expected and if you have a logic analyzer or oscilloscope, check the output of the data pin.

          As I said in the post – this is a hack, and the timings between the two strip types are at their min/max limits. If your hardware is different the timings may be off enough to not work at all.

Leave a Reply

Your email address will not be published. Required fields are marked *