Regex style string parsing

#1

i have a serial string being output from arduino mega, Its output from a couple sensors. Thats working fine.(I believe) I would like to display that data on the dashboard and I am stuck on the string splitting and parsing. I have played with a few examples and I just cannot get it to come through. I have read the basic info but there is some syntax that I havent explained yet. Here is the screenshot of the string being output:

I would like to grab the humidity value, the temp value, and the outside temp value.
I would like those displayed on the UI in a dial
I would also like to later on use the humidity value thresholds to trigger a relay on the pi but thats not in the scope of this post. I have seen several posts I have tried to extract useful snippets from and I get undesired results..

#2

Now that I see the full result of my screenshot I realize the "flows" are out of place. Some of them are from "testing". The part I hope to get help with is on the right in the debug pane. Its the payload string that I am having trouble splitting out values from.

#3

Here is the snippet I found that I was trying to make use of.

1 Like
#4

Do you /could you edit the Arduino code to make the returned string easier to parse ? Eg by adding comma or other unique symbol between the data pairs.

#5

Absolutely I can, I will post the arduino code shortly. I had considered the "json" library that was mentioned in one of the forum posts but i have progressed with this enough I felt I would be back peddling.

#6

#include <OneWire.h>
#include <DallasTemperature.h>
#include "DHT.h"

#define DHTPIN 2 // PIN for DHT22
#define DHTTYPE DHT22 // DHT 22 (AM2302), AM2321
#define ONE_WIRE_BUS 5 //PIN for outside sensor

OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);

float Celcius=0;
float Fahrenheit=0;
DHT dht(DHTPIN, DHTTYPE);

void setup(void)
{

Serial.begin(9600);
sensors.begin();
dht.begin();
}

void loop(void)
{
// Wait a few seconds between measurements.
delay(2000);

// Reading temperature or humidity takes about 250 milliseconds!
// Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
float h = dht.readHumidity();
// Read temperature as Celsius (the default)
float t = dht.readTemperature();
// Read temperature as Fahrenheit (isFahrenheit = true)
float f = dht.readTemperature(true);

float hif = dht.computeHeatIndex(f, h);
float hic = dht.computeHeatIndex(t, h, false);

Serial.print(" Inside Reading: ");
Serial.print(" Humidity: ");
Serial.print(h);
Serial.print(" Temperature: ");
Serial.print(f);

sensors.requestTemperatures();
Celcius=sensors.getTempCByIndex(0);
Fahrenheit=sensors.toFahrenheit(Celcius);
Serial.print(" Outside Reading: ");
Serial.println(Fahrenheit);
delay(1000);
}

#7

When I was using the Arduino IDE to write sketches for my WeMos devices (these days I'm flashing most of them wth ESPeasy), I would create a json formated string to send to the Node-red. Then I could just grab the data in a json friendly way. here is the relevant portion of the sketch I used:

  // Wait a few seconds between measurements.
  delay(2000);  // 2 seconds

  // Reading temperature or humidity takes about 250 milliseconds!
  // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
  float h = dht.readHumidity();
  // Read temperature as Celsius (the default)
  float t = dht.readTemperature();
  // Read temperature as Fahrenheit (isFahrenheit = true)
  float f = dht.readTemperature(true);

  // Check if any reads failed and exit early (to try again).
  if (isnan(h) || isnan(t) || isnan(f)) {
    Serial.println("Failed to read from DHT sensor!");
    return;
  }
 
// MQTT_TOPIC: location/room/device/sensorid/value

  // form a JSON-formatted string:
  String msg1 = "{\"room\":\"";
  String msg2 = room;
  String msg3 = "\",\"device\":\"";
  String msg4 = device;
  String msg5 = "\",\"id\":\"";
  String msg6 = id;
  String msg7 = "\",\"temp\":\"";
  String msg8 = String(t);
  String msg9 = "\",\"humi\":\"";
  String msg10 = String(h);
  String msg11 ="\"}";
  String msg = msg1 + msg2 + msg3 + msg4 + msg5 + msg6 + msg7 + msg8 + msg9 + msg10 + msg11;

  // send it it:  
  long now = millis();
  if (now - lastMsg > 10000) {
    lastMsg = now;
    msg.trim();
    len = msg.length();
    msg.toCharArray(msg_to_send, len+1);
 
    if (debug) Serial.println(msg_to_send);

    client.publish(mqtt_topic, msg_to_send);
  }
   #ifdef FORCE_DEEPSLEEP
     if (debug) Serial.println("Force deepsleep 15min!");
     ESP.deepSleep(15 * 60 * 1000000);
     delay(100);
   #endif
   delay(1000*60*15);  //wait 15 minutes to send next reading

}
// ================================
// =   end of LOOP                =
// ================================
4 Likes
#8

