there are libraries that do what you want.
here is a simple parsing tool that I did a while back for another forum member, has to be modified for your string. You can test it with putting the Example Message into the Serial Monitor:
#include "SerialMessenger.h"
/*
* Example Message
* $GPRMC,001225,A,2832.1834,N,08101.0536,W,12,25,251211,1.2,E,A*03
*/
void parseSerialMssg(const char* mssg);
void parseSoftSoftSerialMssg(const char* mssg);
SoftwareSerial softSerial(4,5);
SerialMessenger serial(Serial, 254, '
uses SerialMessenger.h
#ifndef SERIALMESSENGER_H
#define SERIALMESSENGER_H
#include <SoftwareSerial.h>
#if ARDUINO >= 100
#include "Arduino.h"
#if defined(__AVR_ATmega328P__) || defined(__AVR_ATmega168__)
#define MAX_SERIAL_PORTS 2
#elif defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega16U4__)
#define MAX_SERIAL_PORTS 1
#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
#define MAX_SERIAL_PORTS 5
#endif
#else
#define MAX_SERIAL_PORTS 2
#endif
typedef uint8_t byte_size_t;
class SerialMessenger {
public:
SerialMessenger(HardwareSerial& device, size_t maxMessageLength, char startMarker, char endMarker, void (*parseFunction)(const char*), bool err = false);
SerialMessenger(SoftwareSerial& device, size_t maxMessageLength, char startMarker, char endMarker, void (*parseFunction)(const char*), bool err = false);
~SerialMessenger();
void begin(uint32_t baudRate);
char* checkForValidMessage(const char startMarker, const char endMarker);
static void update(void);
private:
HardwareSerial* hwStream;
SoftwareSerial* swStream;
Stream* stream;
void (*callback)(const char*);
char* incomingMessage;
byte_size_t bufferSize;
byte_size_t idx = 0;
char startMkr;
char endMkr;
bool errors;
static byte_size_t instanceCount;
static SerialMessenger* instances[MAX_SERIAL_PORTS];
enum {
WAITING,
PARSING,
}state = WAITING;
};
#endif
and SerialMessenger.cpp
#include "SerialMessenger.h"
#include "SoftwareSerial.h"
byte_size_t SerialMessenger::instanceCount = 0;
SerialMessenger* SerialMessenger::instances[MAX_SERIAL_PORTS] = {nullptr};
SerialMessenger::SerialMessenger(HardwareSerial& device, size_t maxMessageLength, char startMarker, char endMarker, void (*parseFunction)(const char*), bool err)
{
startMkr = startMarker;
endMkr = endMarker;
instances[instanceCount++] = this;
hwStream = &device;
callback = parseFunction;
bufferSize = maxMessageLength > 254? 254 : maxMessageLength;
incomingMessage = new char[bufferSize + 1];
errors = err;
}
SerialMessenger::SerialMessenger(SoftwareSerial& device, size_t maxMessageLength, char startMarker, char endMarker, void (*parseFunction)(const char*), bool err)
{
startMkr = startMarker;
endMkr = endMarker;
instances[instanceCount++] = this;
swStream = &device;
callback = parseFunction;
bufferSize = maxMessageLength > 254? 254 : maxMessageLength;
incomingMessage = new char[bufferSize + 1];
errors = err;
}
SerialMessenger::~SerialMessenger(){ free(incomingMessage); incomingMessage = NULL;}
void SerialMessenger::update()
{
for (size_t i = 0; i < instanceCount; i++)
{
if (const char* message = instances[i]->checkForValidMessage(instances[i]->startMkr, instances[i]->endMkr))
{
instances[i]->callback(message);
}
}
}
char* SerialMessenger::checkForValidMessage(const char startMarker, const char endMarker) //, const char checksumToken)
{
stream = !hwStream ? (Stream*)swStream : hwStream;
if (stream->available())
{
if (state == WAITING)
{
if (startMkr)
{
if (stream->read() == startMarker)
{
state = PARSING;
}
return nullptr;
}
else
{
state = PARSING;
}
}
else if (state == PARSING)
{
incomingMessage[idx] = stream->read();
if (incomingMessage[idx] == endMarker)
{
incomingMessage[idx] = '\0';
idx = 0;
if (startMkr)
{
state = WAITING;
}
return incomingMessage;
}
else
{
idx++;
if (idx > bufferSize - 1)
{
if (errors)
{
stream->println(F("Bad Message")); //<< Error back to sender
}
idx = 0;
incomingMessage[idx] = '\0';
if (startMkr)
{
state = WAITING;
}
}
}
}
}
return nullptr;
}
void SerialMessenger::begin(uint32_t baudRate)
{
if (hwStream)
{
hwStream->begin(baudRate);
}
else
{
swStream->begin(baudRate);
}
}
, ‘\n’, parseSerialMssg); // defining start & end markers as ’
uses SerialMessenger.h
§DISCOURSE_HOISTED_CODE_1§
and SerialMessenger.cpp
§DISCOURSE_HOISTED_CODE_2§
and '\n' respectively
SerialMessenger sw(softSerial, 254, '
uses SerialMessenger.h
§_DISCOURSE_HOISTED_CODE_1_§
and SerialMessenger.cpp
§_DISCOURSE_HOISTED_CODE_2_§
, ‘\n’, parseSerialMssg);
//SerialMessenger serial1(Serial1, 16, ‘\0’, ‘\n’, parseMssg);
void setup()
{
serial.begin(9600);
sw.begin(9600);
}
void loop()
{
SerialMessenger::update();
}
void parseSerialMssg(const char* mssg)
{
Serial.print(F(“From callback function:\t”));
Serial.println(mssg);
if (strstr(mssg, “GPRMC”))
{
Serial.print(F(“Parsing GPRMC sentence…\n”));
char gprmc[strlen(mssg) + 1];
char fieldData[16];
strcpy(gprmc, mssg);
strtok(gprmc, “,”);
Serial.println(gprmc);
strcpy(fieldData, strtok(NULL, “,”));
Serial.print(F(“Time:\t”));
Serial.println(fieldData);
int hour = (fieldData[0] - ‘0’) * 10 + (fieldData[1] - ‘0’);
int minute = (fieldData[2] - ‘0’) * 10 + (fieldData[3] - ‘0’);
int second = (fieldData[4] - ‘0’) * 10 + (fieldData[5] - ‘0’);
snprintf(fieldData, sizeof(fieldData), “Time:\t%d:%02d:%02d”, hour, minute, second);
Serial.println(fieldData);
strcpy(fieldData, strtok(NULL, “,”));
Serial.print(F(“Status:\t”));
Serial.println(fieldData);
strcpy(fieldData, strtok(NULL, “,”));
Serial.print(F(“Lat:\t”));
Serial.println(fieldData);
strcpy(fieldData, strtok(NULL, “,”));
Serial.print(F(“Dir:\t”));
Serial.println(fieldData);
strcpy(fieldData, strtok(NULL, “,”));
Serial.print(F(“Lon:\t”));
Serial.println(fieldData);
strcpy(fieldData, strtok(NULL, “,”));
Serial.print(F(“Dir:\t”));
Serial.println(fieldData);
strcpy(fieldData, strtok(NULL, “,”));
Serial.print(F(“Speed:\t”));
Serial.println(fieldData);
strcpy(fieldData, strtok(NULL, “,”));
Serial.print(F(“Angle:\t”));
Serial.println(fieldData);
strcpy(fieldData, strtok(NULL, “,”));
Serial.print(F(“Date:\t”));
Serial.println(fieldData);
int year = (fieldData[0] - ‘0’) * 10 + (fieldData[1] - ‘0’);
int month = (fieldData[2] - ‘0’) * 10 + (fieldData[3] - ‘0’);
int day = (fieldData[4] - ‘0’) * 10 + (fieldData[5] - ‘0’);
snprintf(fieldData, sizeof(fieldData), “Date:\t%2d/%02d/%02d”, month, day, year);
Serial.println(fieldData);
strcpy(fieldData, strtok(NULL, “,”));
Serial.print(F(“Var:\t”));
Serial.println(fieldData);
strcpy(fieldData, strtok(NULL, “,”));
Serial.print(F(“Dir:\t”));
Serial.println(fieldData);
strcpy(fieldData, strtok(NULL, “,”));
Serial.print(F(“ChkSum:\t”));
Serial.println(fieldData);
}
else if (strstr(mssg, “GPGGA”))
{
Serial.print(F(“Parsing GPGGA sentence…\n”));
}
}
//void parseSoftSoftSerialMssg(const char* mssg)
//{
// Serial.print(F(“New SoftSerial Message:\t”));
// Serial.println(mssg);
//}
uses SerialMessenger.h
§DISCOURSE_HOISTED_CODE_1§
and SerialMessenger.cpp
§DISCOURSE_HOISTED_CODE_2§