unsigned long Arry issue / Adafruit_NeoPixel

Hello.

I hope this is the right place for this post. It “seems” to be an array issue, but might be something else related to Adafruit_NeoPixel library. Let me try to explain (I’m quite new on programming…)

I use the Adafruit_NeoPixel library and so far everything forked fine untill i tried to use arrays to save colors and so on.

I manage a 216 pixels long RGBW strip.

The code below works fine (all 216 leds are filled with random colors. So far so good)

  for(i=0;i<216;i++){
    strip.setPixelColor(i,  strip.ColorHSV(random(0,65535),255,255));
  } 
  strip.show();

The code below also works fine (but only 176 first leds are filled (see the size of the array; Still OK)

  unsigned long color;
  unsigned long i;
  unsigned long colors[176] = { };
     
  for(i=0;i<176;i++) {
      colors[i] = strip.ColorHSV(random(0,65535),255,255);
    } 

  for(i=0;i<176;i++){
    strip.setPixelColor(i,  colors[i]);
  } 
    
  strip.show();
  delay(1000);

Now comes the problem :frowning: As soon as the array is bigger 176 (why 176?) the behaviour become really eratic.

If I use 178, then a couple of leds are the very end of the strip are on at full brightness with random colors…

If I use 216 (max number of leds on the strip) then “some” leds are fully bright but not the last ones anymore.

Can anyone see anything wrong in this code ?
Beside that, I don’t have any errors during compiling nor sending to the arduino board (uno rev3)

  unsigned long color;
  unsigned long i;
  unsigned long colors[216] = { };  //0…215
     
  for(i=0;i<216;i++) {
      colors[i] = strip.ColorHSV(random(0,65535),255,255);
    } 

  for(i=0;i<216;i++){
    strip.setPixelColor(i,  colors[i]);
  } 
    
  strip.show();
  delay(1000);

Thanks for you help,

Roland (Paris, France)

Please post your entire sketch. Often times the problem is in the part you did not share.

I'm guessing that you only have enough memory for 176 LEDs.

Why are you storing the colors in an intermediate array?
Why not set them directly?

 for(i=0; i<216; i++) {
    strip.setPixelColor(i, strip.ColorHSV(random(0,65535),255,255));
  }

hello…

I need the array because the "get" does not return the same value as the "set" when the brighness is not set to 255 (which is weird IMO)…

BTW, is there a difference between uint32_t colors[216] and unsigned long colors[216] ?

PerryBebbington:
I’m guessing that you only have enough memory for 176 LEDs.

I think you’re right because when I remove some code here and there and some libraries too, everything “seems” to work properly.

BUT this is really weird because when the compilation (of the full code) is over i get this message

<<Sketch uses 6284 bytes (19%) of program storage space. Maximum is 32256 bytes.
Global variables use 418 bytes (20%) of dynamic memory, leaving 1630 bytes for local variables. Maximum is 2048 bytes.>>

What do you think ?

That is the amount permanently allocated memory.
The NeoPixel library allocates memory for the pixels at runtime, 216 RGBW pixels = 864 bytes.

Hi Roland,

I replied with my guess because it fitted the symptoms. It made sense that you might out of memory. However, I don't know any more than that, I am hoping someone cleverer than me will give you a better answer.

BTW, is there a difference between uint32_t colors[216] and unsigned long colors[216] ?

I personally don't like the original C variable types (int, unsigned long etc) because it is not obvious how big they are. Some of them vary between platforms, which only adds to the confusion. I would expect those two to be the same, but someone is going to come along and tell us that for this or that processor unsigned long is not 32 bits. I use the uint32_t style for everything because it is explicit in what is being used.

because the "get" does not return the same value as the "set" when the brighness is not set to 255 (which is weird IMO)

It is not weird, it is the only way it can work. What the brightness does is to scale or cut down the colour components as it is placed into the LED buffer. That is the only way you can affect the overall brightness. It is a software construct put over the top to allow you to dim the strip which by itself has no way of applying an overall brightness.

What is weird is using a thumping big number for the H value of the colour

 strip.ColorHSV(random(0,65535),255,255));

The H value goes from 0 to 255, anything over that just gets truncated to the least significant byte.

BUT this is really weird because when the compilation (of the full code) is over i get this message

Again no it is not weird, it is just you not understanding what is going on. The compiler only knows about the memory you allocate at compile time. The Neopixel buffer is assigned when the code runs, there is no way the compiler knows what the code is going to do when it runs. If it could then that WOULD be weird.

Grumpy_Mike:
What is weird is using a thumping big number for the H value of the colour

 strip.ColorHSV(random(0,65535),255,255));

The H value goes from 0 to 255, anything over that just gets truncated to the least significant byte.

The hue value is 16 bits in the library.

uint32_t Adafruit_NeoPixel::ColorHSV(uint16_t hue, uint8_t sat, uint8_t val) {

  uint8_t r, g, b;

  // Remap 0-65535 to 0-1529. Pure red is CENTERED on the 64K rollover;
  // 0 is not the start of pure red, but the midpoint...a few values above
  // zero and a few below 65536 all yield pure red (similarly, 32768 is the
  // midpoint, not start, of pure cyan). The 8-bit RGB hexcone (256 values
  // each for red, green, blue) really only allows for 1530 distinct hues
  // (not 1536, more on that below), but the full unsigned 16-bit type was
  // chosen for hue so that one's code can easily handle a contiguous color
  // wheel by allowing hue to roll over in either direction.
  hue = (hue * 1530L + 32768) / 65536;
...

Having read that you can see how stupid it is. I wonder when it changed because the Adafruit library never used to work like that. Anyway what is important is the RGB values so there is no need to store the way over specified H value at all, just store the resulting RGB value and save a whole heap of bytes.

Grumpy_Mike:
What is weird is using a thumping big number for the H value of the colour

Not my choice, just adafruit (Arduino Library Use | Adafruit NeoPixel Überguide | Adafruit Learning System)
The H value should be 0 to 360…

But this is not my point. Which is more abour memory.
Not easy at all :slight_smile:

Regards from Paris,
Roland

But this is not my point. Which is more abour memory.

Yes but if you just save the RGB value that the 32 bit random number gives you when converting from HSV then you would save 3 bytes per pixel in that array. So same results but saving 216 * 3 = 648 bytes so then you will not run out of memory so soon and could handle longer strips.

well… I have rgb'+W' values… but I may consider only use RGB.

I'll see that tomorrow. getting late in Paris !

take care
Roland