Search code examples
c++carduinoarduino-esp8266

SD card data parsing with esp8266


I need some assistance for extracting data from a SD card I based my code from this section.

The code works when I read the data from the SD card and display it into the serial port, but when I pass the data into an char* array and call a function that will loop the array, the array displays garbage (some unreadable data). I am trying to make a function which I can use to call different settings stored from SD card in a text file format.

I have a global variable named:

char* tempStoreParam[10]; 

Which will store temporary data to be process. The data stored in the text file is in this format

-n.command

Where: n = int number and index location of the data to be stored in the tempStoreParam[10] and command is a char* array to stored in tempStoreParam[10].

Example:

-1.readTempC

-2.readTempF

-3.setdelay:10

-4.getIpAddr

Here is the code snippet:

while (sdFiles.available()) {
  char sdData[datalen + 1];
  byte byteSize = sdFiles.read(sdData, datalen);
  sdData[byteSize] = 0;
  char* mList = strtok(sdData, "-");
  while (mList != 0)
  {
    // Split the command in 2 values
    char* lsParam = strchr(mList, '.');
    if (lsParam != 0)
    {
      *lsParam = 0;
      int index = atoi(mList);
      ++lsParam;
      tempStoreParam[index] = lsParam;
      Serial.println(index);
      Serial.println(tempStoreParam[index]);
    }
    mList = strtok(0, "-");
  }
} 

I am trying to get the following result:

char* tempStoreParam[10] = {"readTempC","readTempF","setdelay:10","getIpAddr"};

Solution

  • Your code has a few problems - In order:

    The return value of read in this instance is a 32 bit integer - You are truncating it to a byte value, meaning if the file contents are ever over 255 bytes, you will incorrectly terminate your string, and fail to read the contents correctly:

    byte byteSize = sdFiles.read(sdData, datalen);
    

    Secondly, you are storing the address of a stack variable into your tempStoreParam array with this line:

    tempStoreParam[index] = lsParam;
    

    Now, this will work, but only for how long sdData remains in scope. After that, sdData is no longer valid to use, most likely leading to the garbage you experience. What you most likely are trying to do is take a copy of the data to place it into tempStoreParam. To do that, you should use something like this:

    // The amount of memory we need is the length of the string, plus one 
    // for the null byte
    int length = strlen(lsParam)+1
    
    // Allocate storage space for the length of lsParam in tempStoreParam
    tempStoreParam[index] = new char[length];
    
    // Make sure the allocation succeeded 
    if (tempStoreParam[index] != nullptr) {
       // Copy the string into our new container
       strncpy(tempStoreParam[index], lsParam, length);
    }
    

    At this point, you should be able to pass around that string outside the function successfully. As a note, you will need to delete the array created once you are done with it / before reading the file again.