Neopixel Code Not Working Properly

I’ve been playing with Photons for a while now, and I’m currently trying to port a project I put together for an Arduino Trinket to a Photon (and ultimately adding some additional functionality) but I’m running into issues. I didn’t create this original project, but I have started trying to tweak the code to get it working on a Photon correctly. It runs, but the colors are completely off (and it seems that it may be flickering in a funny way). The correct result is supposed look similar to a rocket engine flame (think lots of yellows and reds that are flickering). I’ve tried running some basic Neopixel code on my Photon setup that I found online and it ran just fine but I can’t get this specific code running properly. Anything obvious that I’m missing?

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

#include <Particle.h>
#include <math.h>

#define PIN A0
#define PIXEL_COUNT 61
//arrayLength = pixel count/3
const int arrayLength=20;
#define SCALE_AMOUNT 0.5
#define FLICKER_SPEED 5
#define FLICKER_AMOUNT 50

struct RGBW {
  byte r;
  byte g;
  byte b;
  byte w;
};

RGBW colors[] = {
  { 255, 150, 0, 255},    // yellow + white
  { 255, 120, 0, 0},      // yellow + white
  { 255, 90, 0, 0},       // orange
  { 255, 30, 0, 0},       // orangie-red
  { 255, 0, 0, 0},        // red
  { 255, 0, 0, 0}         // extra red
};

int NUMBER_OF_COLORS = sizeof(colors) / sizeof(RGBW);

int percentBetween(int a, int b, float percent) {
  return (int)(((b - a) * percent) + a);
}

// Parameter 1 = number of pixels in strip
// Parameter 2 = Arduino pin number (most are valid)
// Parameter 3 = pixel type flags:

//#define WS2811         0x00 // 400 KHz datastream (NeoPixel)
//#define WS2812         0x02 // 800 KHz datastream (NeoPixel)
//#define WS2812B        0x02 // 800 KHz datastream (NeoPixel)
//#define WS2813         0x02 // 800 KHz datastream (NeoPixel)
//#define TM1803         0x03 // 400 KHz datastream (Radio Shack Tri-Color Strip)
//#define TM1829         0x04 // 800 KHz datastream ()
//#define WS2812B2       0x05 // 800 KHz datastream (NeoPixel)
//#define SK6812RGBW     0x06 // 800 KHz datastream (NeoPixel RGBW)
//#define WS2812B_FAST   0x07 // 800 KHz datastream (NeoPixel)
//#define WS2812B2_FAST  0x08 // 800 KHz datastream (NeoPixel)
Adafruit_NeoPixel strip = Adafruit_NeoPixel(PIXEL_COUNT, PIN, WS2812);


// 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.

float scale = 1;
float inc = 0.1;
float dir = 1.0;
byte pixelBrightness[arrayLength];
boolean pixelDirection[arrayLength];

// prepopulate the pixel array
void seedArray() {
  for (uint16_t i=0; i < PIXEL_COUNT; i++) {
    uint16_t p = i % arrayLength;
    pixelBrightness[p] = random(255-FLICKER_AMOUNT, 255);
    pixelDirection[p] = !!random(0, 1);
  }
}

void setup() {

strip.begin();
strip.show(); 
  
}

void loop() {
  // how many leds for each color
  int ledsPerColor = ceil(PIXEL_COUNT / (NUMBER_OF_COLORS-1));

  // the scale animation direction
  if (scale <= 0.5 || scale >= 1) {
    dir = dir * -1;
  }

  // add a random amount to inc
  inc = ((float)random(0, 50)/1000);

  // add the increment amount to the scale
  scale += (inc * dir);

  // constrain the scale
  scale = constrain(scale, 0.5, 1);

  for (uint16_t i=0; i < PIXEL_COUNT; i++) {
    uint16_t p = i % arrayLength;

    float val = ((float)i * scale) / (float)ledsPerColor;
    int currentIndex = floor(val);
    int nextIndex = ceil(val);
    float transition = fmod(val, 1);

    // color variations
    if (pixelDirection[p]) {
      pixelBrightness[p] += FLICKER_SPEED;

      if (pixelBrightness[p] >= 255) {
        pixelBrightness[p] = 255;
        pixelDirection[p] = false;
      }
    } else {
      pixelBrightness[p] -= FLICKER_SPEED;

      if (pixelBrightness[p] <= 255-FLICKER_AMOUNT) {
        pixelBrightness[p] = 255-FLICKER_AMOUNT;
        pixelDirection[p] = true;
      }
    }

    RGBW currentColor = colors[currentIndex];
    RGBW nextColor = colors[nextIndex];
    float flux = (float)pixelBrightness[p] / 255;

    byte r = percentBetween(currentColor.r, nextColor.r, transition) * flux;
    byte g = percentBetween(currentColor.g, nextColor.g, transition) * flux;
    byte b = percentBetween(currentColor.b, nextColor.b, transition) * flux;
    byte w = percentBetween(currentColor.w, nextColor.w, transition) * flux;

    strip.setPixelColor(i, g, r, b, w);
  }

  strip.show();
}

