Hi - i'm getting strings from my serial looking like this : FL010100
I would like to split the string into part1:FL part2:01 part3:100 ... I have looked at substring and array and can't find out what's best...
An other string could look like this : CF02L0125P01T00:00:08.556
The first part of the string FL or CF shows the "kind" of data i'm getting and the length of the string is always the same ... FL is 8 characters and CF is 25 and so on ...
What would you recommend?
How are the strings terminated?
All strings starts with [ and ends with ] ...
You can use strtok(), strcpy(), itoa() and so on.
char text[] = "CF02L0125P01T00:00:08.556";
// check if a substring matches a given string
if (strncmp(&text[0], "FL", 2) == 0) { // first two characters match "FL"
// ...
} else if (strncmp(&text[0], "CF", 2) == 0) { // first two characters match "CF"
// ...
}
{
// take a single character out of the string
char character = text[4];
Serial.print(character); // prints 'L'
}
{
// take a substring (but first consider whether you *really* have to copy it)
char firstField[3]; // this can store a string of 2 characters (+ terminating null character)
strncpy(firstField, &text[2], 2); // copy "02"
firstField[2] = '\0'; // null-terminate the string
Serial.print(firstField); // prints "02"
}
{
// alternatively
char firstField[3] = {'\0'}; // initialize firstField[0] with a null character
strncat(firstField, &text[2], 2); // copy "02" and null-terminate
Serial.print(firstField); // prints "02"
}
{
// convert substring to int
char tmp = text[9];
text[9] = '\0'; // tell atoi where to stop
int value = atoi(&text[5]); // value is now 125
text[9] = tmp; // restore the original string
}
{
// convert substring to double/float
char tmp = text[25];
text[25] = '\0'; // tell strtod where to stop
double value = strtod(&text[19], nullptr); // value is now 8.556
text[25] = tmp; // restore the original string
}
Pieter
Lindbaum:
What would you recommend?
something like this... moving a pointer along your string:
expects:
[FL010100]
code:
const size_t MAX_MESSAGE_BUFFER_LENGTH = 16;
template<class T> inline Print &operator << (Print &object, T argument)
{
object.print(argument);
return object;
}
void setup()
{
Serial.begin(9600);
if(Serial)
{
Serial << (F("let's go!\n"));
}
}
void loop()
{
if (char* packet = checkForNewMessage(Serial, '[', ']')) // checks for message on Serial with start marker of "[" and end marker of "]"
{
Serial << (F("\nthis just in...\n")) << (packet) << (F("\n\n"));
//FL010100
char firstPart[3];
char* ptr = packet;
firstPart[0] = *ptr++;
firstPart[1] = *ptr ++;
firstPart[2] = '\0';
char secondPart[3];
secondPart[0] = *ptr++;
secondPart[1] = *ptr++;
secondPart[2] = '\0';
char thirdPart[5] = "";
strcat(thirdPart, ptr);
Serial << (F("First Part = ")) << (firstPart) << F("\n");
Serial << (F("Second Part = ")) << (secondPart) << F("\n");
Serial << (F("Third Part = ")) << (thirdPart) << F("\n");
}
}
char* checkForNewMessage(Stream& stream, const char startMarker, const char endMarker)
{
static char incomingMessage[MAX_MESSAGE_BUFFER_LENGTH] = "";
static unsigned char idx = 0;
static bool gotStartMarker = false;
if (stream.available())
{
if (!gotStartMarker)
{
if (stream.read() == startMarker)
{
gotStartMarker = true;
}
}
else
{
incomingMessage[idx] = stream.read();
if (incomingMessage[idx] == endMarker)
{
incomingMessage[idx] = '\0';
idx = 0;
gotStartMarker = false;
if (!strlen(incomingMessage)) //startMarker followed immediatly by endMarker (i.e.no data)
{
//stream << (F("{\"error\":\"no data\"}\n")); // you can return an error to sender here
return nullptr;
}
//stream << (F("{\"success\":\"")) << (incomingMessage) << (F("\"}\n")); // or return a success messaage
return incomingMessage;
}
else
{
idx++;
if (idx > MAX_MESSAGE_BUFFER_LENGTH - 1)
{
stream << (F("{\"error\":\"message exceeded ")) << (sizeof(incomingMessage) - 1) << (F(" chars\"}\n")); // another error to sender here
idx = 0;
gotStartMarker = false;
incomingMessage[idx] = '\0';
}
}
}
}
return nullptr;
}
template<class T> inline Print &operator << (Print &object, T argument)
{
object.print(argument);
return object;
}
Quite clever! Why didn't they include that in the Arduino core?
Thanx a lot - the pointer solution worked perfect 