Reading from a text file with SD Card

I am not too familiar with arduino

I not only need to read from the text file, but i need to store the data into an array.
I want to do something similar to what loadtxt() does in python

basically myArray[]=loadtxt('myFile')

text file contains :
1 11
106 5
52 7
31 20
....

  • (values do not matter/are random, number of values are unknown/ can change depending on text file)

this is where i think i am having trouble -->Serial.println(dataFile.read());
Serial.write(dataFile.read()) prints the right values, however i need to store these values in a variable of some sort

#include <SPI.h> //SD card headers
#include <SD.h>

using namespace std; 

/////////////////////////////////////////////////////
const int buttonPin = 2; //button pin = Pin 2, input pin
const int ledPin = 12; // output pin=pin12, lights up led
int buttonPinState=0; //button presses or not pressed, HIGH/LOW
bool programEnd= false; // has reached end of array
/*
int Array [] [] = {
  //as many vals as dim1
 {2,5},
 {3,7},
 {6,8},
 {9,10},
 {11,13}//as many rows as dim0
};
*/
int counter=1; // used to compare values executed vs values stored
volatile int sizeArray=0; //global varable, size of array text file

int index1=0; //array index
int index2=0; //array index 2

File dataFile; //file variable name 
/////////////////////////////////////////////////////////////////////////////////////
void setup() {
  int i = 0;
  int j = 0;
  ///////////////////////////////////////////////////////////////////////////
  pinMode(buttonPin, INPUT); //button as input
  pinMode(ledPin, OUTPUT); //led as output
  Serial.begin(9600); //start serial
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }
  ////////////////////////////////////////////////////////////////////////
  //initalize SD card
  Serial.print("Initializing SD card...");
   if (!SD.begin(4)) {
    Serial.println("initialization failed!");
    return;
  }
  Serial.println("initialization done.");

  if (SD.exists("example.txt")) {
    Serial.println("example.txt exists.");
  } else {
    Serial.println("example.txt doesn't exist.");
  }
  /////////////////////////////////////////////////////////////////////////
  dataFile = SD.open("example.txt"); // open txt file
  ////////////////////////////////////////////////////////////////////////
  // import data to an array
  if (dataFile){         
    while (dataFile.available()){ 
      Serial.println(dataFile.read()); 
    }//end of while loop
  }//end of if statement  
  
  //sizeArray=sizeof(textValues)/4; //array size is 5
}

void loop(){
  buttonPinState=digitalRead(buttonPin);

  if(buttonPinState==HIGH && programEnd==false){
   digitalWrite(ledPin, HIGH);
   //Serial.print(textValues[index1][index2]);
   index2++;
   Serial.print("\t");
   //Serial.println(textValues[index1][index2]);
   delay(2000); 
   index2++;
   if (counter>=sizeArray){
    programEnd=true;
    } 
   counter++;
  }
  digitalWrite(ledPin, LOW);
  delay(500);
}

I figured a bit of it out.
whenever file.read() is called, an ascii number is read
so 1 = 49
carrage return = 13
new line read = 10
2=50

so if i had a txt file that had

1
2

while(available){
Serial.Println(file.read())
}

would print:

49
13
10
50

need to store these values in a variable of some sort

An array is the obvious place to store the values
Read a byte
Put it in the array at the current position
increment the array position variable
Repeat until the end of the file or the array is full

Note that

int Array [] [] = { etc

will not compile as all dimensions except the first must be declared

What do you intend to do with the values after reading them and how many of them are there ?

I need this text file to be flexible
so there isn't a set amount of variables
i need the code to work without knowing the amount of variables
just detect when the end of the file is reaches and the array size adjusts to the size of the text file
I could use a filler size to start out with.. then append to increase the size of the array.

I am thinking then i would need to filter out every 13 and 10 that i receive
then use a vector "push back" to start appending into variables

the variables are going set the angle of stepper motors i am attaching to the Arduino and determine which stepper motor is picked

ex

1=stepper motor 1
2=stepper motor 2

20=20 degrees
30=30 degrees

1 20
2 30

would mean, stepper motor 1 move 20 degrees then stepper motor 2 move 30 degrees.

the array size adjusts to the size of the text file

You cannot do that. You need to declare the array at the maximum size expected. If you are worried about memory usage then if the array will need to be a certain size at some time in the future then it will take just as much whether sized at compile time or dynamically sized.

If you read the characters from the SD card, put them in an array of chars and terminate the characters with a '\0' in the next position then you will have created a Cstring (NOTE : not a String) which you can use/manipulate in your program

I see. yeah since it is ASCII it is a char. then translate it to what i want which is an integer.
thanks for the help. :slight_smile:

update: working conversion from Ascii to int
char i='0';
int j=0;

if (dataFile){
while (dataFile.available()){
i=dataFile.read();
j=i-'0';
if(j>=0){
Serial.println(j);}
}//end of while loop
}//end of if statement

WynnNi:
update: working conversion from Ascii to int
char i='0';
int j=0;

if (dataFile){
while (dataFile.available()){
i=dataFile.read();
j=i-'0';
if(j>=0){
Serial.println(j);}
}//end of while loop
}//end of if statement

Don't you think that you ought to check that the character you read from the file IS a digit, before you blindly subtract '0 from it? Suppose that the file contains "Frogs can't swim". Your code will produce absolute nonsense.