SD config and data save

DoDobro!
Posts: 14
Joined: Mon Oct 02, 2023 4:39 pm

SD config and data save

Postby DoDobro! » Wed Oct 04, 2023 8:41 am

Hello,

I'm the newby so excuse my too simple questions please, but still please help with them.

I need to open config file from SD and then write data to another file at SD.

I'm search at google and find pretty powerful sample but because of lack of experience at this area I just can't understand of how exactly does it work?? What exactly each stroke of this code are doing?! Why it have some "F()" operator? Why function "const __FlashStringHelper" multiply by text key?! Such monstrously intricate code is just confuse me!
https://arduinogetstarted.com/tutorials ... om-sd-card

Code: Select all

myInt_1    = SD_findInt(F("myInt_1"));
int SD_findInt(const __FlashStringHelper * key) {
  char value_string[VALUE_MAX_LENGTH];
  int value_length = SD_findKey(key, value_string);
  return HELPER_ascii2Int(value_string, value_length);
}
int SD_findKey(const __FlashStringHelper * key, char * value) {
  File configFile = SD.open(FILE_NAME);

  if (!configFile) {
    Serial.print(F("SD Card: error on opening file "));
    Serial.println(FILE_NAME);
    return;
  }

  char key_string[KEY_MAX_LENGTH];
  char SD_buffer[KEY_MAX_LENGTH + VALUE_MAX_LENGTH + 1]; // 1 is = character
  int key_length = 0;
  int value_length = 0;

  // Flash string to string
  PGM_P keyPoiter;
  keyPoiter = reinterpret_cast<PGM_P>(key);
  byte ch;
  do {
    ch = pgm_read_byte(keyPoiter++);
    if (ch != 0)
      key_string[key_length++] = ch;
  } while (ch != 0);

  // check line by line
  while (configFile.available()) {
    int buffer_length = configFile.readBytesUntil('\n', SD_buffer, 100);
    if (SD_buffer[buffer_length - 1] == '\r')
      buffer_length--; // trim the \r

    if (buffer_length > (key_length + 1)) { // 1 is = character
      if (memcmp(SD_buffer, key_string, key_length) == 0) { // equal
        if (SD_buffer[key_length] == '=') {
          value_length = buffer_length - key_length - 1;
          memcpy(value, SD_buffer + key_length + 1, value_length);
          break;
        }
      }
    }
  }

  configFile.close();  // close the file
  return value_length;
}
Is it possible at Arduino IDE assign values from config file to firmware variables much easier, logically like:

Code: Select all

for ( int i = 1; while configFile line i exist ; 1) {
  var_name = read text before symbol "=" from configFile line i;
  var(var_name) = read text after symbol "=" from configFile line i;
}
Can you help with a such code, please!

And about data logging to SD is it possible to write data to one file all the time continuously and time-to-time as single action write data to another new files? For example all the time write "data_logging.txt" and once per 1min write "data_summary_DATATIME.txt" simultaneously without files reopening or it still require to open-close-open-write-reopen-write etc each file on each writing?? (OMG)

lbernstone
Posts: 831
Joined: Mon Jul 22, 2019 3:20 pm

Re: SD config and data save

Postby lbernstone » Wed Oct 04, 2023 5:38 pm

F() and flashstringhelper are from older devices (eg, esp8266) to map strings directly from ROM. const char* does this in esp32. If your code does not need to be portable, you don't need them.
You can leave files open and reuse them. Note that you need to commit your changes with a flush() before they are written to disk. This is less memory efficient than opening and closing locally.
You can certainly read data in with a for loop, and it is highly recommended to read full sectors (512B on an SD card, 4096 for flash) to get the fastest reads. A while(file1.available()) loop will repeat until it reaches the end of the file. If you prefer to read it line by line (slowly), you can use String r_line = file1.readStringUntil('\n');

DoDobro!
Posts: 14
Joined: Mon Oct 02, 2023 4:39 pm

