How to read numbers from a txt file on an SD card into an array!

Hey guys,

I have a text file on an SD card and I would like to read this into an array on my Arduino.

The text file contains numbers in the form of:

1,2,3,4,5,6,7,8,9,10
1,2,3,4,5,6,7,8,9,10
1,2,3,4,5,6,7,8,9,10 .. etc, until 24 rows. So its 24*10 comma separated variables.

Writing it into an array of the form: array[24][10] (so pretty self explanatory).

I got this to work in a normal C compiler .. however once copied into the Arduino it did not work. I have now learned that you cannot just copy and paste things and expect them to work :stuck_out_tongue:

So, I have been looking around the internet/forums for code ideas and theres lots of posts out there but I cannot get something that actually works.

So far I have this:

#include <SD.h>

const int cs = 4;

int led[24][10],i=0,j=0;

void setup()
{
  Serial.begin(9600);
  
  Serial.print("Initializing card.");
  
  pinMode(53, OUTPUT);
  
  if (!SD.begin(cs)) 
  {
    Serial.println("Card failed to initialize or no card available");
  
    return;
  }
  Serial.println("Card initialized!");
  
  // open the file named ourfile.txt
  
  File myfile = SD.open("array.txt");

  // if the file is available, read the file
  if (myfile) 
  {
    while (myfile.available())
    {  
     
      //write array from file   
      for(i=0;i<24;i++)
      {
        for(j=0;j<10;j++)
        {
          led[i][j]=myfile.read();
        }
      }
      
    }
    myfile.close();    
    
  }  
  
  else {
    Serial.println("Cannot open file!");
  } 
}

void loop()
{

 //print out array to serial monitor
 for(i=0;i<24;i++)
 {
   for(j=0;j<10;j++)
   {
      Serial.write(led[i][j]);
   }
 }

 delay(10000000);
  
}

It .. kind of works but not really. When I read from the array in the void loop() it prints the first line from the file, then the last 5 lines and then a load of rubbish. So its definitely not right, its skipped 18 rows or something or its just put them into the array randomly - but it shows that the 'write' code has done something .. and like 5% of what it did was correct.

I assume its to do with the fact I haven't got anything here to actually skip the commas .. I was reading about strtok and parseint but I have never used them before and when I tried to figure them out - it gave me even more rubbish results than before!

If anybody could fix this for me then I would greatly appreciate it.
Thanks!

Havik:
Hey guys,

I have a text file on an SD card and I would like to read this into an array on my Arduino.

The text file contains numbers in the form of:

1,2,3,4,5,6,7,8,9,10
1,2,3,4,5,6,7,8,9,10
1,2,3,4,5,6,7,8,9,10 .. etc, until 24 rows. So its 24*10 comma separated variables.

Writing it into an array of the form: array[24][10] (so pretty self explanatory).

I got this to work in a normal C compiler .. however once copied into the Arduino it did not work. I have now learned that you cannot just copy and paste things and expect them to work :stuck_out_tongue:

So, I have been looking around the internet/forums for code ideas and theres lots of posts out there but I cannot get something that actually works.

So far I have this:

#include <SD.h>

const int cs = 4;

int led[24][10],i=0,j=0;

void setup()
{
 Serial.begin(9600);
 
 Serial.print("Initializing card.");
 
 pinMode(53, OUTPUT);
 
 if (!SD.begin(cs))
 {
   Serial.println("Card failed to initialize or no card available");
 
   return;
 }
 Serial.println("Card initialized!");
 
 // open the file named ourfile.txt
 
 File myfile = SD.open("array.txt");

// if the file is available, read the file
 if (myfile)
 {
   while (myfile.available())
   {  
   
     //write array from file  
     for(i=0;i<24;i++)
     {
       for(j=0;j<10;j++)
       {
         led[i][j]=myfile.read();
       }
     }
     
   }
   myfile.close();    
   
 }  
 
 else {
   Serial.println("Cannot open file!");
 }
}

void loop()
{

//print out array to serial monitor
for(i=0;i<24;i++)
{
  for(j=0;j<10;j++)
  {
     Serial.write(led[i][j]);
  }
}

delay(10000000);
 
}




It .. kind of works but not really. When I read from the array in the void loop() it prints the first line from the file, then the last 5 lines and then a load of rubbish. So its definitely not right, its skipped 18 rows or something or its just put them into the array randomly - but it shows that the 'write' code has done something .. and like 5% of what it did was correct. 

I assume its to do with the fact I haven't got anything here to actually skip the commas .. I was reading about strtok and parseint but I have never used them before and when I tried to figure them out - it gave me even more rubbish results than before!

If anybody could fix this for me then I would greatly appreciate it.
Thanks!

You are going to have to write a function that decodes the input stream from file.read().

