Need to turn on pins in a Nested Array based on potentiometer values

Hi there. Blackfin and others helped me a few days ago with a project I was attempting, where I had 16 LEDs in a row and wanted to turn them on one at a time as the potentiometer was turned.
It was a success and I learned about arrays.

Now I am using most of that code to try something similar, but with 16 LEDS in a 4 x 4 matrix.
What I have done with the code is add in 35 more arrays that consist of pin numbers that I want to be turned on to form a shape. then when the potentiometer is turned it will cycle through the arrays I have and the shapes I have set up with the leds.
But, when I run my code, I get LED08 AND LED10 dimly lit and when i cycle through the potentiometer turn I only get LED07 AND LED09 to come on.

Could you review my code and see what I did wrong, and how to correct it?
Thank you in advance for your time and energy in helping me with this project.

//Start of Code
//16 LED Matrix Display Demo

//#define DEBUG 1  //uncomment to have val count up automatically

int val = 0;       // variable to store the value coming from the sensor
int mapval;
unsigned int mask;

//make your pin assignments "const" so the 
//compiler will catch if you try to modify them
//as you might with variables
const int potPin = A4;    //potentiometer input

//give the LEDs names for reader clarity
const int LED01 = 13;
const int LED02 = 12;
const int LED03 = 11;
const int LED04 = 10;
const int LED05 = 9;
const int LED06 = 8;
const int LED07 = 7;
const int LED08 = 6;
const int LED09 = 5;
const int LED10 = 4;
const int LED11 = 3;
const int LED12 = 2;
const int LED13 = A0;
const int LED14 = A1;
const int LED15 = A2;
const int LED16 = A3;

//put the LED names into an array. This makes
//it much cleaner to deal with large numbers
//of items like this (see setup() for an example)


//I want 16 preset designs so I need to make 16 arrays to call on.
const int Array01[] =
{ LED01, LED05, LED09, LED13
};
const int Array02[] =
{ LED01, LED02, LED03, LED04
};
const int Array03[] =
{ LED02, LED06, LED10, LED14
};
const int Array04[] =
{ LED05, LED06, LED07, LED08
};
const int Array05[] =
{ LED03, LED07, LED11, LED15
};
const int Array06[] =
{ LED09, LED10, LED11, LED12
};
const int Array07[] =
{ LED04, LED08, LED12, LED16
};
const int Array08[] =
{ LED13, LED14, LED15, LED16
};
const int Array09[] =
{ LED01, LED06, LED11, LED16
};
const int Array10[] =
{ LED04, LED07, LED10, LED13
};
const int Array11[] =
{ LED01, LED04, LED13, LED16
};
const int Array12[] =
{ LED06, LED07, LED10, LED11
};
const int Array13[] =
{ LED02, LED03, LED05, LED08, LED09, LED12, LED14, LED15
};
const int Array14[] =
{ LED01, LED04, LED06, LED07, LED10, LED11, LED13, LED16
};
const int Array15[] =
{ LED01
};
const int Array16[] =
{ LED01, LED02
};
const int Array17[] =
{ LED01, LED02, LED03
};
const int Array18[] =
{ LED01, LED02, LED03, LED04
};
const int Array19[] =
{ LED01, LED02, LED03, LED04, LED05
};
const int Array20[] =
{ LED01, LED02, LED03, LED04, LED05, LED06
};
const int Array21[] =
{ LED01, LED02, LED03, LED04, LED05, LED06, LED07
};
const int Array22[] =
{ LED01, LED02, LED03, LED04, LED05, LED06, LED07, LED08
};
const int Array23[] =
{ LED01, LED02, LED03, LED04, LED05, LED06, LED07, LED08,
  LED09
};
const int Array24[] =
{ LED01, LED02, LED03, LED04, LED05, LED06, LED07, LED08,
  LED09, LED10
};
const int Array25[] =
{ LED01, LED02, LED03, LED04, LED05, LED06, LED07, LED08,
  LED09, LED10, LED11
};
const int Array26[] =
{ LED01, LED02, LED03, LED04, LED05, LED06, LED07, LED08,
  LED09, LED10, LED11, LED12
};
const int Array27[] =
{ LED01, LED02, LED03, LED04, LED05, LED06, LED07, LED08,
  LED09, LED10, LED11, LED12, LED13
};
const int Array28[] =
{ LED01, LED02, LED03, LED04, LED05, LED06, LED07, LED08,
  LED09, LED10, LED11, LED12, LED13, LED14
};
const int Array29[] =
{ LED01, LED02, LED03, LED04, LED05, LED06, LED07, LED08,
  LED09, LED10, LED11, LED12, LED13, LED14, LED15
};
const int Array30[] =
{ LED01, LED02, LED03, LED04, LED05, LED06, LED07, LED08,
  LED09, LED10, LED11, LED12, LED13, LED14, LED15, LED16
};
const int Array31[] =
{ LED01, LED02, LED03, LED04, LED05,
  LED09, LED10, LED13, 
};
const int Array32[] =
{ LED01, LED04, LED05, LED08,
  LED09, LED12, LED13, LED14, LED15, LED16
};
const int Array33[] =
{ LED01, LED02, LED03, LED04, LED05, 
  LED09, LED13, LED14, LED15, LED16
};
const int Array34[] =
{ LED01, LED03, LED05, LED06, 
  LED09, LED10, LED13, LED15
};
const int Array35[] =
{ LED02, LED06,LED14
};