There is an Arduino Json library that can help with this:


OSC is also a nice protocol to use for these kinds of things, on the Node-RED side you would use node-red-contrib-osc and node-red-contrib-slip along with the OSC library:

#9

I seem to remember that this library is rather large. While certainly true that it easily produces good JSON output, I found that it was only worth it when needing to output lots of different JSON and then its size sometimes caused issues (with early ESP01's). I generally ended up handcrafting output or creating a simple function of my own.

1 Like
#10

I looked into all the libraries mentioned. I haven't changed my source sketch yet but I think
that ZENOFMUD post was the best solution to my question.
Any pointers on how my sketch will look formatted properly ZENO?
I dont quite grasp the formatting structures including the comma's and backslashes.
Why? Is that part of the json format?

#11

That's what I was also saying.

The backslashes are escaping characters that would otherwise have meaning in C++. You have to tune your brain to filter them out. I typically write the string "normally" and then add in the escaping. If you are reusing patterns, try a simple function.

1 Like
#12

A json object is made up of key:value pairs inside of '{}'. Since strings must be in double quotes, double quotes inside a string must be escaped with the back slash. Lets look at the first line of the code building the msg's and that is:

String msg1 = "{\"room\":\"";

Starting after String msg1 = we see " that is the start of the string that will end up in the variable msg1. Next comes the { which is the start of the json. (The json will end with a } which you can see in the msg11 line.) so

msg1 now contains {

Next you see \", that is escaping the double quote so it can be used in the string

msg1 now contains {"

that is followed by room\":\" so we add room":" (remember the double quotes are escaped) to the msg1 and

msg1 now contains {"room":"

Now we move onto the next line:

String msg2 = room;

This just moves the contents of the variable room into msg2. If room contained livingroom, msg2 would now contain livingroom. All of this gets built together at the end, and it might have been clearer if I had coded that line as

String msg1 += room;

and then

msg1 would contains {"room":"livingroom

And so it goes and so it goes in the code to build up the entire json object. Had I known about the arduino libraries, I may have used them, but at this point the code I wrote works and I have other things to do (like make waffles for the grandkids that will be arriving in a bit)

I hope this helps. You can learn more going thru some tutorials.

1 Like
#13

I finally added the JSON library. Now I need to take the data into node and use it to display on the charts.
I also want to be able to trigger an action based on the humidity reading.

#14

Hi - I'm not sure if there's a question there.

I don't see a JSON node in your flow - which you'll need to parse the raw JSON string received over the Serial node to a JavaScript object you can start accessing its properties.

But I also see in your Arduino code you're writing non-JSON content over the Serial port. So you first need to get to the point where you are only writing lines of JSON over serial.

Without rereading the entire history of this thread, remember to use a Debug node to confirm exactly what you're getting over serial.

#15

10-4, i will take out the original serial prints and leave the json only. As far as the node I thought that is what the function node was doing. I will look for a JSON node in the pallet
Thank you for the response.

#16

I commented out all the standard serial output. Then it went sour. I tried
serial.print(root...........);
That didnt work. Now I have it messed up.
I dont have it even sending json over serial. I also found the json node to add to the flow.
Not there yet. I am sorry, By the end of this forum post I WILL have learned.
Ive missed some basic syntax. YET again...

#17

#18

Unfortunately my issue is not "not exactly" a node-red problem. It is printing to the serial monitor.
It just doesn't seem to be passing the values in. I better read more on the json library.
I am assuming i have a basic syntax problem. Sorry, I was hoping to post better success.

#19

SUCCESS!!!!!!! Now back to regularly scheduled program NODE-RED!!!

#20

OK,
Its getting late for me. I think I am almost there! At this point my current goal is to just get the data to the UI gauges. i wiped out all the other stuff and started with a function node. Been messing with it for a while. I get some data to the ui but its not the objects data. no I finally have a real error.
My input message is the json object. All I want to do is pull out those 3 values. All you guys make this look easy.
I am thinking I have another syntax issue but I haven't lined it out yet. Love some tips at this point. i am certainly trying. and having fun learning.