Boron + Neopixel + RGB.onChange?

Hello everyone. I’ve read through numerous posts about RGB.onChange and Neopixel (only a handful, that I found, and I am coming up completely empty on getting anything working.

I wired up a regular RGB LED and implemented the RGB.mirrorTo code just fine. However, for cramming everything into a nice little enclosure, it’s much easier to use something a bit more convenient. I had a neopixel on a breakout in my drawer of stuff, so I decided to give it a try. Wiring it up and just addressing the neopixel, everything works great. Weird stuff happens when I try to use RGB.onChange though.

If I call STARTUP(RGB.onChange(ledChangeHandler)); it looks like the handler never fires. If I put RGB.onChange(ledChangeHandler) inside of setup() stuff just…breaks. The first time I tried it (adding it into my existing code) it would cause the onboard LED to alternate flashing green and white, and never kick out of that. The good news (I think?) is the neopixel would also blink (not green, just white on and off). After I gave up, I started from scratch and added just the neopixel code. Now if I keep it in setup all it will do is fast flash green, like it’s constantly looking for a network signal. The neopixel does NOT flash or light up at all in this case. Anyone recently use a neopixel with a Boron to mimic the onboard LED? Here’s all of the not working code.


// This #include statement was automatically added by the Particle IDE.
#include <neopixel.h>

#define PIXEL_COUNT 1            
#define PIXEL_PIN D5             
#define PIXEL_TYPE WS2812     

#define MIRROR_LED 0            


Adafruit_NeoPixel led(PIXEL_COUNT, PIXEL_PIN, PIXEL_TYPE);
STARTUP(RGB.onChange(ledChangeHandler));
void setup() {
   
   
   Serial.begin(115200);
  
       
   led.begin(); 
   //led.setPixelColor(MIRROR_LED, led.Color(0,255,0));  // used to make sure working
   led.show(); 
   delay(300);
   //RGB.onChange(ledChangeHandler);  // just completely breaks the board
 
    
}

void loop() {
    
    
}


void ledChangeHandler(uint8_t r, uint8_t g, uint8_t b)
{
  led.setPixelColor(MIRROR_LED, led.Color(r, g, b)); 
  led.show();
  
}

My guess is that:

  1. You should not call RGB.onChange from STARTUP(). It probably won’t work properly there.

  2. You can’t call the NeoPixel code from an LED change handler

I think the LED change handler is called from an interrupt handler. It’s intended to only set a pin state, which is a very short duration event. The NeoPixel code is not intended to run in that context.

What you would need to do is set the ledChangeHandler from setup. Save the LED colors from the ledChangeHandler in a global variable. Then from loop(), update the NeoPixel from the last value, if it changed.

Awesome, thanks. I’ll try that.

As an alternative, I ordered some DFRobot DFR0239 to maybe solve my issue.

Thanks so much.

I’m not entirely sure, but I think the only (potentially) problematic call there is led.show() but led.setPixelColor() should be save to be called from an ISR.

Hence I’d try this

bool needUpdate = false;

void ledChangeHandler(uint8_t r, uint8_t g, uint8_t b) {
  led.setPixelColor(MIRROR_LED, led.Color(r, g, b)); 
  needUpdate = true;  
}

void loop() {
  if (needUpdate) {
    needUpdate = false;
    led.show();
  }
}

(however, this would cause some “flicker” compared to the on-board LED when loop() gets delayed by some business code or the device OS talking to the cellular modem)

@RedHuskies, I much prefer APA102 or SK9822 smart LEDs for their more simple and robust protocol (although they need one extra signal pin - but still one less than a regular RGB LED - gets most beneficial when using more than one independent LED).

@ScruffR thank you. After playing around a bit, I think I’m going to probably stick with something that works with mirrorTo as it’s a little cleaner and “nicer” behavior. The DFRobot DFR0239s that I ordered should be here Thursday. It looks like a straightforward hookup and small enough to work for my needs. I’ll continue to tweak the neopixel WS2812 to see if I can make it work if needed (like I said, I already had that, which is why I started with it). I can always explore other LED options you mentioned as well. I’m in no rush to have this in any sort of shipping product ready state. Just more planning for when it does get sealed up in its permanent home.

Thanks again.