Help for reading/writing data from sd

Hi guys, I need your help.
I'm currently creating a device that needs to do some operation with the sd card.

To be precise I'm building a gps chrono and I have to:

1)Read and write a settings file that is located in the main folder (I don't want to use the eeprom becouse hopefully this device will be sold and I want the ability to just send the settings file and just copy and paste);

2)Read information on previously written data (mainly gps coordinates and some other information);

3)datalogging (i need to keep track of all the times that were calculated by the main functions and store in a specific file in a specific folder that rappresent the varius tracks).

The main program (responsable of all the UI and the chrono part) is working fine but I need all the information acquired to be readible from my device (mainly) but also from the file (in case the rider wants to check all the times using the pc).

I saw that the possible solution would be the strtok function.

I used paython whenever i needed to work with strings becouse for me is much easier and I haven't really understood the token logic.

Can anyone solve my problem or give me an advice?

Thank to everyone,
any advice is appreciated.

We will be glad to help you with code you have written. Most people in this forum will not write code for you.

ToddL1962:
We will be glad to help you with code you have written. Most people in this forum will not write code for you.

No no, obviusly I'm not asking you to do the job. I was just wondering if that function could solve my problems and also if you could help me clarify how strtok works or if I'm doing it right.

I didn't really written anything, i just grabbed some exemples from various places.

In python I just split the file in rows, than I split each part of the row in segments using a letter or a simbol.

For example, if I had to grab a setting value I would store like: "time=1.55" .
Then I would use .split() to split the value name from the value itself in an array of strings.

Now, from what I undestood strtok reads a char array (string) and returns a pointer from the beginning of the array (or from the last correspondence) to the first matching letter (with the prev exemple it would have returned "time").

The differenece between the metod I used with python and c is that python's split function get 1 string and returns a list of strings, instead strtok returns me just the pointer to the first part of the string until the delimiter is found, right?

So, if I'm right (but I don't think so), to make the function to read the settings file I have to:

-Open the file (SD.open("settings.txt");

-Read the row (using getLine);

-Split the first part of the row with the "=" delimiter (like this: strtok (str,"=") );

-Understand which value I'm reading (using strcmp?) with all my values;

-Get the value part of the row (I have to call another strtok but at this point i have to add an ending delimiter
like"," or ";");

-Link the scanned value to the variable and convert to int or any other type (with atoi() or others);

-Repeat the previus steps until the file is over or all the settings are synced;

Sorry for the mess but before wasting hours and then re write all the code I wanted to know if at least the logical part is correct.

You really don't have to write your own code for that. A file format for what you are considering is usually referred to as an ".ini" file. It can have sections and setting=value formats. Here is an ini file library for the Arduino: GitHub - stevemarple/IniFile: Arduino library to parse ini files.

Some people prefer XML or Json files for settings. You can also find libraries for those formats as well.

Thank you very much. I'll have a look at those libraries.
I'll use them for sure if they make the job easier. :slight_smile: :slight_smile:

How many variables do you set? Could you use something as simple and short as a letter-number combo for each setting?

State Machine

Another way of processing incoming data, without blocking, is to set up a "state machine". Effectively this means looking at each byte in the input stream, and handling it depending on the current state.

As an example, say you had this coming into the serial port:

R4500S80G3

Where Rnnn is RPM, Snnnn is speed, and Gnnnn is the gear setting.

The state machine below switches state when it gets a letter "R", "S" or "G". Otherwise it processes incoming digits by multiplying the previous result by 10, and adding in the new one.

When switching states, if first handles the previous state. So for example, after getting R4500 when the "S" arrives, we call the ProcessRPM function, passing it 4500.

This has the advantage of handling long messages without even needing any buffer, thus saving RAM. You can also process message as soon as the state changes, rather than waiting for end-of-line.

Example state-machine code

The example and intro-level state machine code are a little way into the blog here (not my site, but a very GOOD site):

When you read SD or Serial data 1 char at a time

  while (Serial.available ())
    processIncomingByte (Serial.read ());

you can code to watch for spaces and line-ends to know when one data is ended and another may begin.

It gives you advantages. You can process data as it arrives and have the parse and recognition (even if the answer is the data is garbage or corrupt) by the time a whole word arrives which is when buffer-then-parse-with-string-functions only begin to process/parse/recognize what was read the state machine is already done using the cycles/time between arriving characters instead of waiting.

To go from single letter identifiers to short identifiers is the next step. In the example it is simpler since all identifiers are 1 single char, but whole words are do-able too just more code and a word list in data is not beginner example material.

Remember - C string is a char array. You can work it element by element as you would with an array of ints. The string.h functions have no lock on string data, they are just one way to do it.