I assume this is a class assignment.

You are going to have to interpret each byte that file.read() return.

Do some research on ASCII to binary conversions.

Chuck.

Not a class assignment - personal project.

Would it be simpler if I changed the file so its one number per line in terms of decoding it into the array?

So something like

5
81
43
32
7.. up to 240 numbers

I am creating the original text file from a desktop app I created before it is transferred via SD to the arduino so the format of the text file can be anything.

I'll take a look into conversions, thanks!

Ok, I have got something working! It reads the data from the text file and places it into the array correctly.

const int cs = 4;

void ReadCard()
{
  Serial.begin(9600);  
  Serial.print("Initializing card.");  
  pinMode(53, OUTPUT);
  
  if (!SD.begin(cs)) 
  {
    Serial.println("Card failed to initialize or no card available");  
    return;
  }
  Serial.println("Card initialized!");
  
  File myfile = SD.open("array3.txt");

  if (myfile) 
  {
    while (myfile.available())
    {  
      for(i=0;i<24;i++)
      {
        for(j=0;j<10;j++)
        {
          led[i][j]=myfile.parseInt();
        }
      }
      myfile.close();  
    }
  }  
  else {
    Serial.println("Cannot open file!");
  } 

  //print out array to serial monitor to check it worked
  for(i=0;i<24;i++)
  {
    for(j=0;j<10;j++)
    {
       Serial.println(led[i][j]);
    }
  } 
}

I looked up the 'pin 53' part - its used to select the SD card and is usually pin 53 on the Arduino Mega, but pin 10 on the Uno (I have an Uno). I changed 53 to 10 .. and the code stopped working. Yet it works with 53 even though pin 53 doesn't exist on the Uno?

Any idea what is going on there?

Also could you explain why we have the const int = 4, why 4?

Thanks!

Havik:
Ok, I have got something working! It reads the data from the text file and places it into the array correctly.

const int cs = 4;

void ReadCard()
{
 Serial.begin(9600);  
 Serial.print("Initializing card.");  
 pinMode(53, OUTPUT);
 
 if (!SD.begin(cs))
 {
   Serial.println("Card failed to initialize or no card available");  
   return;
 }
 Serial.println("Card initialized!");
 
 File myfile = SD.open("array3.txt");

if (myfile)
 {
   while (myfile.available())
   {  
     for(i=0;i<24;i++)
     {
       for(j=0;j<10;j++)
       {
         led[i][j]=myfile.parseInt();
       }
     }
     myfile.close();  
   }
 }  
 else {
   Serial.println("Cannot open file!");
 }

//print out array to serial monitor to check it worked
 for(i=0;i<24;i++)
 {
   for(j=0;j<10;j++)
   {
      Serial.println(led[i][j]);
   }
 }
}




I looked up the 'pin 53' part - its used to select the SD card and is usually pin 53 on the Arduino Mega, but pin 10 on the Uno (I have an Uno). I changed 53 to 10 .. and the code stopped working. Yet it works with 53 even though pin 53 doesn't exist on the Uno?

Any idea what is going on there?

Also could you explain why we have the const int = 4, why 4?

Thanks!

The pin53, pin10 is related to the actual SPI hardware in the AVR chip. The UNO (AVR ATMega328P) has the SPI hardware on pins 10,11,12,13. Pin 10 is the SlaveSelect pin or sometimes Called SS. Your SDcard has it's CS pin on Arduino Pin 4. If pin 10 is configured as and INPUT, and it is LOW, And any SPI tranfer is attempted, the AVR chip's hardware changes from SPI MasterMode(in control of the SPI bus) to SPI SLAVEmode(waiting for the 'SPI Master device' to command it). This causes you Sketch to Hang forever.

Pin53 is the SS pin for MEGA's (AVR ATMega2560). It acts the same way.

As a precaution, Most SPI example make sure the the SS pin (Uno 10, Mega 53) is configured as and OUTPUT and HIGH. The current SPI.h library initializes it this way during SPI.begin(). So, it can be ignored.

What is your Exact Hardware?
UNO? or MEGA?
What SDCard shield are you using?

I'm glad you found file.parseInt() :slight_smile:

We get a lot of entry level students that want others to do their homework for them. We try to give pointers but not do if for them.

Chuck.

Here's a way to do it, with error checking (by fat16lib).

Unfortunately, Chuck, it's a waste of your time because thta strategy doesn't end up helping anyone at all. I'm not sure why some of these forum threads rank so high in Google searches.

Thank you very much DaveEvans for posting a link to a post that really helps and addresses a question that many of us have. The only examples I could find all did a Serial.print of the results, and I was struggling to figure out how to put the results into a variable. The definitions are not in SD.h or SD.cpp, they are in the SDFat library which, to me, seems a little complex at first glance.