New to working with arduino and neopixel leds so I apologize for my inexperience. Looking for some assistance with a flicker and glitch issue I'm having with several 90 led strips I've soldered together totaling to 344 neopixels. The chasing animation I've used has worked on previous soldered together strips but after repairing a small issue I'm having a difficult time replicating what I was able to successfully accomplish in previous projects. I can't figure out what I'm doing wrong. When I turn on the power, leds light up and chase animation starts, but after about 30 seconds the last 2/3rds of the strip flickers and stops animating then begins to glitch.
I have programmed a chasing animation (written by another person) to other strips of around 300 to 250 neo pixels and they have run just fine. So I don't think the problem is in the sketch. This is how I have my neopixels set up:
I thought maybe they were drawing too many amps, but I'm using a 5v 10A power supply and that many lights should only be drawing a little over 2 amps.
I thought perhaps that they were using too much RAM but when I compile the sketch it says that I'm barely making a dent in the total bytes; "4034 bytes (1%) Max is 253952. Global variables use 245 bytes 2% of dynamic memory, leaving 7947 bytes for local variables, max 8192." I'm using an Arduino Mega 2560
I thought maybe the strip was bad so I used an all-new strip and still had the same issue. I thought maybe my solder joints were bad but I had more experienced people solder the joints and still the same issue.
I can only make it work consistently with 90 neopixels. It's just odd because even with the same sketch and the same method of powering and joining the strips together, other projects I've completed have worked just fine. It's suddenly not working for me. I'm at the last bit of patience I have for this, but the project is important and I need to fix it. Any help or direction would be appreciated.
Added. The compiler would know about that array, so I do not understand why it would not have counted it and given you a report as to why the code would not run. At all.
a7
Read for fun. My bad:
You wrote
uint16_t chaseStates[NUM_CHASES][STREAM_LENGTH];
That's 34 * 344 * 2 bytes. 23392 bytes.
The compiler doesn't know about that, so you get a report that does nowhere near reflect the total memory required.
The begin() method allocates memory for the strip, does not report failure or you fail to check if it does.
> arduino-cli compile -b arduino:avr:mega --warnings all --clean
Sketch uses 4034 bytes (1%) of program storage space. Maximum is 253952 bytes.
Global variables use 245 bytes (2%) of dynamic memory, leaving 7947 bytes for local variables. Maximum is 8192 bytes.
> arduino-cli compile -b MegaCore:avr:2560 --warnings all --clean
Sketch uses 3998 bytes (1%) of program storage space. Maximum is 261632 bytes.
Global variables use 245 bytes (2%) of dynamic memory, leaving 7947 bytes for local variables. Maximum is 8192 bytes.
> nm -SCn build/arduino.avr.mega/forum_1342731.ino.elf | grep chase
00800206 00000044 b chaseHeads
0080024a 00000088 b chaseColor
> nm -SCn build/MegaCore.avr.2560/forum_1342731.ino.elf | grep chase
00800206 00000044 b chaseHeads
0080024a 00000088 b chaseColor
No sign of changeStates.
Both have LTO enabled by default. Let's try without:
> arduino-cli compile -b MegaCore:avr:2560:LTO=Os --warnings all --clean
Sketch uses 4512 bytes (1%) of program storage space. Maximum is 261632 bytes.
Global variables use 23637 bytes (288%) of dynamic memory, leaving -15445 bytes for local variables. Maximum is 8192 bytes.
Not enough memory; see https://support.arduino.cc/hc/en-us/articles/360013825179 for tips on reducing your footprint.
Something really weird is going on with LTO.
For comparison a couple of boards with enough memory:
build/arduino.samd.mkr1000/forum_1342731.ino.elf
200000ac 00000088 B chaseColor
20000134 00000044 B chaseHeads
20000178 00005b60 B chaseStates
build/esp32.esp32.featheresp32/forum_1342731.ino.elf
3ffc1a38 00005b60 B chaseStates
3ffc7598 00000044 B chaseHeads
3ffc75dc 00000088 B chaseColor
to setupChases() and call a function I wrote called printChases() which does what it says, compiling for the Mega fails, viz:
Global variables use 21800 bytes (266%) of dynamic memory, leaving -13608 bytes for local variables. Maximum is 8192 bytes.
Not enough memory; see http://www.arduino.cc/en/Guide/Troubleshooting#size for tips on reducing your footprint.
Error compiling for board Arduino Mega or Mega 2560.
I did not think the optimizer, which I assume is the problem here, could optimize its way out of a ridiculous use of memory.
And besides the fact that there seems to be plenty of use of that array that I don't see being optimized away.
I surrender and await the heavies who will 'splain this. Going horizontal now...
So at 60mA per neopixel you need a power supply capable of supplying at least 20.6 Amps. So your power supply is too small. You could reduce this power requirement by limiting the brightness in the setup function.
You need to also to have a 1000uF capacitor between power and ground at the beginning and end of each strip, and maybe in the middle of a strip as well. Also as mentioned extra power and ground at each end and middle of strips.
Please show how these 90 pixel strips are aggregated.
So:-
344 * 34 = 11696 points in the array. But as each point is a uint16_t , each point takes 2 bytes
giving
11696 * 2 = 23392 bytes
Why do you have to use a two dimensional array at all?
The Arduino Mega has 8K of dynamic memory
In fact for 334 Leds, each LED requires three bytes of dynamic memory, gives :-
334 * 3 = 1002 bytes of memory, which is only about one eighth of the total memory available on that processor.
True it can't.
So the optimizer is not your problem. It doesn't kick in at all and has no role in your code.
What do you think the optimizer does? It's job is to replace or remove redundant code, that is code that exists but is never used. Like a line of code that does nothing, or a line that can never be reached.
Your problem is requiring such a massive array in the first place.
I do not disagree, but I find my sloppy coding doing similar gymnastics when I do not keep the math inside [zero..NUMPIX-1] for placement and [zero..255] for color and brightness. I add this to my sketches to keep me honest.
void debugValues(int i, int r, int g, int b) {
// Call this function to:
// verify index matches starting color values
// verify no values < 0 or > 255
// verify index matches ending color values
Serial.print(i); // index
Serial.print(" ");
Serial.print(r); // red
Serial.print(" ");
Serial.print(g); // green
Serial.print(" ");
Serial.print(b); // blue
Serial.println();
}
I like to write code that wouldn't need to know it's being checked in some library function.
I will cop, however, to being lazy. When running a train of LEDs off the end of the track, for example, it's just easier to let it and rely on something else to keep the damages to a minimum. Either end of the track.
FastLED is different, in that case you are the owner of the array and no one but you will keep trouble at bay.
On the same hand, or it's it the other, if you are using those indices in other code then you are back to wanting to keep everything on bounds.
My own honesty-enforcer is, um, somewhat primitive. This function can be called from anywhere, and I call it when something that "can't happen" has, in fact, occurred.
But you don't seem to be reading this thread. The code compiles even though it has a massive array that is clearly being used in some algorithm @dlvarner wrote or found…
And only when I wrote an explicit initialisation meant to provoke an error by frustrating any optimisation, and had to also add printing out the array, did the compiler finally notice that the code was trying to use more memory than available.
So something besides knowing everything about everything is going on here. I can't say what it is. I hope someone who actually knows more about this than, it seems, either of us can add something to the discussion.
What on Earth are you talking about? Please try to make that make any sense.
If anyone is missing any point it would be you. A program with a too-large array to compile does, until you start actually using the array in a certain way it was not previously.
Where are arrays ever defined except "inside the code"?
This is a global array of the simplest kind; the code should not compile but rather give an error, the same kind of error it is possible to get it to eventually issue.
int largeTwoDimensionalArray[TOO][BIG];
Where the product of TOO and BIG times two is very much larger than the available RAM. Would you not expect help from the compiler to show you the folly of trying to do that?
This is not normal. I want to know what is happening, nothing about it seems right to me.
Whatever else is going on, the 23392 bytes for the chaseStates array is a red herring. It was totally optimised out of being any problem, here were the four references to it in the code, which in my haste I read as making it safe from being simply disregarded.
So having indulged in your effort to solve your problems maybe you could remember that the whole point of this thread was to solve @dlvarner 's problem not yours. You are better than this.
The OP has indicated he/ she no longer requires help so I have closed the topic. If you really want to add something feel free to request it be opened.