Parsing a comma delimited string from serial monitor (AtMega2560 wifi built-in)

Hey everyone!!
In the past I had some issues with the AtMega2560 with wifi built-in, but now I've got it somewhat working. I have a string sent from the Esp module separated by commas of individual temperature sensor readings from Thingspeak. This is then picked up by the AtMega over serial monitor and defined as a variable. How can I parse the data using commas so I can assign them to individual variables?

Help would be much appreciated.

Please see below for code and outputs.

ESP Module

#include <SPI.h>
#include <Wire.h>
#include "ThingSpeak.h"
#include <ESP8266WiFi.h>
const char ssid[] = "Beep";  // your network SSID (name)
const char pass[] = "Bap";   // your network password


WiFiClient  client;

//---------Channel Details---------//
unsigned long counterChannelNumber1 = 0000000;            // Channel ID (Current)
unsigned long counterChannelNumber2 = 0000000;            // Channel ID (Current)
unsigned long counterChannelNumber3 = 0000000;            // Channel ID (Current)
const char * myCounterReadAPIKey1 = "REPLACEME"; // Read API Key (Needs to be changed)
const char * myCounterReadAPIKey2 = "REPLACEME"; // Read API Key (Needs to be changed)
const char * myCounterReadAPIKey3 = "REPLACEME"; // Read API Key (Needs to be changed)
const int FieldNumber1 = 1;  // The field you wish to read
const int FieldNumber2 = 2;  // The field you wish to read
const int FieldNumber3 = 3;  // The field you wish to read
const int FieldNumber4 = 4;  // The field you wish to read
const int FieldNumber5 = 5;  // The field you wish to read
const int FieldNumber6 = 6;  // The field you wish to read
const int FieldNumber7 = 7;  // The field you wish to read
const int FieldNumber8 = 8;  // The field you wish to read
//-------------------------------//
 
void setup()   {
  Serial.begin(115200);
  WiFi.mode(WIFI_STA);
  ThingSpeak.begin(client);
      Serial.println("[ON]");

}
 
 
void loop() {
  //----------------- Network -----------------//
  if (WiFi.status() != WL_CONNECTED)
  {
    Serial.print("Connecting to ");
    Serial.print(ssid);
    Serial.println(" ....");
    while (WiFi.status() != WL_CONNECTED)
    {
      WiFi.begin(ssid, pass);
      delay(5000);
    }
    Serial.println("Connected to Wi-Fi Succesfully.");
  }

  //----------------- Room1 -----------------//  
  long Room1 = ThingSpeak.readLongField(counterChannelNumber1, FieldNumber1, myCounterReadAPIKey1);
  int statusCode;
  statusCode = ThingSpeak.getLastReadStatus();
  if (statusCode == 200)
  {
  }
  else
  {
    Serial.println("Unable to read channel / No internet connection");
  }
  //----------------- End of Room1 -----------------//  

  //----------------- Room2 -----------------//  
  long Room2 = ThingSpeak.readLongField(counterChannelNumber1, FieldNumber2, myCounterReadAPIKey1);
  statusCode = ThingSpeak.getLastReadStatus();
  if (statusCode == 200)
  {
  }
  else
  {
    Serial.println("Unable to read channel / No internet connection");
  }
  //----------------- End of Room2 -----------------//  

  //----------------- Room3 -----------------//  
  long Room3 = ThingSpeak.readLongField(counterChannelNumber1, FieldNumber3, myCounterReadAPIKey1);
  statusCode = ThingSpeak.getLastReadStatus();
  if (statusCode == 200)
  {
  }
  else
  {
    Serial.println("Unable to read channel / No internet connection");
  }
  //----------------- End of Room3 -----------------//  

  //----------------- Room4 -----------------//  
  long Room4 = ThingSpeak.readLongField(counterChannelNumber1, FieldNumber4, myCounterReadAPIKey1);
  statusCode = ThingSpeak.getLastReadStatus();
  if (statusCode == 200)
  {
  }
  else
  {
    Serial.println("Unable to read channel / No internet connection");
  }
  //----------------- End of Room4 -----------------//  

  //----------------- Room5 -----------------//  
  long Room5 = ThingSpeak.readLongField(counterChannelNumber1, FieldNumber5, myCounterReadAPIKey1);
  statusCode = ThingSpeak.getLastReadStatus();
  if (statusCode == 200)
  {
  }
  else
  {
    Serial.println("Unable to read channel / No internet connection");
  }
  //----------------- End of Room5 -----------------//  

  //----------------- Room6 -----------------//  
  long Room6 = ThingSpeak.readLongField(counterChannelNumber1, FieldNumber6, myCounterReadAPIKey1);
  statusCode = ThingSpeak.getLastReadStatus();
  if (statusCode == 200)
  {
  }
  else
  {
    Serial.println("Unable to read channel / No internet connection");
  }
  //----------------- End of Room6 -----------------//  

  //----------------- Room7 -----------------//  
  long Room7 = ThingSpeak.readLongField(counterChannelNumber1, FieldNumber7, myCounterReadAPIKey1);
  statusCode = ThingSpeak.getLastReadStatus();
  if (statusCode == 200)
  {
  }
  else
  {
    Serial.println("Unable to read channel / No internet connection");
  }
  //----------------- End of Room7 -----------------// 
   
  //----------------- Room8 -----------------//  
  long Room8 = ThingSpeak.readLongField(counterChannelNumber1, FieldNumber8, myCounterReadAPIKey1);
  statusCode = ThingSpeak.getLastReadStatus();
  if (statusCode == 200)
  {
  }
  else
  {
    Serial.println("Unable to read channel / No internet connection");
  }
  //----------------- End of Room8 -----------------//  
  Serial.print(Room1);
  Serial.print(",");
  Serial.print(Room2);
  Serial.print(",");
  Serial.print(Room3);
  Serial.print(",");
  Serial.print(Room4);
  Serial.print(",");
  Serial.print(Room5);
  Serial.print(",");
  Serial.print(Room6);
  Serial.print(",");
  Serial.print(Room7);
  Serial.print(",");
  Serial.print(Room8);
  Serial.print(",\n");
  delay(10000);
}