@brooksben11, how are you powering the neopixels and how are they connected to the Photon?

1 Like

Might not be your issue but when working with a 500-LED DotStar strip, I had weird flickering on the last 2-4 23-led segments. Although I was driving below the max frequency with the default SPI divider, I had to run the Photon with the SPI freq divider at 16 to get rid of the flickering.

1 Like

I’ve got 5V and ground coming straight off of the USB cable to the neopixel leads (with a 1,000uF capacitor between them). I spliced it up this way prior to realizing that the Vin pin outputs at 5V when connected to USB. The A0 pin is connected to the neopixel data lead with a resistor in series (I believe 500 Ohm). I tried using a logic-level shifter up to 5V originally thinking that was the issue, but it makes no difference. I specifically tried both with and without one when running a basic ‘rainbow’ code on the Photon and it worked fine both times, so I’m pretty confident my setup is good. I should also mention that I had it wired up exactly the same via the Trinket and it worked flawlessly.

@brooksben11 with 61 LEDs at max 60ma per Neopixel, that adds up to about 3.7Amps! What is the capacity of your USB supply and how long is your USB cable?

Not sure on the capacity, it’s actually plugged into a docking station/hub; it’s a fairly short cable, maybe 2-3 feet? I don’t THINK that’s the issue simply because my previous setup was the same and ran perfectly. It was a USB cable powering a Photon (used to basically turn a few pins on/off to control the Trinket) with 5V/Gnd spliced off of said cable powering both the Neopixels and a Trinket running the code to control the Neopixels. My current setup is exactly the same, except I’ve removed the trinket and connected the data lead to the Photon instead with it running the above code; the total power-draw should be less, if anything. Also, as I said before, I was able to run a simple ‘rainbow’ code via the Photon without any problems so I really think it’s something funky in the code that works fine on an Arduino but that the Photon doesn’t like.

Just keep in mind that the USB standard (up to version 2) was to only supply a max of 500mA. The USB v3 (blue connectors) and the new USB-C standard allows for more current (900mA on v3, 3000-5000mA on C). If you are running your setup on a standard (USB v2) port on the docking station, you can only draw 13.5% of the power you need if you set all the pixels to white (all colors on at full intensity). You could have brown-outs which cause unexpected behavior.

Looking at your code, I’m not a C++ expert but it looks like there are no constraints or checks on currentIndex and nextIndex. Those indexes are used to access array elements. It could be that you are retrieving values outside the bounds of the array.

float val = ((float)i * scale) / (float)ledsPerColor;
int currentIndex = floor(val);
int nextIndex = ceil(val);
...
RGBW currentColor = colors[currentIndex];
RGBW nextColor = colors[nextIndex];
1 Like

Obviously this is quite an old post, but after revisiting the code for another project I finally found my issue. Well, 2 issues that when combined made it look like the code wasn’t working. Apparently the Neopixel library I was using on the Trinket was slightly different than the one that was ported over to Particle; the order of the R and G of the RGBW callouts were/are flipped causing me to get a bunch of green in my Neopixels when there shouldn’t have been any at all. Just swapping the color values fixed that.

Lastly, this code was written specifically for the Trinket which is a much slower device. When ran on the Photon is simply ran too fast and rather than a soft fluctuation in color values it seemed to have more of a flicker in line with a problem. Adding a 50ms delay between color changes gave me the look I was after.

Just figured I would post an update in case anyone else ran into issues trying to bring a Neopixel project over to the Photon since my issues weren’t really specific to my project/code. Thanks to everyone who posted before trying to help me out!