SD card: retrieve numerical data split into different variables

Hello,

(I am still a freshman...)
I am attempting to save numerical data in a SD card and retrieve it split into variables.

Number 1 into variable A

Number 2 into variable B

and

Number 3 into variable C

Below, you will see my sketch which I produced using bits from everywhere. (thanks to everybody)

Hence, my trouble is to find how to optimize / make my sketch better and foolproof.

Goal:
I am working on a system to check my electric bills, hence, log my electric power consumption and to avoid losing data whenever a power cut occurs (happens rarely, but it happens).
The following sketch is only a part of my final sketch (which I will certainly post here when it is finished).

So... if anyone is interested to have a look into my soup and to add salt and pepper, please feel free to do so.
--- for the moment, I used random numbers to simulate what has to be written on the SD card.
and ... I have a 3-phase electric system... (3x220v)

#include <SD.h>
void setup() {
  Serial.begin(115200);
  SD.begin(4);
  int A = 0;
  int AA = 0;
  int B = 0;
  int BB = -1;
  int C = 0;
  int CC = -2;
  char line[32];
  size_t line_length = 0;
  File file = SD.open("data.txt", FILE_WRITE | O_TRUNC);  // clean file on the SD card
  if (file) {

    for (uint8_t i = 1; i <= 3; ++i) {
      line_length = snprintf(line, sizeof(line), "%5hi", (int16_t)random(500, 600));  //formatting the random numbers and saving them on the SD card
      Serial.print("Writing at position ");
      Serial.print(i);
      Serial.print(" : \"");
      Serial.print(line);
      Serial.println("\"");
      file.println(line);
    }
    file.close();      //close the SD card file
    line_length += 2;  // count characters "\r\n" added by println
  }
  Serial.println();  //blank line to separate save and read/distributing into variables
                     // Following reads all lines from file
  file = SD.open("data.txt");
  if (file) {
    while (file.available() >= line_length) {
      static uint8_t line_id = 0;
      file.seek(line_id * line_length);  // go to line

 //saving the 3 numbers in 3 different variables
      if (AA == 0) {
        A = file.parseInt();
        AA = AA + 1;
        BB = BB + 1;
        CC = CC + 1;
      }
      if (BB == 0) {
        B = file.parseInt();
        BB = BB + 1;
        CC = CC + 1;
      }
      if (CC == 0) {
        C = file.parseInt();
        CC = CC + 1;
      }
      file.read(line, line_length - 2);  // read line without "\r\n"
      line[line_length - 2] = '\0';      // make sure to add null character to make a valid C-string
    }
    file.close();  //close the SD card file

// show that there are 3 numbers in the 3 variables - corresponding to the random numbers at the beginning
    Serial.print("A = ");
    Serial.println(A);
    Serial.print("B = ");
    Serial.println(B);
    Serial.print("C = ");
    Serial.println(C);
  }
}
void loop() {
}

result:

12:05:23.940 -> Writing at position 1 : "  510"
12:05:23.972 -> Writing at position 2 : "  527"
12:05:23.972 -> Writing at position 3 : "  590"
12:05:23.972 -> 
12:05:23.972 -> A = 510
12:05:23.972 -> B = 527
12:05:23.972 -> C = 590

another result:

12:08:20.552 -> Writing at position 1 : "  547"
12:08:20.552 -> Writing at position 2 : "  533"
12:08:20.552 -> Writing at position 3 : "  562"
12:08:20.597 -> 
12:08:20.597 -> A = 547
12:08:20.597 -> B = 533
12:08:20.597 -> C = 562

Thanks a million...

The usual way to save to SD card would be using comma separated values. Are you going to store multiple sets of data or just one.

You can read Serial Input Basics - updated to get some ideas; although it is intended for serial communication, the principles can be equally applied to reading from file. Example 2 will be suitable for the reading of a line from file.

Instead of Serial.something(), you open a file and use file.something().

It might have an advantage to replace

file.println(line);

by

file.print(line);
file.print("\n"); // add linefeed

When using the mentioned tutorial, you don't need to keep track of line_length, you will simply read to the '\n'.

How to convert the a text to a number can be found in example 4 and how to split received data on the comma can be found in example 5.

Note that example 5 uses < and > and not '\n' when reading serial.

1 Like

In addition, you can go with NMEA0183 GPS format and start the line with a '$' and end with a newline.

Ok, thanks SurferTim and sterretje for the quick response.

Are you going to store multiple sets of data or just one.
1 set of data will be saved every 12h.
I do not think I will need more for my project.
And the data will only consist of 3 numbers.
(I found a very small SD card (250 mb capacity))

sterretje
I will try to implement your idea...
As this is my 4th project, I am still overcomplicating my sketches...., but I am getting better...

SurferTim
I had this idea as I built a GPS clock. But I did not follow it up...
But now, as you advise me, I will see what I can do with the GPS format.

Keep you posted...
Eric

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.