Get a value from SDCARD txt file

Hello everyone. Im working on a program using a sd card module.. im planning to get the value of a certain int or char from a sd card .txt file

For example txt file contain this:

1
2
3
4
5

I want int1 = 1 (the first line on the sdcard text file) so whenever i call int1 in the program, its value is equal to 1.. then int2 = 2. Then int3 = 3 and so on..

And if i change the txt file for example:

5
10
15
20
25

Int 1 = 5. Because 5 is the first line on the txt file.. then
Int2 = 10
Int3 = 15 and so on..

I will be updating the value frequently.. it would be much easier to edit a text file for changing the value of the int or char.. rather than editing the sketch or ino file.

Hope u get what i mean..

int arr[ARRAY_SIZE];
File file = SD.open(....);
for (int i = 0; i < ARRAY_SIZE && file.available(); i++) {
 arr[i] = file.parseInt();
}
file.close();

Juraj:
int arr[ARRAY_SIZE];
File file = SD.open(…);
for (int i = 0; i < ARRAY_SIZE && file.available(); i++) {
arr = file.parseInt();
}
file.close();
[/quote]
Could you explain what each line of code do? Thanks!

Help?

projectdimpreza:
Help?

What kind of question is that?

PaulS:
What kind of question is that?

Im new to programming sorry

projectdimpreza:
Im new to programming sorry

Writing in English, too, apparently.

Because juraj can never be bothered to use code tags, the code that was posted was mangled by the forum software. It should have been:

int arr[ARRAY_SIZE];
File file = SD.open(....);
for (int i = 0; i < ARRAY_SIZE && file.available(); i++)
{
  arr[i] = file.parseInt();
}
file.close();

It creates an array, uselessly named arr.
It opens some undefined file, using some undefined mode. YOU are supposed to open the correct file, the correct way.

It then reads data from the file, and converts each token that is found to a long, and stores the result in the int array. The for loop ends when the end of the file is reached, or the array is filled.

Finally, it closes the file.

You COULD have looked up each statement to learn the same thing.

PaulS:
Writing in English, too, apparently.

Because juraj can never be bothered to use code tags, the code that was posted was mangled by the forum software. It should have been:

int arr[ARRAY_SIZE];

File file = SD.open(…);
for (int i = 0; i < ARRAY_SIZE && file.available(); i++)
{
  arr[i] = file.parseInt();
}
file.close();



It creates an array, uselessly named arr.
It opens some undefined file, using some undefined mode. YOU are supposed to open the correct file, the correct way.

It then reads data from the file, and converts each token that is found to a long, and stores the result in the int array. The for loop ends when the end of the file is reached, or the array is filled.

Finally, it closes the file.

You COULD have looked up each statement to learn the same thing.

Ok heres whats inside the text file…

1
2
3
4
5

I want “1” to be int1
“2” to be int2
“3” to be int3
“4” to be int4
“5” to be int5

So evertime i call int1 the value it will give me is “1”… i want to display the value on a lcd…

If i call int3 the value it will display on lcd is “3”
you get the idea…

Each line on the sdcard text file has a int value… so how to i do that?

projectdimpreza:
you get the idea..

I can only speak for myself, but I haven't the foggiest

projectdimpreza:
Ok heres whats inside the text file..

1
2
3
4
5

I want "1" to be int1
"2" to be int2
"3" to be int3
"4" to be int4
"5" to be int5

So evertime i call int1 the value it will give me is "1".. i want to display the value on a lcd..

If i call int3 the value it will display on lcd is "3"
you get the idea..

Each line on the sdcard text file has a int value.. so how to i do that?

you want numbers or text? what type are int1 to int5?
for numbers:

  File file = SD.open(....);
  int1 = file.parseInt();
  int2 = file.parseInt();
  int3 = file.parseInt();
  int4 = file.parseInt();
  int5 = file.parseInt();
  file.close();

Juraj:
you want numbers or text? what type are int1 to int5?
for numbers:

  File file = SD.open(....);

int1 = file.parseInt();
  int2 = file.parseInt();
  int3 = file.parseInt();
  int4 = file.parseInt();
  int5 = file.parseInt();
  file.close();

So how do i select line 3 in the sd card text file.. and make its value to int3?

projectdimpreza:
So how do i select line 3 in the sd card text file.. and make its value to int3?

you read all the previous lines

Juraj:
you read all the previous lines

Which in practice, since SD cards actually deal in characters, means you have to look for \r or \n or whatever's in your file to demarcate the lines and keep count how many you've encountered.

Open your file in Notepad++ and go View > Show symbol > Show end of line and you will see what line end characters you have. (Probably one or both of CR and LF.)

See here for a handy SD car hex dump.