Re: SD config and data save

Postby DoDobro! » Thu Oct 05, 2023 10:26 am

lbernstone wrote:
Wed Oct 04, 2023 5:38 pm
You can certainly read data in with a for loop, and it is highly recommended to read full sectors (512B on an SD card, 4096 for flash) to get the fastest reads. A while(file1.available()) loop will repeat until it reaches the end of the file. If you prefer to read it line by line (slowly), you can use String r_line = file1.readStringUntil('\n');
Thanks for answer, small clarifications:
1) I don't insist on "read file by string", I just see such logic as the most correct way to get and set configuration settings. File itself can be read by any better functions and store at memory or something like that.
2) Nice function to read string #1. But it's completely unclear how with this function to read at config file the next string #2,#3,etc???
I know that it's possible to calculate String Length and read next characters, but if I will use not "string" but "char" methods it's destroy the simplicity and clarity of "String-by-string config variables reading" logic. :(
So how to read string #2,#3,etc?
Or does Arduino have function to [read string from first '\n' to second '\n'], [read string from second '\n' to third '\n'], etc?

lbernstone
Posts: 831
Joined: Mon Jul 22, 2019 3:20 pm

Re: SD config and data save

Postby lbernstone » Thu Oct 05, 2023 4:36 pm

The FS.read functions move the seek position in the file, so if you read a string up to the CR, the next read will start on the next line, and available will show that many characters less remaining.
If you want to use char pointers, it will be more appropriate to use a buffer, read in 512/4096 bytes with a readBytes (https://github.com/espressif/arduino-es ... c/FS.h#L61) and then parse it as you like. It returns the number of bytes actually read if it hits EOF. Those pointers will get allocated from the stack unless you manually allocate the memory, so this is a good way to blow your stack if you don't watch it. Strings are dynamically allocated from heap.
If you just want to end up with a const char* at the end of your processing, String::c_str() will return a char array.
FYI, if you are a C programmer, the basic POSIX functions are available, inherited from ESP-IDF.

DoDobro!
Posts: 14
Joined: Mon Oct 02, 2023 4:39 pm

Re: SD config and data save

Postby DoDobro! » Tue Oct 10, 2023 7:43 pm

I've found something useful: https://github.com/stevemarple/IniFile - but its too powerful&bulky.
I need just to open cfg files from SD, read it, set some settings. But I'm completely stuck with all this C++ mess "string String String() char char* etc". Guys, please, help with exact code for:
1) Read config file to string buffer.
2) If use the straight config order there will be no need to search at whole config, just to jump from 1 settings to last. But because ArduinoIDE/C++ does not have "string cursor place" it will be better to just cut off all already used string part at the front of it.
I've re-write this code already for fkng 2 days for millions times but it does not work. Please, fix it with proper C++ syntax etc.

Config file structure is most simple:

Code: Select all

Setting1=100
Setting2=200
etc
Code which does not work, fix it, please:

Code: Select all

File configFile = SD.open("/tester.cfg", FILE_READ);
char configFile_data = configFile.read();
String configFile_data_str = String(configFile_data);
configFile_data_str.remove(0, length(configFile_data_str.readStringUntil("Setting1=")));
Setting1 = configFile_data_str.readStringUntil("\n");
configFile_data_str.remove(0, length(configFile_data_str.readStringUntil("\n")));
Guys, please, help with exact code for this bored task!!!

lbernstone
Posts: 831
Joined: Mon Jul 22, 2019 3:20 pm

Re: SD config and data save

Postby lbernstone » Wed Oct 11, 2023 4:56 am

I'm not going to do your homework for you, but perhaps what you are really looking for is the Preferences library? That is much easier to use for configuration settings, and stores it on the esp32 rather than on a removable device.
https://github.com/espressif/arduino-es ... ounter.ino

Who is online

Users browsing this forum: No registered users and 65 guests