AtMega2560

char *strings[8]; // an array of pointers to the pieces of the above array after strtok()
char *ptr = NULL;
float room1t, room2t, room3t, room4t, room5t, room6t, room7t, room8t;
String inString;
char raw;
void setup()
{
   Serial.begin(115200);
   Serial3.begin(115200);
}

void loop()
{
   while (Serial3.available()) {
   raw = Serial3.read();
   Serial.write(raw);
   inString += raw;
   } 
}

Output
15:35:10.503 -> Connected to Wi-Fi Succesfully.
15:35:16.916 -> 23,23,22,23,23,23,22,23,
15:35:33.650 -> 23,23,22,23,23,23,22,23,
15:35:50.489 -> 23,23,22,23,23,23,22,23,
15:36:07.080 -> 23,23,22,23,23,23,22,23,

I'm not sure how I could apply this, I get these values when I do.

16:11:06.206 -> Connected to Wi-Fi Succesfully.
16:11:28.313 -> C0o0n0n0e0c0t0e0d0 0t0o0 0W0i0-0F0i0 0S0u0c0c0e0s0f0u0l0l0y0.0
0
16:12:01.341 -> 02030,02030,02020,02030,02030,02030,02020,0204Connected to Wi-Fi Succesfully.

Have a look at Robin's Serial Input Basics - updated.

I have no idea why you think that this relates to Avrdude, stk500 or Bootloader and hence your topic has been moved to a more suitable location on the forum.

You could consider using the text parser library. For example,

#include <textparser.h>

TextParser parser(", ");  // Delimiter is a comma followed by a space.

void setup() {
  Serial.begin(9600);
}

void loop() {
  char line[80];
  if (not Serial.readBytesUntil('\n', line, sizeof(line))) {
    return;
  }

  // Assume the line contains eight values of type `float`.
  float roomT[8];
  parser.parseLine(line, roomT);

  // `roomT` now contains the eight values.
  for (float const& t: roomT) {
    Serial.println(t);
  }
}

The type of the values can be changed by changing the type of roomT, the delimiter can be changed in the declaration of parser.

