How to parse a String from serial (RX pin)

Hi

I have an Arduino Mega and his job is to read sensors and show the values to LCD's.
2 Ultrasonic sensors to read the water level in two tanks and also 2 Flow sensors that can
see the water flow that fills each tank. All this is working nice and now I need to send the
data to a dashboard at IO Adafruit. But this is not why I post this message for now.

My Arduino Mega is sending the values to the serial in a string of data with comma separated value.

,value,value,value,value,

Example:

,41,12,85,24,

It means

41 cm for the level of the tank_1
12 liters per minute filling the tank_1
85 cm for the level of the tank_2
24 liters per minute filling the tank_2

I take the TX pin of the Mega and connected it to the RX of my arduino 8266
and it's ok.

Parsing

I have a parsing code that works on another project. I was using it to receive values and print
it on a wireless LCD and it work nice. (same comma separate value)

Except that this code is made to deal with a receiver so it begin by if receive.available()

In my new project the data is coming from serial so it won't work

I check on the net and read instructions and examples with serial.available
and String and array and almost got it but it's not working.

Instead of showing everything I tried, this is the code that work very nice
with my other project and the receiver.

String text = " ";//String to hold the text


void loop(){
  
    if (receive.available())                //check when received data available
  {
    char buf[64];
    receive.read(&buf, sizeof(buf));
    text = (char*)buf;
    Serial.println(text);
  }

    if (text.startsWith(",")) {
      int sepLocation[10];
      int index = text.indexOf(",");
      int i = 0;
      String extractedValues[9];
      while (index >= 0) {
        sepLocation[i] = index;
        i++ ;
        index = text.indexOf(",", index + 1);
      }
      for (int o = 0; o < 9; o++) {
        extractedValues[o] = text.substring((sepLocation[o] + 1), sepLocation[(o + 1)]);
      }

             lcd.setCursor(0,0);
             lcd.print (extractedValues[0] + "cm");


             lcd.setCursor(9,0);
             lcd.print (extractedValues[1] + "l/m");
                    

             lcd.setCursor(1,0);
             lcd.print (extractedValues[2] + "cm");
			 

             lcd.setCursor(1,9);
             lcd.print (extractedValues[3] + "l/m");
			  
			 }
			 }

This code is nice and was parsing very well the data I received on a RF receiver to print the values
to an LCD. Each value from extractedValues[0], extractedValues[1], etc..

Question

How can I modify this code to take the same kind of comma separated value but from my serial pin. ?

Serial Input Basics

Ditch the String class right now... it has memory management issues that can randomly crash your system.

Ok

I think I should add to my post the last test I've made.

With this code I can print the string called "text" in the serial monitor
so I know that I do receive the data from the Arduino Mega

But It look like the if (text.startsWith(",")) is not working.

#include "config.h"  // Put wi-fi and IO Adafruit credentials


#include <Adafruit_Sensor.h>
#include <DHT.h>
#include <DHT_U.h>
#include "Wire.h"
#include "LCD.h"
#include "LiquidCrystal_I2C.h"
#include <Wire.h>

#define DATA_PIN 2  // pin connected to DH22 data line

String text = " ";//String to hold the text

LiquidCrystal_I2C lcd_1(0x27,2,1,0,4,5,6,7);

DHT_Unified dht(DATA_PIN, DHT22); // create DHT22 instance


// set up the 'temperature' and 'humidity' feeds

AdafruitIO_Feed *temperature = io.feed("Temperature");
AdafruitIO_Feed *humidity = io.feed("Humidity");

// I add this for the water tanks feeds on Io Adafruit

AdafruitIO_Feed *level_tank_1 = io.feed("Level_Tank_1");
AdafruitIO_Feed *flow_in_tank_1 = io.feed("FlowInTank_1");

//AdafruitIO_Feed *level_tank_2 = io.feed("Level_Tank_2");
//AdafruitIO_Feed *flow_in_tank_2 = io.feed("FlowInTank_2");


void setup() {

   lcd_1.begin (16, 2); // 16 x 2 LCD module
   lcd_1.setBacklightPin(3,POSITIVE);
   lcd_1.setBacklight(HIGH);

  // start the serial connection
  Serial.begin(9600);

  // wait for serial monitor to open
  while(! Serial);

  // initialize dht22
  dht.begin();

  // connect to io.adafruit.com
  Serial.print("Connecting to Adafruit IO");
  io.connect();

  // wait for a connection
  while(io.status() < AIO_CONNECTED) {
  Serial.print(".");
  delay(500);
  }

  // we are connected
  Serial.println();
  Serial.println(io.statusText());

}

