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.
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.
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).
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.
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.
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 are three bytes of data for each pixel. These should be issued in green, red, blue order, with the most-significant bit first.
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.