Advanced Coding

Author Gravatar Image PHILLIP BURGESS

Help! My Arduino servo code stops working when combined with NeoPixels!

Unfortunately the NeoPixel and Servo libraries don’t play nice together; one is dependent on periodically disabling interrupts, the other absolutely requires interrupts. There are a couple of options here:
  • Use a dedicated servo control shield or breakout board, offloading that task from the processor so interrupts are a non-issue.
  • Use a hardware-PWM-based servo library rather than the stock Arduino Servo library. This can provide rock-steady servo timing without interrupts, but can only control a very limited number of servos (2-3), and only on very specific pins. PWMServo appears to handle this…download “Paul’s version 2 library” from that page.

How fast can I refresh a string of (N) pixels?

NeoPixels receive data from a fixed-frequency 800 KHz datastream (except for “V1” Flora pixels, which use 400 KHz). One bit therefore requires 1/800,000 sec — 1.25 microseconds. One pixel requires 24 bits (8 bits each for red, green blue) — 30 microseconds. After the last pixel’s worth of data is issued, the stream must stop for at least 50 microseconds for the new colors to “latch.”

For a strip of 100 pixels, that’s (100 * 30) + 50, or 3,050 microseconds. 1,000,000 / 3,050 = 328 updates per second, approximately.

However…

That’s only the time needed to push the bits down the wire. The actual refresh rate will be something less than this, and can’t be estimated as a single number for all cases. It takes time to process each “frame” of animation. How much time depends on the complexity of the math and the efficiency of the code (for example, floating-point calculations can be relatively slow). The technique above gives a maximum theoretical rate, but that’s just a starting point. Reality in some cases could fall an order of magnitude (or more) below this.

For exploratory benchmarking, you can always write code as if a large number of pixels were present, and time the result. The extra output bits will simply be ignored by the strip (or you can even test with no NeoPixels connected at all).

That won’t do. Now what?

Because NeoPixels use a fixed-frequency clock, options are limited. You can’t switch out for a faster microcontroller and expect substantially different results.

One option is to use a different LED type, such as our LPD8806 strips or WS2801 pixels. These can be driven at higher data rates, though they do have some other tradeoffs with respect to NeoPixels (cost, color resolution and/or pixel density).

Another is to develop your own code for a more capable microcontroller or an FPGA that drives multiple NeoPixel strips in parallel. One such project — OctoWS2811 for the Teensy 3.0 microcontroller — is shown later. This sort of thing is a complex undertaking and not recommended for beginners. And even among more experienced programmers, there’s often an unreasonable over-emphasis on data rates when the real bottlenecks lie elsewhere…don’t dwell on this too much unless you can confirm it’s a problem.

Can I control NeoPixels using (Board X)?

We currently only offer an Arduino library. See the links later for other devices. For anything beyond this, if considering writing your own library, understand that some devices are better suited to the task than others. Read through the timing requirements shown below and determine if the processor or device in question can synthesize a signal meeting those specifications. An 8 MHz AVR can just barely keep up…anything slower may have trouble, though some hardware-specific hacks (like clever use of SPI) might make it possible. In many cases, assembly language is required.

Why not Raspberry Pi?

The Raspberry Pi running Linux is a multitasking system, and control may switch among multiple running programs at any time. As such, it’s impossible to guarantee the strict 800 KHz signal required by NeoPixels. You may be able to fudge it for short intervals, but it’s not something that can be counted upon. This is why we use LPD8806 pixels for the Raspberry Pi light painting demonstration.

Third-Party Libraries

NeoPixel-compatible libraries have been developed for devices beyond Arduino. Please keep in mind that Adafruit did not develop any of this code, does not know it inside and out, and can’t fix bugs or offer technical help. This is Wild West stuff.
  • OctoWS2811: specifically for the PJRC Teensy 3.0 microcontroller board. Uses DMA to drive up to 8 NeoPixel strips concurrently with minimal processor load. Multiple boards can be cascaded for still larger displays.
  • FadeCandy: also for Teensy 3.0. Doesn’t support as many pixels as OctoWS2811, but adds smooth interpolation and other features for the color-persnickety.
  • LEDscape: specifically for BeagleBone Black. Although the BeagleBone is a multitasking Linux system like the not-NeoPixel-compatible Raspberry Pi, this code exploits hardware features specific to the BeagleBone Black to drive hundreds of meters of NeoPixel strip with virtually no processor load.
  • WS2812 LED Driver for Parallax Propeller.
  • xCORE NeoPixel test code for the XMOS xCORE startKIT.
Some of these are 3.3V devices. See the “Powering NeoPixel” page for notes on controlling 5V NeoPixels from 3.3V microcontrollers.

WS2811? WS2812? Why do I see two different names mentioned?

The WS2811 is an earlier driver chip separate from the RGB LED. The data signal is similar, but runs at half the speed. By the time the WS2812 (with integrated LED) was released, a lot of code and projects had already built up around the WS2811 name. Sometimes code “for the WS2811” might actually be for the newer chip, or for either type. The Adafruit_NeoPixel library supports both.

Writing Your Own Library


The WS2812 datasheet explains the data transmission protocol. This is a self-clocking signal — there’s only one wire, not separate data and clock lines. “1” and “0” bits are indicated by varying the duty cycle of a fixed-frequency square wave.
There’s a math goof in the datasheet’s timing values. Use these figures instead:
Note that there’s nearly 25% “wiggle room” in the timing. So if your code can’t match the recommended times exactly, it’s usually okay.

There are three bytes of data for each pixel. These should be issued in green, red, blue order, with the most-significant bit first.
The data for pixel #0 (nearest the microcontroller) is issued first, then pixel #1, and so forth to the furthest pixel. This does not operate like a traditional shift register!

After all the color data is sent, the data line must be held low for a minimum of 50 microseconds for the new colors to “latch.”

You may want to dig through our Arduino library for insights. The timing-critial parts are written in AVR assembly language, but it’s extensively commented with C-like pseudocode.

My Microcontroller Isn’t Fast Enough to Do That

The WS2812 appears to be backwardly-compatible with the 400 KHz WS2811 signal. If you can precisely match the latter chip’s timing, either type will respond. The WS2811 protocol is not simply a half-speed WS2812. The duty cycle for the “0” and “1” bits is slightly different. From the WS2811 datasheet:
Last updated on 2014-04-17 at 04.15.18 AM Published on 2013-08-30 at 09.06.47 PM