const int grpArrays[35] = 
{
    Array01, Array02, Array03, Array04,
    Array05, Array06, Array07, Array08,
    Array09, Array10, Array11, Array12,
    Array13, Array14, Array15, Array16,
    Array17, Array18, Array19, Array20,
    Array21, Array22, Array23, Array24,
    Array25, Array26, Array27, Array28,
    Array29, Array30, Array31, Array32,
    Array33, Array34, Array35
    
};

const int grpinLED[] = 
{
    LED01, LED02, LED03, LED04,
    LED05, LED06, LED07, LED08,
    LED09, LED10, LED11, LED12,
    LED13, LED14, LED15, LED16
    
};

void setup() {
  // put your setup code here, to run once:
  
//for debug messages
    Serial.begin(115200);

    pinMode( potPin, INPUT );

    //we use the array created above to set the
    //pinmodes for the LEDs. Using an array
    //and a for-loop saves many lines of code
    for( int i=0; i<35; i++ )
        pinMode( grpArrays[i], OUTPUT );  
        

}

void loop() {
  // put your main code here, to run repeatedly:
//if you uncomment the "#define DEBUG 1" line above
    //val will count up each loop and form an "LED chaser"
    //with the line commented, val will be set from the
    //analog channel
#ifdef DEBUG
    val++;
    if( val > 1023 )
        val = 0;
#else        
    val = analogRead(potPin);    // read the value from the sensor    
#endif    
    //the analog read will come back with a number
    //between 0 and 1023 (that's 1024 steps produced
    //by a 10-bit A/D converter.)
    //Here the map() function is used to shrink that
    //to a range from 0-16. This works out nicely
    //as you have 16 LEDs.
    //for val == 0, mapval = 0
    //for val ==512, mapval = 18
    //for val == ...
    //for val == 1023, mapval = 35
    //
    mapval = map( val, 0, 1023, 0, 35 );

    //this variable is used for debug; see the msg printed
    //at the end of loop()
    mask = 0;
    
    //here we go through 0-35 (36 values)
    //think of each value of i as representing an
    //LED position. For values of i less than
    //mapval, we turn the corresponding LED on;
    //(basically, all LED positions below mapval
    //should be turned on)
    //the array of LEDs above comes in handy here too
    for( int i=0; i<35; i++ )
    {
        //if i is the same as mapval, turn on that LED 
        if( i == mapval )
        {
            //mask is built here for the serial msg
            //the '<<' means a bit is shifted left
            //in this case, a '1' is shifted left
            //a mapval number of times; in the debug
            //msgs below this will be the '1' that
            //corresponds to the LED being on
            mask |= (1<<i);
            //use i to index into the the array to 
            //turn on the LED
            digitalWrite( grpArrays[i], HIGH );
        }//if
        else
        {
            //i is not equal to the mapval value so 
            //turn off this LED
            digitalWrite( grpArrays[i], LOW );
        }//else
            
    }//for

    //turn on the serial monitor and set the baud
    //rate to 115200
    //this part is just to show how the above checks
    //work. The '1' in mask corresponds to the LED
    //that is on. All the '0's are LEDs that are off.
    Serial.print( "For analog value " ); 
    Serial.print(val); 
    Serial.print(" LED mask = " );
    for( int i=35; i>=0; i-- )
        Serial.print( (mask&(1<<i)?"1":"0" ) );
    Serial.print( " (" ); 
    Serial.print( mask, HEX ); 
    Serial.print(")"); 
    Serial.print( " Mask was " );
    Serial.println( mapval );

    //delays aren't great but they're simple
    delay(5);
}

I have never heard the term “nested array” before.
Can you explain, please?

