Accessing values read from an SD card in setup() and loop()

So I am trying to read in a matrix of values from an SD card, and I am successfully doing so. Ideally, I would do this reading in of the matrix via a function called in the setup(), and be able to manipulate the data inside of the matrix in loop(). However, I am uncertain how to allow the matrix to be “seen” by setup() and loop(), as the matrix is defined within my ReadCardInfo function.

Normally I would just define the matrix before the setup() part in order to make the variable a global variable, but unfortunately I only know the size of the matrix when I open the SD card and read in the first line (this first line contains the dimensions). Alternatively I would just make the matrix be an output to the function, but I can’t seem to get the function to allow matrix outputs.

So, any suggestions on how to allow this matrix to be seen?

Here is the code as I have it so far, which reads in an SD card and saves it into the matrix I want to access called myMatrix:

#include <SD.h>

const int chipSelect = 4;
char fileName[] = "circlel.txt";

void setup(){
//Read in the SD card info
ReadCardInfo(fileName);
}

void loop(){
  
}

void ReadCardInfo(const char *fileName)
{
  Serial.begin(9600);
  Serial.print("Initializing Card");
  

  Serial.println();
  
  //Make sure the card is valid
  if (!SD.begin(chipSelect))
  {
    Serial.println("initialization failed");
    while(1);
  }
  Serial.println("Card initialized!");
  delay(1000);

  //Read in the file
  File myText = SD.open(fileName);

  //Make sure the file is valid
  if (myText){
    Serial.println("good");
  }
  else{
    Serial.println("bad");
    while(1);
  }

   //Get the number of rows and columns of the matrix (this will always be the first line of the text file)
   int    rowNum = myText.parseInt();
   int     colNum = myText.parseInt();

   //Initialize the matrix
    float myMatrix[rowNum][colNum];

  if (myText){
    if (myText.available()){
    
    //For each row and column,
      for (int i=0; i < rowNum; i++){
        for (int j=0; j < colNum; j++){
          //Read in the next float
          float c = myText.parseFloat();

          //Save that value into the matrix
          myMatrix[i][j] = c;
        }
      }
      myText.close();
    }
  }

  Serial.println("Done");


  //For testing purposes, print the contents of the SD card to Serial
  for (int i=0; i< rowNum; i++){
    for (int j=0; j < colNum; j++){
      Serial.print(myMatrix[i][j]);
      Serial.print(" ");
    }
    Serial.println("");
  }

  
}

sarallen:
However, I am uncertain how to allow the matrix to be "seen" by setup() and loop(), as the matrix is defined within my ReadCardInfo function.

Never heard of global variables?

I suggest a C programming class!

.

Yes, I have heard of global variables. But I though the only way to make them was to initialize the variable outside of setup() and loop(), at the start. But my problem is that I do not know the size of myMatrix to begin with; that variable's size is only found in my ReadCardInfo function. So how am I supposed to initialize myMatrix as a global variable if I don't know its size?

Or is there a different way of defining global variables?

There's a couple of ways to do this. The 'Arduino way' is to set aside some global storage which is larger than you could ever want to use. If you think you could never ever possibly have more than 100 items, then just assign an array of length 100. The compiler will warn you if you run out of memory.

The 'C way' is to have a global pointer. As the array expands, use malloc() to allocate more memory. This will work fine on the Arduino until you accidentally allocate more memory than the Arduino has available. Then unpredictable things happen. None of them good.

The 'C++ way' is to create a class to store the data and the methods which operate on the data. This can be done on the Arduino as it is C++ underneath but you end up choosing one of the above methods inside the class.