Read array names from another array

I have some LEDS that are grouped...let's assume I have 10 LEDs in four groups as follows

Group 1
LEDs 1, 3 and 5
Group 2
LEDs 2 and 4
Group 3
LEDs 6,7,8
Group 4
LEDs 9 and 10

to control them it would be helpful to assign these values to arrays as follows

byte downstairs[3] = {1,3,5};
byte upstairs[2] = {2,4};
byte garden[3] = {6,7,8};
byte shed[2] = {9,10};

ideally, I'd assign them all to one multidimensional array with
"groups[4][x]", but since the size of each array varies, that is not possible (I think, please correct me if I'm wrong)

I have tried to set up another array as follows;

String groups[4] = {String("downstairs"), String("upstairs"), String("garden"), String("shed")};

I was hoping that by using for and next loop with i and j I would be able to read the arrays as follows;

value = groups[i][j];

BUt it's not working - I can see why, it's probably trying to read "Groups" as a two dimensional array - but I can't figure out how to get it to recognise "

groups[i]

" as the array name follow by "[j]" as the element within that array.

Suggestions please?

By the way - the LEDs are WS2812bs, so they’re all on one pin, otherwise I can see it would have been easier to simply use the different pin numbers…

I suspect pointers may be the answer…but I’m not that familiar with them…

Lots of ways to skin this cat.
You could use a simple 2D array, and maybe waste a few elements, but most solutions are going to need a means of identifying the number of elements used, possibly using the first element to hold the number of elements, or a terminating impossible value, like a negative number.

String or strings isn’t going to work because after compilation, array names no longer exist.

GreyArea:
I was hoping that by using for and next loop with i and j I would be able to read the arrays as follows:value = groups[i][j];

Suggestions please?

Use pointers.

const byte downstairs[3] = {1, 3, 5};
const byte upstairs[2] = {2, 4};
const byte garden[3] = {6, 7, 8};
const byte shed[2] = {9, 10};


const byte groupCount = 4;
const byte *groups[groupCount] = {downstairs, upstairs, garden, shed};
const byte groupLengths[groupCount] = {3, 2, 3, 2};


void setup()
{
  for (byte i = 0; i < groupCount; i++)
  {
    for (byte j = 0; j < groupLengths[i]; j++)
    {
      byte value = groups[i][j];
    }
  }
}
void loop() {}

johnwasser:
Use pointers.

Technically, an Iliffe vector.

AWOL:
Lots of ways to skin this cat.
You could use a simple 2D array, and maybe waste a few elements, but most solutions are going to need a means of identifying the number of elements used, possibly using the first element to hold the number of elements, or a terminating impossible value, like a negative number.

String or strings isn't going to work because after compilation, array names no longer exist.

Issues with the 2D array that may or may not be down to my inexperience.

  • Final array sizes could be considerably larger...from 50 elements down to 5...so quite a lot of waste.
  • since some of the code is quite complex, one of the reasons for reducing the array size was to reduce execution time...ie to operate only on the two elements in "shed" rather than all ten...I guess your impossible terminator might fix that...

As to pointers...yeah, I kind of dimly know they could help, just not exactly sure how...I'll go google...thanks all.

As to pointers...yeah, I kind of dimly know they could help, just not exactly sure how.

There's a worked example in reply #3
(I'd probably make better use of "sizeof" to populate the "groupLengths" array)

AWOL:
There's a worked example in reply #3
(I'd probably make better use of "sizeof" to populate the "groupLengths" array)

LOL...measure of my noobness...didn't scroll the code window down so only saw the setup part...I'll go play with the new toy...

If you want to retrieve the group values by location name you could keep all the values in a flat array and set indices into it at run time, making it easier to maintain. A structure could hold the location names, index into the array and the number of elements for that location.

/*
byte downstairs[3] = {1, 3, 5};
byte upstairs[2] = {2, 4};
byte garden[3] = {6, 7, 8};
byte shed[2] = {9, 10};
*/

// values for led groups
byte ledGroups[] = {1, 3, 5, 2, 4, 6, 7, 8, 9, 10};

// details of each group
typedef struct {

  char name[15];
  byte startIdx;  // index into ledGroups array, set at runtime
  byte count;     // # of elements in group

} ledgroup;

ledgroup ledInfo[] = { {"downstairs", 0, 3}, {"upstairs", 0, 2}, {"garden", 0, 3}, {"shed", 0, 2}};

byte groupCount; // # of groups

void setup()
{
  Serial.begin(9600);

  groupCount = sizeof(ledInfo) / sizeof(ledInfo[0]);

  // set indices of each group
  byte idx = ledInfo[0].count;

  for (int i = 1; i < groupCount; i++)
  {

    ledInfo[i].startIdx = idx;  // set index
    idx += ledInfo[i].count;    // bump to next group

  } // for

  // show values for each group
  for (int i = 0; i < groupCount; i++) showValues(i);

  // values based on name
  Serial.println("By name:");
  showValuesByName("upstairs");

}

void showValues(int grpIdx) {

  Serial.println(ledInfo[grpIdx].name);

  // starting and ending index for each group
  byte startIdx = ledInfo[grpIdx].startIdx;
  byte endIdx = startIdx + ledInfo[grpIdx].count;

  // print values from array
  for (int i = startIdx; i < endIdx; i++)
  {
    Serial.println(ledGroups[i]);
  }

}

void showValuesByName(char *name)
{

  // look at each group
  for (int i = 1; i < groupCount; i++)
  {
    // if this is the one we want
    if (!strcmp(name, ledInfo[i].name) )
    {
      showValues(i);
      break;

    }

  }

}


void loop()
{


}

To be a little more robust:

const byte downstairs[] = {1, 3, 5};
const byte downstairsCount = sizeof downstairs / sizeof downstairs[0];
const byte upstairs[] = {2, 4};
const byte upstairsCount = sizeof upstairs / sizeof upstairs[0];
const byte garden[] = {6, 7, 8};
const byte gardenCount = sizeof garden / sizeof garden[0];
const byte shed[] = {9, 10};
const byte shedCount = sizeof shed / sizeof shed[0];

const byte groupCount = 4;
const byte *groups[groupCount] = {downstairs, upstairs, garden, shed};
const byte groupLengths[groupCount] = {downstairsCount, upstairsCount, 
                                                                   gardenCount, shedCount};

Still reading...Blue Eyes, one solution I did consider was indexing the LEDs by group, rather than groups by LED (ie, having a ten element array where the element values were 1,2,3 - so where you had;

// values for led groups
byte ledGroups[] = {1, 3, 5, 2, 4, 6, 7, 8, 9, 10};

I had;

// values for led groups
byte ledGroups[] = {1, 2, 1, 2, 1, 3, 3, 3, 2, 2};

It works, but again I'm stepping through ALL the LEDS where I'd like to be able to step through just the one group...

I'm still looking at pointers...I'm sure if I just dropped this into the sketch it would work, but I'm trying to get my head around HOW it works...the relationship between the value and the address, when and how it changes, etc. and where to conbfidently and correctly use either * or $...

If you look at the code in reply #3, you’ll see that the pin numbers in the room-named arrays are all unique - this doesn’t have to be so, if, for example you have a hallway light that could also be considered to be in, say, the living room.

johnwasser - thank you...pasted your code with some sligth changes into my sketch and it's working...!

AWOL:
If you look at the code in reply #3, you'll see that the pin numbers in the room-named arrays are all unique - this doesn't have to be so, if, for example you have a hallway light that could also be considered to be in, say, the living room.

Yes, thanks for drawing my attention to that...an LED that is controlled by two groups would be odd though...it's for a model and the LEDs are "pretending" to be different kinds of light sources...some are soft glow, some are fluorescent striplights. The groups will control the animations, and an animation that's appropriate for a fluorescent light (eg a random "flicker") might not be appropriate for a soft underfloor light.

But...it is still good to know as all these things may change!