Variable Array Sizes when Instantiating?

Started by MaxMaxfield 3 years ago4 replieslatest reply 3 years ago137 views
As always, I'm really sorry to bug you with a simple question (simple to you, not to me) -- I'll try to make this the last one for a while. I'm using an Arduino clone along with the Adafruit NeoPixel Library (https://learn.adafruit.com/adafruit-neopixel-uberguide/arduino-library-installation)

Normally I just use a single string of NeoPixels I call "Neos," which I would instantiate as follows (assume a string of 45 Neopixels):

#define NUM_NEOS 45

#include <Adafruit_NeoPixel.h>

const int PinNeos = 6;

Adafruit_NeoPixel Neos(NUM_NEOS, PinNeos, NEO_GRB + NEO_KHZ800);

The last part "NEO_GRB + NEO_KHZ800" is defined by the NeoPixel library

Later on, if I wanted to change the color of pixel 6 to be red, I could use:

Neos.setPixelColor(6, 0xFF0000);


In the past, I've also had success creating an array of NeoPixel strips like the following:

const int PinNeos [4] = {7,8,9,10};

Adafruit_NeoPixel Neos[4] =
    Adafruit_NeoPixel(NUM_NEOS, PinsNeos[0], NEO_GRB + NEO_KHZ800),
    Adafruit_NeoPixel(NUM_NEOS, PinsNeos[1], NEO_GRB + NEO_KHZ800),
    Adafruit_NeoPixel(NUM_NEOS, PinsNeos[2], NEO_GRB + NEO_KHZ800),
    Adafruit_NeoPixel(NUM_NEOS, PinsNeos[3], NEO_GRB + NEO_KHZ800)

To be honest, I no longer have any clue how I came to arrive at the above solution, but it works. Now, if I wanted to change the color of pixel 6 on strand [1] I could use:

Neos[1].setPixelColor(6, 0xFF0000);

The thing is that the above works because I know the size of the array before I start.


Now take a look at these SMADs (Steve and Max's Awesome Displays):

Each SMAD has 45 LEDs -- different users will have different configurations -- some with have one string with 1, 2, 3, or 4 SMADs -- others will have two strings each with 1 or 2 SMADs -- and some will have four strings each with 1 SMAD

What I would really like to do would be to create a single program that could run any combination -- something like the following:

#define NUM_NEOS_PER_SMAD    45
#define NUM_STRINGS           2  // could be 1, 2, or 4 (ideally any number from 1 up)
#define NUM_SMADS_PER_STRING  2  // could be 1, 2, or 4 (ideally any number from 1 up)

const int PinNeos[NUM_STRINGS] = {}; // THIS IS THE MAIN BIT THE USER WOULD "TWEAK" to add the appropriate number of pins.

What I want is some way to instantiate the NeoPixels to use the NUM_STRINGS (which could be 1 -- so an array of one element) and the number of SMADs per string.

??? Adafruit_NeoPixel instantiation

So, assuming we want to do something like turning each LED on to color red in turn, we could do something like:

for (int iStr = 0; istr < NUM_STRINGS; iStr++)


    for (int iSMAD = 0; iSMAD < NUM_SMADS_PER_STRING; iSMAD++)
        for (int iNeo = 0 iNeo < NUM_NEOS_PER_SMAD; iNeo++);
            neos[istr].setPixelColor( (iNeo + (iSMAD * NUM_NEOS_PER_SMAD)), 0xFF0000);

The more I look at the above, the more I think it's unfair of me to post this question -- but then I think you might say "Ah, Ha, of course!"

Thanks as always -- Max
[ - ]
Reply by beningjwJune 29, 2021

Lots of different ways to do this. My suggestion would be to use an EEPROM to store the configuration settings for the device. Use a serial interface to set the configuration, how many LED's, etc. 

You can then create an array for the maximum number of LED's, but only index in the array up to your configuration maximum. 

Then you have no need to recompile each time you change configurations. You can avoid using malloc or memory pools as well!

[ - ]
Reply by MaxMaxfieldJune 29, 2021
Hi Jacob -- I wish I had you in the same room as a whiteboard!!!
[ - ]
Reply by waydanJune 29, 2021

Hi Max,

Do you want the user to be able to reconfigure the display dynamically through a PC interface, or will changing the number of strings etc. require a recompile? If you can recompile, you might want to put all the user-set parameters and variables in a separate header file to make configuration easier.

You may want to avoid using #define to set the array size as this gives users two locations to edit.

#define NUM_STRINGS    2
const int PinNeos[NUM_STRINGS] = {/*...*/};

Now if I want to add or remove an object from PinNeos, I have to also update NUM_STRINGS. One way to get around this is to calculate the size of the array after declaration.

const int PinNeos[] = {/*declare my objects here*/};
const size_t num_strings = sizeof(PinNeos) / sizeof(*PinNeos);

You can then use num_strings in your loops, but users will only need to edit the declaration of PinNeos. Note that you cannot use this method to check the size of an array passed to a function because arrays are converted to pointers.

Best regards,

- Daniel

P.S. Your SMADs look awesome!

[ - ]
Reply by MaxMaxfieldJune 29, 2021

Hi Daniel -- thanks foe your suggestion -- very clever -- I learn something new every day :-)