void loop() {

  io.run(); // keep this on top of loop to keep IO Adafruit connected


//  This code was working with string data coming from a receiver.////

//    if (receive.available()) //check when received data available
//    {
//    char buf[64];
//    receive.read(&buf, sizeof(buf));
//    text = (char*)buf;
//    Serial.println(text);
//    display.clearDisplay();
//    }

//modifications I made to try to adapte with serial data (RX Pin)

if (Serial.available())  //check when serial data available
    {
    char text[32];
    char byteRead;
    int availableBytes = Serial.available();
    for (int t=0; t<availableBytes; t++)
    {
    text[t] = Serial.read();
    }
   
    Serial.println(text); // This is showing me the text value so I can see that I do receive
                          // the data string from The Arduino Mega
    }

// This is the parsing section.  not modify yet because I tough it could work with my modification above  

    if (text.startsWith(",")) {
      int sepLocation[5];
      int index = text.indexOf(",");
      int i = 0;
      String extractedValues[4];
      while (index >= 0) {
        sepLocation[i] = index;
        i++ ;
        index = text.indexOf(",", index + 1);
      }
      for (int o = 0; o < 4; o++) {
        extractedValues[o] = text.substring((sepLocation[o] + 1), sepLocation[(o + 1)]);
      }

       lcd_1.setCursor(0,1);
       lcd_1.print(extractedValues[0]);
    }

//Data to IO Adafruit section

// I didn't include the values for the water tanks since it is not parsed yet.
// But this section is working well and I'm sending the temperature and humidity
// to IO Adafruit.  It work because the values are coming from a sensor connected
// directly to the ESP8266.


  sensors_event_t event;
  dht.temperature().getEvent(&event);

  float celsius = event.temperature;
  float fahrenheit = (celsius * 1.8) + 32;

  Serial.print("celsius: ");
  Serial.print(celsius);
  Serial.println("C");

  lcd_1.setCursor(0,0);
  lcd_1.print(celsius);
  lcd_1.print(" C");

  temperature->save(celsius); //To send celsius to Io Adafruit


  dht.humidity().getEvent(&event);

  Serial.print("humidity: ");
  Serial.print(event.relative_humidity);
  Serial.println("%");

  lcd_1.setCursor(9,0);
  lcd_1.print(event.relative_humidity);
  lcd_1.print(" %");

  humidity->save(event.relative_humidity);  //To send celsius to Io Adafruit

  delay(5000);  // Wait 5 seconds
}

Yeah, your use of Serial functions is completely broken. You check to see if there is one character available, then you charge off to see how many there are and try to handle them. You have nonsense variables like byteRead that you don't use... you try to call the methods of a char array (which don't exist)... you need to look at a working example like I posted before.

Hi aarg,

I was adding a reply to my post at the same time you wrote to me.

I'm new with arduino and to be worst, my primary language is French so be easy on me :slight_smile:

What do yo mean by "Ditch the String class right now"

I'm going to read the link about the serial basic to sent me in a few minute but I was wandering about what you mean.

Thanks

hddforensic:
What do yo mean by "Ditch the String class right now"

Stop using it immediately, throw it in the garbage.

Ok Aarg,

This is what append when you don't know enough about what you do
and try to adapte codes with few examples from the net.

That's why my first idea what not to show my tests because I knew
it was a mess after so many "anything".

I'm reading the examples you sent me but it's going to take me a while.

Good exemples in French are hard to find and in English are are to understand
for me. sorry.

What about the first parsing code I sent ?
This one was working nice with my remote wireless LCD.

If it's good, can it be adapte to serial instead receiver ?

Hi groundFungus,

While writting this reply, I saw your link,

I'm going to read it too,

Thanks

hddforensic:
What about the first parsing code I sent ?
This one was working nice with my remote wireless LCD.

If it's good, can it be adapte to serial instead receiver ?

You can adapt the principles, but the implementation isn't clean enough to make it worth saving. I suggest that you begin from nothing, using the input examples I linked to.