I need to read the following packet of data into an 8266 and parse it.
*X;1:000; 0;0;000;1
I have the following code working but data comes in as characters rather than one packet.
if (Serial.available()) {
char data = Serial.read(); // read the received character
display.print("data= ");
Serial.print(data); // echo back to data to the sender
display.println(data);
}
I did read the 'Serial Input Basics' but the example there has an end of data code, I don't have that.
My data set always stars with a * and is 19 chars long...
Any assistance how to get started to pull this data in would be appreciated.
Thanks
J-M-L
January 18, 2025, 7:54am
2
I would suggest to study Serial Input Basics to handle this
Sscanf() can then be used or strtok() and strtol() if the numbers are integers
I have read that, as I said the examples there are based on an ending which I dont have. Is there a way to bring in 19 characters after a starting character?
The '*' is effectively the line ending character
1 Like
J-M-L
January 18, 2025, 8:22am
5
Is there a new line at the end ?
If not, either you handle the next star as the end character or need to build a timeout or use the fact itβs always 19 chars (is it?)
(Sorry for not reading carefully your first post)
1 Like
You can use the following codes to receive/store the arrived string (data packet) and then use strtok() function of post #2 @J-M-L to parse the string for the extracton of the individual data items.
char myData[19]; //'*' not saved; 18 chars are saved, last one for null
void loop()
{
byte n = Serial.available();
if(n !=0)
{
char ch = Serial.read();
if(ch == '*')
{
byte m = Serial.readBytes(myData, 18); //
myData[m] = '\0'; //inset null-byte
Serial.println(myData); //see the arrived string
//--insert codes to extract data items from myData[] array-------
}
}
}
Is it "line ending character" or "line beginning character (the Start Mark of a New Frame)"?
b707
January 18, 2025, 8:46am
7
It may looks obvious, but what about to catch the start character and then count received chars until it became a 18... ?
1 Like
J-M-L
January 18, 2025, 8:57am
8
a small state machine could do. I count only 18 characters including the star though
*X;1:000; 0;0;000;1
I have counted 19 including the * and the space after the 2nd data item.
J-M-L
January 18, 2025, 9:09am
10
dudester:
X;1:000; 0;0;000;1
I need to get my eye surgery done... 19th of feb !
J-M-L
January 18, 2025, 9:20am
11
so something like this should work (typed here, fully untested)
// read incoming messages with format "*X;1:000; 0;0;000;1"
const char startMarker = '*'; // our payload start marker
const byte payloadSize = 18; // without the start marker
char payload[payloadSize + 1]; // +1 for the trailing null char.
bool receivePayload() {
static enum State : byte {WAITING_STAR, WAITING_PAYLOAD} state = WAITING_STAR;
static byte count = 0;
bool payloadReady = false;
if (Serial.available()) {
char r = Serial.read();
switch (state) {
case WAITING_STAR:
if (startMarker == r) {
count = 0; // reset the count
payload[0] = '\0'; // mark the buffer empty
state = WAITING_PAYLOAD; // get ready for receiving the payload
}
break;
case WAITING_PAYLOAD:
payload[count++] = r;
payload[count] = '\0'; // mainatin a readable payload
payloadReady = (count >= payloadSize);
if (payloadReady) state = WAITING_STAR;
break;
}
}
return payloadReady;
}
void handlePayload() {
Serial.print(F("Parsing ["));
Serial.print(payload);
Serial.println(F("]"));
char X;
int num1, num2, num3, num4, num5, num6;
int fieldsParsed = sscanf(payload, "%c;%d:%d; %d;%d;%d;%d", &X, &num1, &num2, &num3, &num4, &num5, &num6);
if (7 == fieldsParsed) {
Serial.print("X: "); Serial.println(X);
Serial.print("num1: "); Serial.println(num1);
Serial.print("num2: "); Serial.println(num2);
Serial.print("num3: "); Serial.println(num3);
Serial.print("num4: "); Serial.println(num4);
Serial.print("num5: "); Serial.println(num5);
Serial.print("num6: "); Serial.println(num6);
} else {
Serial.println("Error: Failed to parse all fields correctly.");
}
}
void setup() {
Serial.begin(115200);
Serial.println(F("ready"));
}
void loop() {
if (receivePayload())handlePayload();
}
you could add further error testing once you extracted the values as the code as it stands does not worry about one or 3 digits for the numbers.
horace
January 18, 2025, 9:23am
12
dudester:
*X;1:000; 0;0;000;1
are the field widths of the data within the frame fixed?
e.g. X; followed by one digit : followed by three digits etc etc
is the data continuous or periodic etc
e.g.
*X;1:000; 0;0;000;1*X;1:000; 0;0;000;1*X;1:000; 0;0;000;1
once you have read the data into a byte array you could parse it using sscanf() , e.g.
byte data[] = "*X;1:000; 0;0;000;1";
int d1, d2, d3, d4, d5, d6;
if (sscanf((char *)data, "*X;%d:%d;%d;%d;%d;%d", &d1, &d2, &d3, &d4, &d5, &d6) == 6) {
Serial.printf("\n\nD1 %d\n", d1);
Serial.printf("D2 %d\n", d2);
Serial.printf("D3 %d\n", d3);
Serial.printf("D4 %d\n", d4);
Serial.printf("D5 %d\n", d5);
Serial.printf("D6 %d\n", d6);
}
gives
D1 1
D2 0
D3 0
D4 0
D5 0
D6 1
Can you print here the outputs that you have got as well as your complete sketch?
Literally just your code, I havent had time to start parsing the data yet.
Thank you for your code, however I just get no response at all in the serial monitor when i send some test data....
J-M-L
January 19, 2025, 9:02am
18
can you post the full code you use and describe the wiring / power ?
dudester:
*X;1:000; 0;0;000;1
Post the interface requierement specification to see how we can help.
The code you posted as below does not work.
GolemMastafa's code does.
Circuit is just an RS232-TTL board Tx & Rx to Tx & Rx on an 8266
// read incoming messages with format "*X;1:000; 0;0;000;1"
const char startMarker = '*'; // our payload start marker
const byte payloadSize = 18; // without the start marker
char payload[payloadSize + 1]; // +1 for the trailing null char.
bool receivePayload() {
static enum State : byte {WAITING_STAR, WAITING_PAYLOAD} state = WAITING_STAR;
static byte count = 0;
bool payloadReady = false;
if (Serial.available()) {
char r = Serial.read();
switch (state) {
case WAITING_STAR:
if (startMarker == r) {
count = 0; // reset the count
payload[0] = '\0'; // mark the buffer empty
state = WAITING_PAYLOAD; // get ready for receiving the payload
}
break;
case WAITING_PAYLOAD:
payload[count++] = r;
payload[count] = '\0'; // mainatin a readable payload
payloadReady = (count >= payloadSize);
if (payloadReady) state = WAITING_STAR;
break;
}
}
return payloadReady;
}
void handlePayload() {
Serial.print(F("Parsing ["));
Serial.print(payload);
Serial.println(F("]"));
char X;
int num1, num2, num3, num4, num5, num6;
int fieldsParsed = sscanf(payload, "%c;%d:%d; %d;%d;%d;%d", &X, &num1, &num2, &num3, &num4, &num5, &num6);
if (7 == fieldsParsed) {
Serial.print("X: "); Serial.println(X);
Serial.print("num1: "); Serial.println(num1);
Serial.print("num2: "); Serial.println(num2);
Serial.print("num3: "); Serial.println(num3);
Serial.print("num4: "); Serial.println(num4);
Serial.print("num5: "); Serial.println(num5);
Serial.print("num6: "); Serial.println(num6);
} else {
Serial.println("Error: Failed to parse all fields correctly.");
}
}
void setup() {
Serial.begin(115200);
Serial.println(F("ready"));
}
void loop() {
if (receivePayload())handlePayload();
}
J-M-L
January 19, 2025, 2:00pm
21
are you communicating at 115200 bauds ?
dudester:
Serial.begin(115200);