Storing bytes to an SD card?

I have an 2D array that i am using to store timer information in. (time to come on, time to go off, for each zone) and I had origininally planned to use EEPROM to do this.... however, the DUE does not have EEPROM :frowning: so that will not work.

So, i got an SD card reader and have it hooked up to the arduino, but thats as far as i've gotten with this.

I notice a lot of the examples require to you to have a .txt file. Is that required? All i want to do is write some bytes to the SD card, then if the DUE resets i want the due to check to see if there is information on the SD card, and if there is, load it into an array....

I see that a lot of the examples show "while((data = myFile.read()) >= 0) Seria.write(data)" but im not sure how to store that information into an array, rather than just print it out.

Any assistance would be greatly appreciated.

I notice a lot of the examples require to you to have a .txt file.

No, they don’t. People typically use text files so that they can read (and edit) the data. You can use any extension you like, and store ASCII or binary data in it.

I see that a lot of the examples show ‚Äúwhile((data = myFile.read()) >= 0) Seria.write(data)‚ÄĚ but im not sure how to store that information into an array, rather than just print it out.

  byte myData[512];
  int index = 0;

  while((data = myFile.read()) >= 0)
  {
     myData[index++] = data;
  }

Thanks for your answer.

That seems easy enough for a normal array, but what about a 2D array?

byte data;

  if (timerFile = SD.open("timerData.txt") {
  while ((data = TimerFile.read()) >= 0) {
      for (int j = 0; j < 9; j++) {
        for (int k = 0; k < 7; k++) {
          timerArray[i][j] = data;
        }
      }
    }
  }

and

byte counter;
  
  if (TimerFile.open("timerData.txt")) {
  while (TimerFile.read() >= 0 && counter < 63) {
      for (int j = 0; j < 9; j++) {
        for (int k = 0; k < 7; k++) {
          timerArray[j][k] = TimerFile.read();
          counter++;
        }
      }
    }
  }
  TimerFile.close();
}

to not seem to be working, but my method for writing to the file could also be suspect:

if (TimerFile.open("timerData", O_RDWR | O_CREAT | O_AT_END)) {
      for (int j = 0; j < 9; j++) {
          for (int k = 0; k < 7; k++) {
           TimerFile.print(timerArray[j][k]);
          }
        }
      }
    TimerFile.close();
  }

You posted 3 snippets of code, and said that they don't work.

You need to post ALL of one code, and explain what it actually does, and how that differs from what you want. Explaining how you know what it does would be a good thing.

Qdeathstar:
Thanks for your answer.

That seems easy enough for a normal array, but what about a 2D array?

byte data;

if (timerFile = SD.open(‚ÄútimerData.txt‚ÄĚ) {
 while ((data = TimerFile.read()) >= 0) {
     for (int j = 0; j < 9; j++) {
       for (int k = 0; k < 7; k++) {
         timerArray[i][j] = data;
       }
     }
   }
 }

a byte is defined to be an 8 bit value from 0 … 255. ALWAYS Positive or Greater than or equal to Zero.

So, if(byte>=0) will always be true.

Look at this code:

if (timerFile = SD.open("timerData.txt") {
  bool eof=false;
  int j=0;
  int k=0;
  while(!eof){  // until file is empty
    int data = TimerFile.read(); // get next byte
    eof = data < 0; // is the file empty!
    if (!eof) { // save the data into the array 
      timerArray[j][k] = data; // actually store the byte
      k++;
      if(k>6) { // filled a row of the array
        j++; // increment to next row.
        k=0; // start back at the first column element of the next array row.
        }
      if(j>8) { //the whole array has been filled
        break; // exit from the while Loop
        }
      }
    else {// end of file detected, abort loop
      break;
      }
    }

  if(eof) {// badness happend, the file was short!
    Serial.println(" the file was not as long as expected!");
    char buf[100]; // a character (string) buffer I will used to make an error message
    sprintf(buf,"The file only had %d bytes in it",((j*6)+k)-1);
    Serial.println(buf);
    if (k>0) k--; // calculate last filled element
    else { 
      if(j>0) { // ended on last element of prior row
        k=6;
        j--;
        }
      }
    // now, j and k point to the last filled element

    sprintf(buf,"So, the last element was timerArray[%d,%d], and it contains %d.",j,k,timerArray[j][k]);
    Serial.println(buf);
    }
  else Serial.println("Array filled");
  }
else Serial.println("could not open file");

Qdeathstar:

byte counter;

if (TimerFile.open(‚ÄútimerData.txt‚ÄĚ)) {
 while (TimerFile.read() >= 0 && counter < 63) {
     for (int j = 0; j < 9; j++) {
       for (int k = 0; k < 7; k++) {
         timerArray[j][k] = TimerFile.read();
         counter++;
       }
     }
   }
 }
 TimerFile.close();
}

what is the initial value of counter?

Your code reads a byte (well actually an int), checks to see if that int is greater than or equal to zero, throws the int away, then check if it has done the following 63 times:
Then reads the next 63 bytes [0…8,0…6]. Increments counter, (counter ==1)
Then reads the next 63 bytes [0…8,0…6]. Increments counter, (counter ==2)
Then reads the next 63 bytes [0…8,0…6]. Increments counter, (counter ==3)
Then reads the next 63 bytes [0…8,0…6]. Increments counter, (counter ==4)
Then reads the next 63 bytes [0…8,0…6]. Increments counter, (counter ==5)
Then reads the next 63 bytes [0…8,0…6]. Increments counter, (counter ==6)

… continue this loop until counter reaches 64 or you have read the entire file.

So each time through the loop, you try to read 64 bytes from the file, but you only use 63? Is this what you want?

Qdeathstar:
to not seem to be working, but my method for writing to the file could also be suspect:

if (TimerFile.open("timerData", O_RDWR | O_CREAT | O_AT_END)) {

for (int j = 0; j < 9; j++) {
         for (int k = 0; k < 7; k++) {
          TimerFile.print(timerArray[j][k]);
         }
       }
     }
   TimerFile.close();
 }

You do realize that print() makes human readable text from binary data, and write() stores machine readable text?

byte b=100;
print(b);  //results in 0x31 0x30 0x30  being stored in the file? (three characters '1' '0' '0')

//  While
write(b); // results in 0x64 being stored in the file? (one character 'd')

Chuck.