Um, well, maybe that isn't a thing. I made arrays, with led names inside. I then made an array that contained the names of all the other arrays. I want it so that when the potentiometer moves it switches from array01 to array02 to array03 and so on and so forth until the end of my arrays. So, not sure how to accomplish this but my thought process was use grpArrays to call up one of my arrays then turn on the pins in that array, until the potentiometer moves again. If you have any ideas on a better way to accomplish my goal, I am happy to accept help, criticism and instruction. Thanks!

The first thing that I see is this

const int grpArrays[35] = 
{

It suggests an array of ints. But it doesn't contain ints, it contains pointers to ints.

The second problem I think I see is that each element of this array (I think it's an Iliffe vector) carries no indication of how big it is. That could be awkward later.

        pinMode( grpArrays[i], OUTPUT );

The grpArrays array does NOT contain pin numbers.

You have 16 LEDs, their ‘pattern’ can be stored in a single uint16_t, each bit representing a LED.

You could just use one array for the LED pin numbers and one array for the designs.

So your code could look like (untested):

//16 LED Display Demo

const byte potPin = A4;
const byte ledPins[16] = { 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, A0, A1, A2, A3 };

//I want preset designs.
const uint16_t designs[] = {
  0x1111, 0x000F, 0x2222, 0x00F0, 0x4444, 0x0F00, 0x8888, 0xF000,
  0x8421, 0x1248, 0x9005, 0x0C60, 0x6996, 0x96E1, 0x0001, 0x0003,
  0x0007, 0x000F, 0x001F, 0x003F, 0x007F, 0x00FF, 0x01FF, 0x03FF,
  0x07FF, 0x0FFF, 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF, 0x131F, 0xECCC,
  0xF11F, 0x5335, 0x0222,
};

void setup() {
  Serial.begin(115200);
  for (auto pin : ledPins)
    pinMode( pin, OUTPUT);
}

void loop() {
  uint32_t topLoop = millis();
  static uint32_t lastPotCycle;
  if (lastPotCycle - topLoop >= 100) {
    lastPotCycle = topLoop;
    int val = analogRead(potPin);
    int mapval = map(val, 0, 1023, 1, sizeof(designs) / sizeof(designs[0])) - 1;
    uint16_t mask = designs[mapval];

    for (byte i = 0; i < 16; i++) {
      digitalWrite( ledPins[i], mask & (1 << i) ? HIGH : LOW);
    }
    Serial.print(F("For analog value "));
    Serial.print(val);
    Serial.print(F(" design was "));
    Serial.println( mapval );
    Serial.print(F(" LED mask = 0b"));
    Serial.print(mask, BIN);
    Serial.print(F(" 0x"));
    Serial.println(mask, HEX);
  }
}

Wow Whandall! That is amazing! I am going to solder up the wiring to my LED's tomorrow and then upload the code and let you know what happens. Thank you so much for the information and explanations. I love learning new things and implementing them.

If you have further questions, use this thread for them, not PMs.

Here is the requested “step through the patterns in a 500 ms on / off cycle” sketch (untested)

//16 LED Display Demo

const byte potPin = A4;
const byte ledPins[16] = { 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, A0, A1, A2, A3 };

//I want preset designs.
const uint16_t designs[] = {
  0x1111, 0x000F, 0x2222, 0x00F0, 0x4444, 0x0F00, 0x8888, 0xF000,
  0x8421, 0x1248, 0x9005, 0x0C60, 0x6996, 0x96E1, 0x0001, 0x0003,
  0x0007, 0x000F, 0x001F, 0x003F, 0x007F, 0x00FF, 0x01FF, 0x03FF,
  0x07FF, 0x0FFF, 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF, 0x131F, 0xECCC,
  0xF11F, 0x5335, 0x0222,
};

void setup() {
  Serial.begin(115200);
  for (auto pin : ledPins)
    pinMode( pin, OUTPUT);
}

void writePattern(uint16_t mask) {
  for (byte i = 0; i < 16; i++) {
    digitalWrite( ledPins[i], mask & (1 << i) ? HIGH : LOW);
  }
}

void loop() {
  uint32_t topLoop = millis();
  static uint32_t lastCycle;
  static byte currentPattern;
  if (lastCycle - topLoop >= 500) {
    lastCycle = topLoop;
    writePattern(currentPattern & 1 ? 0 : designs[currentPattern >> 1]);
    if (++currentPattern >= (2 * sizeof(designs) / sizeof(designs[0]))) {
      currentPattern = 0;
    }
  }
}