I want "1" to be int1
"2" to be int2
"3" to be int3
"4" to be int4
"5" to be int5

It sounds to me that you would be better off using an array.

Using an array would make it easy for int[1] be say 1 and for it to be changed later so that int[1] is set to any other value you want.

Using a better name for the array would be a good idea

Sorry i dont really understand how to count \r or \n

I get the idea that every enter in the text file has a delimiter.. but i dont know how the code posted above will stop reading at the 3rd \r \n.
If example i want to get just the 3rd line.

Could somebody explain what each line of the code do?

To clear things up.. the project is a vending machine.. i want the price to be displaying on the lcd.. and price change everytime so i was thinking to get the price value from a sdcard txt file.. to make it easier.. instead of editing the whole sketch just to change the price..

The lcd would display the price together with the item name.. Something like this..

$1/item

And the txt file is like this..

1,item1
2,item2
3,item3

First charcter is the price then comma then item name.

Or if any of you guys have a better idea of doing this.. feel free to comment..

projectdimpreza:
Sorry i dont really understand how to count \r or \n

Doesn't #5 over here where you're also active, do what you want?

neiklot:
Doesn't #5 over here where you're also active, do what you want?

Let me try.. so how do i assign a name once i got the value of the line im looking for?

Example if the third line is is "3"

I will call "price3" in my code and it will display "3" on lcd.. like this..

lcd.print(price3);

Will display "$3/item3" on lcd

There is not much difference between reading from Serial and reading from SD; the underlaying mechanisms are the same and most methods (or all) that are available for the Serial class are also available for the SD class. In the SD reference, you will not find a reference to readBytesUntil but it is available and you can check the Serial reference to find how to use it.

You can try the below code and see if it works; it compiles but I can not test. It simply reads the file line by line and displays relevant information

It does not contain code for a button yet but I have indicated where you can implement that.

Study and understand it
2)
Test it; a line (in hex) will probably look like

33 30 0D

with maybe a 0A after the 0D. For further help, you have to provide the hex values that the code prints for a line so I can help you to clean up if needed

Note that the code does not use strtok but strchr.

#include <SPI.h>
#include <SD.h>

const int chipSelect = 4;

File dataFile;


void setup()
{
  // Open serial communications and wait for port to open:
  Serial.begin(9600);
  while (!Serial)
  {
    ; // wait for serial port to connect. Needed for native USB port only
  }


  Serial.print("Initializing SD card...");

  // see if the card is present and can be initialized:
  if (!SD.begin(chipSelect))
  {
    Serial.println("Card failed, or not present");
    // don't do anything more:
    while (1);
  }
  Serial.println("card initialized.");

}

void loop()
{
  // variable to hold a line
  char line[10];
  // clear the buffer
  memset(line, '\0', sizeof(line));

  // open the file
  dataFile = SD.open("prices.txt");

  // if the file is not available
  if (!dataFile)
  {
    Serial.println("error opening datalog.txt");
    // hang forever
    for (;;);
  }

  // read the records in the file
  while (dataFile.available())
  {
    // read a line
    size_t numChars = dataFile.readBytesUntil('\n', line, sizeof(line) - 1);
    // print the number of characters in the line
    Serial.print("Number of charaters read = "); Serial.println(numChars);
    // print the line
    Serial.print("Line = "); Serial.println(line);

    // print the line in hex so we can see what is in there exactly
    for (uint16_t cnt = 0; cnt < strlen(line); cnt++)
    {
      if (line[cnt] < 0x10)
      {
        Serial.print("0");
      }
      Serial.print(line[cnt]);
      Serial.print(" ");
    }
    Serial.println();

    // a pointer  that will point to the validity after splitting the line
    char *validity;
    // find comma
    validity = strchr(line, ',');
    if (validity == NULL)
    {
      Serial.println("No comma separated record");
    }
    else
    {
      // replace comma by terminating nul character
      // this will result in line actually 'containing' only the price
      *validity = '\0';
      // increment pointer so it points to first character of validity
      validity++;
      Serial.print("price = "); Serial.print(line);
      Serial.print(" validity = "); Serial.println(validity);
    }
    // you can replace this delay by button code
    delay(2000);
  }

  // close the file
  dataFile.close();

  // if you use a button, you can omit this delay
  delay(5000);
}

Note that this is only a guide; it’s not quite perfect but should work.

I'm going to ask the mods to close this thread. It's basically about what the OP here asked about in this hijacked thread and this one of his own where there was a partial solution weeks ago and where I gave a solution for the latest requirements yesterday. Not saying my solution's perfect of course, but it makes more sense to me to add new contributions here.

Locked as requested.

(There is no such thing as "close thread" so I went with what seemed like the next closest thing.)