The Adafruit_NeoPXL8 library can be installed using the Arduino Library Manager. You will also need the Adafruit_NeoPixel and Adafruit_ZeroDMA libraries.

Remember to install the correct board support package through the Boards Manager:

  • Adafruit SAMD for Adafruit M0 and M4 boards
  • Arduino SAMD for Arduino Zero and similar
  • Pico/RP2040 Earle F. Philhower III for Feather RP2040 and SCORPIO
  • esp32 for Feather ESP32-S3

Example Code

There is a single Adafruit_NeoPXL8 example sketch called “strandtest,” and it’s pretty minimal. There’s no need for a whole graphics demo, because most NeoPXL8 functions are identical to their NeoPixel counterparts, and there are plenty of NeoPixel examples around already. The differences mostly relate to pin assignments.

First, include Adafruit_NeoPXL8.h instead of Adafruit_NeoPixel.h:

#include <Adafruit_NeoPXL8.h>

Then declare an Adafruit_NeoPXL8 object (instead of an Adafruit_NeoPixel object) — we’ll call our object “leds” in the example — passing up to three arguments:

Adafruit_NeoPXL8 leds(LENGTH, PINS, FORMAT);

The constructor’s first argument is the number of NeoPixels in each of the eight strands. In other words, the total number of NeoPixels will be 8 times this value. If this value is set at 60, then the total number of NeoPixels is 480 (60 × 8).

The strands don’t all need to be the same length. In that case, give the length of the longest strand. But from the software’s point of view there’s still 8 times this many pixels…it’s going to require that much memory regardless and there will be gaps in how pixels are addressed. It’s best and optimal if all 8 strands are in use and the same length, but not required.

NeoPXL8 is a RAM hog, but on most M0 boards, depending on your code’s other needs, you can often get 250 RGB pixels per strand (2,000 pixels total). 300 (2,400 total) is starting to push things. Scale back for RGBW pixels, which require about 33% more RAM.

M4 boards have six times the RAM and can handle absurd thousands of pixels…but in reality, you might not want more than a couple thousand, tops, just to allow the CPU enough time to compute all those pixels at a good frame rate. For an M0 project, maybe a few hundred to a thousand or so. There’s no hard limit, you just need to experiment what’s practical to compute.

The second argument is an 8-element int8_t array indicating which pins to use for outputs 0 through 7.

This is extremely hardware-dependent, and you’ll see in the strandtest sketch there are several different arrays given for different situations. For example, using a Feather M0, NeoPXL8 FeatherWing with the default pin assignments and the Fadecandy-style connector, it’s:

int8_t pins[8] = { PIN_SERIAL1_RX, PIN_SERIAL1_TX, MISO, 13, 5, SDA, A4, A3 };
Adafruit_NeoPXL8 leds(NUM_LED, pins, NEO_GRB);

As explained on the prior page, on the Feather M0, outputs 3, 6 and 7 are not negotiable — they must go to pins 13, A4 and A3 (these can be reordered — you can change which is considered output 3, 6 or 7 — but you cannot select completely different pins). For the remaining 5 outputs, there’s a limited ability to reassign things:

Output Number

Default Pin

Alternate Pin
















Feather M4 is a little different. There, outputs 4 through 7 are not negotiable — they must go to pins 13 through 10 (though they can be reordered within that series). For the other four outputs, there’s a limited ability to reassign things:

Output Number

Default Pin

Alternate Pin













Changing these assignments requires cutting and bridging pads on the component side of the FeatherWing board, plus matching changes to the pins[] array.

If neither pin choice will work for your application, use a value of -1 for that element of the pins[] array, as many as required. You will lose the corresponding NeoPixel output, and it will still take up RAM and pixel indices as if it were there, but the pin can then be used for normal GPIO.

Different boards will have different pinouts, you’ll see this in the example code. The Metro M4 uses an entirely different set of pins. And on the Metro M0 (or Arduino Zero), things are super easy…if you want to use digital pins 0-7 as the eight NeoPixel outputs, just pass NULL instead of a pins[] array, or leave this argument off entirely. RP2040 boards have their own rules, explained on the next page.

The third argument to the constructor is the NeoPixel data format or color order. Different manufacturers of “NeoPixel compatible” LEDs may use a different R/G/B (and sometimes W) byte order…and even among single manufacturers, different production runs may change the order as required for big customers or if they find it can economize the design. This is very similar to the last argument to the Adafruit_NeoPixel constructor, except any NEO_KHZ800 or NEO_KHZ400 values are ignored (only 800 KHz is supported). You can leave this argument off to use the default NEO_GRB color order.

All 8 strands must be the same type and color order; e.g. you cannot mix RGB and RGBW NeoPixels.

From a coding perspective, the rest appears nearly identical to a regular NeoPixel sketch.

Call the object’s begin() function to allocate memory and initialize the pin outputs:


You can check for a return value of “true” to confirm the allocation was successful.

Then setPixelColor() to modify individual pixel values and show() to issue data to the strands, just like a regular NeoPixel sketch.

For functions that take a pixel index (e.g. setPixelColor(), getPixelColor()), all the pixels are treated as if one long continuous strand. For example:

If the strand length was declared as 60…that’s 480 pixels total…

  • Pixels 0 – 59 are on strand 0
  • Pixels 60 – 119 are on strand 1
  • Pixels 120 – 179 are on strand 2
  • Pixels 180 – 239 are on strand 3
  • Pixels 240 – 299 are on strand 4
  • Pixels 300 – 359 are on strand 5
  • Pixels 360 – 419 are on strand 6
  • Pixels 420 – 479 are on strand 7

This is true even if some strands are physically shorter, or if an element in the pins[] array is -1. The unused bits just vanish into the unknown, like that one light switch that doesn’t seem to control anything in the house.

One small difference from Adafruit_NeoPixel is that the setBrightness() function, in combination with setPixelColor() and getPixelColor(), work better here. The original color value assigned to a pixel using setPixelColor() will always be accurately returned by getPixelColor(), regardless of the current brightness setting. In Adafruit_NeoPixel this is a “destructive” operation and only an approximation is returned.

That’s the vital stuff to know.

Also maybe helpful: if using other NeoPixel code as a starting point, this blog post discusses some out-of-favor techniques and how to write more modern NeoPixel code. If it’s using the wheel() function, it’s old!

This guide was first published on May 30, 2018. It was last updated on Mar 08, 2024.

This page (NeoPXL8 Arduino Library) was last updated on Mar 08, 2024.

Text editor powered by tinymce.