[edit]

If you want these values to be assigned to separate variables instead, you can use the following:

float room1t, room2t, roomt3t;                   // Etc.
parser.parseLine(line, room1t, room2t, room3t);  // Etc.

You can even mix types if you are so inclined.

1 Like

Send your temperatures in the following format and store them in a char-type array after reception and then use strtoul() or stkto() function to extract the individual items.

//----------------- End of Room8 -----------------//  
  Serial.print(Room1);
  Serial.print(',');
  Serial.print(Room2);
  Serial.print(',');
....................................
  Serial.print(Room8);
  Serial.print('\n');

Receive Code:

char myData[50] = {0};
byte m = Serial3.readBytesUntil('\n', myData, 50);
myData[m] = '\0';
Serial.println(myData); //say: 23,45,89,22,23,23,34,25
memset(myData, 0, 50):

Extracting integer values of temperatures using strtoul() function.

char *temPtr;
byte x1 = strtoul(myData, &temPtr, 10);   // x1 = 0x17
Serial.println(x1, DEC);  //shows: 23

byte x2 = strtoul(temPtr+1, &temPtr, 10); //x2 = 2D
Serial.println(x2, DEC);  //shows: 45

you could parse the comma seperated string using sscanf(), e.g.

void setup() {
  char data[] = "23.4,21,32.6,56,66.7,12.4,9,22.22";
  Serial.begin(115200);
  float room1t, room2t, room3t, room4t, room5t, room6t, room7t, room8t;
  sscanf(data, "%f,%f,%f,%f,%f,%f,%f,%f",
         &room1t, &room2t, &room3t, &room4t, &room5t, &room6t, &room7t, &room8t);
  Serial.println(room1t);
  Serial.println(room2t);
  Serial.println( room3t);
  Serial.println(room4t);
  Serial.println( room5t);
  Serial.println(room6t);
  Serial.println( room7t);
  Serial.println(room8t);
}

void loop() {}

a run gave

23.40
21.00
32.60
56.00
66.70
12.40
9.00
22.22
1 Like

consider generic tokenize() for this and potentially other cases and applications

char s [80];

// -----------------------------------------------------------------------------
#define MaxTok  10
char *toks [MaxTok];
int   vals [MaxTok];

int
tokenize (
    char       *s,
    const char *sep )
{
    unsigned n = 0;
    toks [n] = strtok (s, sep);
    vals [n] = atoi (toks [n]);

    for (n = 1; (toks [n] = strtok (NULL, sep)); n++)
        vals [n] = atoi (toks [n]);

    return n;
}

// -----------------------------------------------------------------------------
void dispToks (
    char * toks [])
{
    char s [40];
    for (unsigned n = 0; toks [n]; n++)  {
        sprintf (s, " %6d  %s", vals [n], toks [n]);
        Serial.println (s);
    }
}

// -----------------------------------------------------------------------------
void loop ()
{
    if (Serial.available ())  {
        int n = Serial. readBytesUntil ('\n', s, sizeof(s)-1);
        s [n] = 0;      // terminate string

        tokenize (s, ",");
        dispToks (toks);
    }
}

// -----------------------------------------------------------------------------
void setup ()
{
    Serial.begin (9600);
}

Another version using strtok() function.

void setup()
{
  Serial.begin(9600);

  // char str[] = "1234,5678,23789";
  char str[] = "23.4,21,32.6,56,66.7,12.4,9,22.22";
  const char s[2] = ",";  //including null-byte
  char *token;
  float dataArray[8];
  int i = 0;

  /* get the first token */
  token = strtok(str, s);
  dataArray[i] = atof(token);

  /* get other tokens */
  while ( token != NULL )
  {
    i++;
    token = strtok(NULL, s);
    dataArray[i] = atof(token);
  }

  for (int j = 0; j < 8; j++)
  {
    Serial.println(dataArray[j], 2);
  }
}

void loop()
{

}

Output:

23.00
21.00
32.60
56.00
66.70
12.40
9.00
22.22

1 Like

Oh my God. Thankyou all so so much but this is the best option that works. Thankyou all!! You are a beautiful human being brodie.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.