Arrays, 2D Arrays and nested for loops

I’m just wondering if this code would work. I’m trying to translate something I wrote in Python into C for Arduino and I’m not sure if I have the syntax/operations correct. In Python you can use the index of an item in one list (array) to reference an item of the same index in another.

I’m talking specifically about the ForNoteOn() and ForNoteOff() functions in the below code. I am using nested for loops as well as using the index of those iterated items in arrays (and a 2D array) to affect items of the same index/iteration in other arrays. I’m not sure if it works like this in C, but it compiles.

The code is like this (void setup() and void loop() left out, obviously):

#include <MIDI.h>                                            

#define LED 13                                               // LED = Pin 13

int dataPins[] = {2, 3, 4, 5, 6, 7};

int selPins[] = {9, 10, 11, 12, 14, 15, 16, 17};
int selVals[] = {0, 0, 0, 0, 0, 0, 0, 0};

// set the MIDI note values per select line

int notes[8][6] = {
  {48, 49, 50, 51, 52, 53},          
  {54, 55, 56, 57, 58, 59},
  {60, 61, 62, 63, 64, 65},
  {66, 67, 68, 69, 70, 71},
  {72, 73, 74, 75, 76, 77},
  {78, 79, 80, 81, 82, 83},
  {84, 85, 86, 87, 88, 89},
  {90, 91, 92, 93, 94, 95}
};


// -----------------------------------------------------------------------------------------------------

MIDI_CREATE_DEFAULT_INSTANCE();                              // Create an instance of the library with default name, 
                                                             // serial port and settings.

void readSelect(){                                           // Read Select lines
  for (int i = 0; i < 8; i++) { 
      selVals[i] = digitalRead(selPins[i]);
  }
}

// -----------------------------------------------------------------------------------------------------

// ForNoteON will be called by Midi Library when MIDI NOTE ON message is received.
// Bytes for Channel, Pitch, and Velocity.

void ForNoteOn(byte channel, byte pitch, byte velocity) {
   
  digitalWrite(LED,HIGH);                                     // LED off

  readSelect();                                              // Read Select lines
  
  for (int n = 0; n < 8; n++) {                              // For each select line (1-7) (*leave out 8 for now)
    if (selVals[n] > 0) {                                    // If that select line is HIGH
      for (int m = 0; m < 6; m++) {                          // Then for each note in each array in notes (1-6)
        if (notes[n][m] == pitch) {                          // if the mth note in the nth array is equal to the MIDI note
          digitalWrite(dataPins[m], HIGH);                   // write to equivalent mth data line (1-6).
        }        
      }
    }
  }  
}

Run it on the device and see?

Looks OK to me. As long as you are consistent as to how you index the 2D array.
Perhaps use indexing variables named uint8_t row, column so that you are less likely to get confused when indexing i.e. [row][column]

Just try it indeed

Side note - You are wasting memory for nothing as notes[l][r] is computable as 48+6*l+r with index l in 0..7 and r in 0..5

Thanks for the replies.

mistergreen: Run it on the device and see?

I'd love to! But my Arduino hasn't arrived yet and I'm currently repairing the thing I'll be interfacing it with (a synthesizer). I'm really just asking about the syntax/correctness of the code.

boylesg: Looks OK to me. As long as you are consistent as to how you index the 2D array. Perhaps use indexing variables named uint8_t row, column so that you are less likely to get confused when indexing i.e. [row][column]

Thanks. Good to hear that. Yeah, better named variables would be less confusing for sure. Is it okay to index as I did?

As in, what I want to do is: 1) loop through each item in the array selVals[], 2) if that item is high/non-zero, check if an item in the corresponding sub array of notes[] is equal to the incoming data byte. 3) If this is true, I want to then send an output to the corresponding pin in dataPins.

If that makes any sense!

Yes it will work. As I said you can compute the value, no need for the array of notes (and if you want to keep it make them at least byte to match what you'll be testing against and save half the memory)

if (notes[n][m] == pitch) could be if (48+6*n+m == pitch)

if (selVals[n] > 0)is ok but could just be for readability if (selVals[n] == HIGH)

After you find the right pitch and have done digitalWrite(dataPins[m], HIGH);, you could break; out of your loop as you will not find another value matching, so no point keeping looking.

digitalWrite(LED,HIGH);  // LED off the comment does not match what you do

Break is a great idea, thanks. You're right about it being computable, I'll have a look at that tomorrow morning.

digitalWrite(LED,HIGH);  // LED off the comment does not match what you do

Oops :)