Adafruit_Neopixel library (for use with Neopixel Featherwing

I’ve seen some discussion about the Adafruit_Neopixel library possibly being ported for Particle, but so far I have not seen definitive evidence that this was done. Can someone please clarify this?

Trying to use an Adafruit Neopixel Featherwing:

… with either an Argon or Xenon board. Can’t locate the correct library in the Particle workbench.

In the past I’ve used the “neopixel” library for other projects, but that library doesn’t work with the Neopixel Featherwing.

Hi @jjdeprisco - Have you checked the Particle library search? There are a number of neopixel libraries, this is the main one.

Yes, I have that one, but it does not work with the Neopixel Featherwing, at least not so far in my tests with the Xenon.

I’ve ordered a Feather Huzzah, which should be here tomorrow. I want to verify I can get the Neopixel Featherwing working with the Huzzah. But from what I see so far, that should be easy with the Adafruit_Neopixel library they require (which is not in the Particle library search).

@jjdeprisco, I have to ask - did you jumper one of pads on the featherboard to select a Neopixel data pin and then specify that in your code?

Yes, a pad has a jumper and the code is noted with that, but I didn’t get past verifying the sketch because of the library issue.

@jjdeprisco, looking at the Adafruit library, it is too hardware biased, making it difficult to adapt. Have you tried the Neopixel-NRF library? I was able to compile for a Xenon and DeviceOS 1.5.2 without errors. I am not able to test it though.

1 Like

Thanks for the suggestion. So far that’s not compiling either.

lib/neopixel/neopixel.cpp:92:0: multiple definition of "Adafruit_NeoPixel::~Adafruit_NeoPixel()"
/firmware/user/../wiring/inc/spark_wiring_ticks.h:41:0: multiple definition of "Adafruit_NeoPixel::~Adafruit_NeoPixel()"
/firmware/user/../wiring/inc/spark_wiring_ticks.h:41:0: multiple definition of "Adafruit_NeoPixel::updateLength(unsigned short)"
/firmware/user/../wiring/inc/spark_wiring_ticks.h:41:0: multiple definition of "Adafruit_NeoPixel::begin()"
/firmware/user/../wiring/inc/spark_wiring_ticks.h:41:0: multiple definition of "Adafruit_NeoPixel::setPin(unsigned char)"

Those are just the first few errors. This is why I want to confirm a setup away from the Xenon first (on a HUZZAH board), just so I can get a feel for how the stock library works. Perhaps then, once I see some working examples, I can troubleshoot on the Xenon via Particle Workbench better.

@jjdeprisco, can you share your Web IDE application using the “SHARE THIS REVISION” button and post the link here or DM me.

After about 5 days of a sidebar with @peekay123 - I have an update. What started as an enhancement to a previously working POC turned into an education in neopixels within Particle as well as a lesson in some red herrings and rabbit holes. In fact, the neopixel side of things turned out to be the least of my worries.

The original project was an SR04 sensor on an Argon which, when tripped, sent events over mesh to a Xenon where an LED was turned on/off. I had that working a couple weeks ago and wanted to add a Neopixel Featherwing, with some sort of light show to replace the LED. All of this was on OS 1.5.2.

@peekay123 assisted me with understanding the ins/outs of combining the original Xenon sketch on the receiving end with new neopixel code. After a few iterations, I lost a few days when some bizarre behavior with the previously working events handler started to occur. @peekay123 could not reproduce this, and today it was clear why.

Earlier today, I located a wiring error on the Argon board, which may have happened when the project got jostled around in the course of testing this past week. With that corrected, I turned my attention back to the Xenon, but was not seeing events. So I decided to swap out the Argon’s SR04 and from there everything worked fine.

Fully commented code and a video will be shown below.

Argon Code (sensor side)

// Originally from:

// Sensor gateway using the Argon board. This contains the HC-SR04
// Ultrasonic code and sends data to the other nodes to notify of a trip

#include "HC_SR04.h"

double cm = 0.0;
bool beam_status = false;

int trigPin = D4;
int echoPin = D5; // JJD pin works despite notes to the contrary in Particle's documentation.

HC_SR04 rangefinder = HC_SR04(trigPin, echoPin);

void setup() 
    Spark.variable("cm", &cm, DOUBLE);

void loop() 
    cm = rangefinder.getDistanceCM();
    if (cm<30){
        if (beam_status==false){
            Particle.publish("tripStatus", "breach");
            beam_status = true;   
    } else {
        if (beam_status==false){
        } else {
            Particle.publish("tripStatus", "all_clear");
            beam_status = false;

Xenon code (receiving side)

/* JJD 2/13/23
 Based on original LED sketch here:
 Includes peekay123's suggestions on the switch setup

 Combining Xenon sketches to receive events from the SR04 sketch on my Argon via myHandler,
 to change pixel behavior on Xenon. Both pieces work when tested separately.
 For specifics on neopixel parameters, see original examples. Too much text to clutter here.

/* ======================= includes ================================= */

#include "Particle.h"
#include "neopixel.h"

/* ======================= prototypes =============================== */

void colorAll(uint32_t c, uint8_t wait);
void colorWipe(uint32_t c, uint8_t wait);
void rainbow(uint8_t wait);
void rainbowCycle(uint8_t wait);
uint32_t Wheel(byte WheelPos);

/* ======================= extra-examples.cpp ======================== */

SYSTEM_THREAD(ENABLED); // added per web research to avoid Xenon dropping off

#define PIXEL_COUNT 32  // Changed for Neopixel Featherwing
#define PIXEL_PIN D5    // D5 works despite the notes below
#define PIXEL_TYPE WS2812B
#define BRIGHTNESS 10   // These things are way too bright!!

// Define types of effects in this enum
enum effect_type {NONE, CLEAR, RAINBOW}; // Thanks to peekay123!

// define the global variable which holds the current effect
effect_type effect = NONE;  // Start with no effect (does nothing)

Adafruit_NeoPixel strip(PIXEL_COUNT, PIXEL_PIN, PIXEL_TYPE);

// IMPORTANT: To reduce NeoPixel burnout risk, add 1000 uF capacitor across
// pixel power leads, add 300 - 500 Ohm resistor on first pixel's data input
// and minimize distance between Arduino and first pixel.  Avoid connecting
// on a live circuit...if you must, connect GND first.

void setup() {

  // *** Neopixel Setup code *** //
  strip.begin();; // Initialize all pixels to 'off'

  // Subscribe to sensor tripping using Particle.subscribe
  Particle.subscribe("tripStatus", myHandler); // the name of the publish() call in sensor node [ publish("tripStatus") ]


void loop() {
    This is a non-blocking way to show the desired LED effect.
    The only "blocking" is during the execution of the effect.
    The effect is set in "myHandler" which is run whenever loop() completes.
    Once set, the swtich() statement runs the selected effect and then resets
    the effect to NONE to basically do nothing until the effect value is changed again.
   switch(effect) {        //  Thanks to peekay123!
      case NONE:        // No effect so do nothing
      case CLEAR:       // CLEAR effect
        // Use ColorAll() so could clear screen to other color than black by setting R/G/B value in strip.Color()
        colorAll(strip.Color(0, 0, 0), 20);
        effect = NONE;  // effect complete, reset to NONE
      case RAINBOW:     // RAINBOW effect
        rainbow(20);    // Do effect
        colorAll(strip.Color(0, 0, 0), 20); // JJD added this again to see if it will stop green
        effect = NONE;  // effect complete, reset to NONE
      default:          // Catch for invalid value, acts as NONE

// Now for the myHandler function, which is called when the cloud tells us that our sensor's event has been published.
void myHandler(const char *event, const char *data)
  if (strcmp(data,"breach")==0) {
    // if the sensor's threshold is breached, then...
    effect = RAINBOW; // play rainbow
  else if (strcmp(data,"all_clear")==0) {
    // if your sensor's beam is all clear, then...
    effect = CLEAR;

/* ======================= Neopixel behaviors ======================== */

// Set all pixels in the strip to a solid color, then wait (ms)
void colorAll(uint32_t c, uint8_t wait) {
  uint16_t i;

  for(i=0; i<strip.numPixels(); i++) {
    strip.setPixelColor(i, c);

void rainbow(uint8_t wait) {
  uint16_t i, j;

  for(j=0; j<256; j++) {
    for(i=0; i<strip.numPixels(); i++) {
      strip.setPixelColor(i, Wheel((i+j) & 255));

// Slightly different, this makes the rainbow equally distributed throughout, then wait (ms)
void rainbowCycle(uint8_t wait) {
  uint16_t i, j;

  for(j=0; j<256; j++) { // 1 cycle of all colors on wheel
    for(i=0; i< strip.numPixels(); i++) {
      strip.setPixelColor(i, Wheel(((i * 256 / strip.numPixels()) + j) & 255));

// Input a value 0 to 255 to get a color value.
// The colours are a transition r - g - b - back to r.
uint32_t Wheel(byte WheelPos) {
  if(WheelPos < 85) {
   return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
  } else if(WheelPos < 170) {
   WheelPos -= 85;
   return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
  } else {
   WheelPos -= 170;
   return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);

Here’s a video of the working project:

1 Like

That’s some great collaboration! Thank you for posting back the status. Always interesting to read about projects.

Hats off to both of you! (@peekay123 )

1 Like

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.