Node-red, raspberry pi and arduino communication issues

Hello, first im a dangerous novice here. may not even be in the correct space.
I am running my brewing system with node red. I am using 1 wire temp sensors for ketlles, and fermenters. i have the 3 sensors in brew house connected to raspberry pi and i am displaying temps properly in Node red. now the problems, i have 4 more sensors connected in parallel to my arduino.
when im connected to arduino with laptop serial monitor has no issues sending messages of temps for each unit. (ferm1,ferm2,ferm3, and glycol)
however my issue is receiving that data to the pi with usb cable.
i have serial in node set up with the proper baud rate. (9600)
but when i try to sepperate , split, each line to its own message , thats where im getting my but kicked.
when watching the serial monitor it will show "msg.payload : string[19]"
then the message . problem is the string number (string[19]) isnt only desplaying one device. its as if there is something causing them to scramble.
it may be they way my coding in arduino prints to serial causing there error.
is there a way to find line that starts with ferm1, ferm2, ferm3, and glycol and then take data only from that line in a new message?
i may have confused you all but i am confused and i am not that good at explaining what is inside my head.
cheers.

  1. What version of Node-RED and Node.js are you using? (look at the NR startup log for this info)
  2. Whch arduino are you using and does it support WiFi?
  3. what sensor are you using on the arduino to read the temperatures?
  4. have you coded the code on the arduino yourself or are you using a package like ESPEasy or Tasmoda? If using a package, which one?
  5. attach a debug node (set to display the complete msg object) to the output of serial-in node. See below for how to do this
  6. export your flow and attach it to a reply. See below for how to do this

How to get data from messages

There’s a great page in the docs that will explain how to use the debug panel to find the right path to any data item.

Pay particular attention to the part about the buttons that appear under your mouse pointer when you over hover a debug message property in the sidebar.

BX00Cy7yHi

https://nodered.org/docs/user-guide/messages

How to post code or flows

In order to make code readable and usable it is necessary to surround your code with three backticks (also known as a left quote or backquote ```)

``` 
   code goes here 
```

You can edit and correct your post by clicking the pencil :pencil2: icon.

See this post for more details - How to share code or flow json

Thanks Zenofmud for responding and giving me tips. On how to enter info.

I have read many forums seeking help with this project over the last year and I have noticed to many people are quick to criticize the person seeking help because they don’t understand how to share code or flow. Thumbs up to you for actually explaining that in response. Thanks! Here is what I have so far.

  1. “What version of Node-RED and Node.js are you using? (look at the NR startup log for this info)
  2. Whch arduino are you using and does it support WiFi?
  3. what sensor are you using on the arduino to read the temperatures?
  4. have you coded the code on the arduino yourself or are you using a package like ESPEasy or Tasmoda? If using a package, which one?
  5. attach a debug node (set to display the complete msg object) to the output of serial-in node. See below for how to do this
  6. export your flow and attach it to a reply. See below for how to do this

response.

  1. node-red v. 1.2.9
  2. arudino mega 2560
  3. as in my post. Dallas 1-wire (ds18b20) temp sensors
  4. I am using someons example code and I tweeked it for my settings.
  5. I have attached the debug nodes and my issue has been the monitor doesn’t slow enough for me to retrieve the info like I keep seing in videos.
  6. Here is flow and Arduino code. Also note no this Arduino doesn’t have wifi, but is connected to raspberry pi (4b+) via usb
//0x28, 0xA3, 0xFC, 0x96, 0xF0, 0x01, 0x3C, 0x20

// This Arduino sketch reads DS18B20 "1-Wire" digital

// temperature sensors.

// Tutorial:

// http://www.hacktronics.com/Tutorials/arduino-1-wire-tutorial.html

#include <OneWire.h>

#include <DallasTemperature.h>

// Data wire is plugged into pin 3 on the Arduino

#define ONE_WIRE_BUS 4

// Setup a oneWire instance to communicate with any OneWire devices

OneWire oneWire(ONE_WIRE_BUS);

// Pass our oneWire reference to Dallas Temperature.

DallasTemperature sensors(&oneWire);

// Assign the addresses of your 1-Wire temp sensors.

// See the tutorial on how to obtain these addresses:

// http://www.hacktronics.com/Tutorials/arduino-1-wire-address-finder.html

DeviceAddress ferm1 = { 0x28, 0x9D, 0xFD, 0x07, 0xD6, 0x01, 0x3C, 0x38 };//0x28, 0x9D, 0xFD, 0x07, 0xD6, 0x01, 0x3C, 0x38

DeviceAddress ferm2 = {0x28, 0xAA, 0x5A, 0x07, 0xD6, 0x01, 0x3C, 0x32 };

DeviceAddress ferm3 = { 0x28, 0x1B, 0x55, 0x07, 0xD6, 0x01, 0x3C, 0x6D };

DeviceAddress glycol = { 0x28, 0xD9, 0xD7, 0x96, 0xF0, 0x01, 0x3C, 0xFF };//0x28, 0xD9, 0xD7, 0x96, 0xF0, 0x01, 0x3C, 0xFF

//DeviceAddress dogHouse3Thermometer = { 0x28, 0x9B, 0xE1, 0x96, 0xF0, 0x01, 0x3C, 0xFC };

void setup(void)

{

// start serial port

Serial.begin(9600);

// Start up the library

sensors.begin();

// set the resolution to 10 bit (good enough?)

// sensors.setResolution(ferm1, 10);

sensors.setResolution(ferm1, 10);

sensors.setResolution(ferm2, 10);

sensors.setResolution(ferm3, 10);

sensors.setResolution(glycol, 10);

}

void printTemperature(DeviceAddress deviceAddress)

{

float tempC = sensors.getTempC(deviceAddress);

if (tempC == -127.00) {

Serial.print("Error getting temperature");

} else {

// Serial.print("C: ");

//Serial.print(tempC);

// Serial.print(" F: ");

Serial.print(DallasTemperature::toFahrenheit(tempC));

}

}

void loop(void)

{

delay(1000);

// Serial.print("Getting temperatures...\n\r");

sensors.requestTemperatures();

Serial.print("ferm1 is: ");

printTemperature(ferm1);

Serial.print(",");

Serial.print("ferm2 is: ");

printTemperature(ferm2);

Serial.print(",");

Serial.print("ferm3 is: ");

printTemperature(ferm3);

Serial.print(",");

Serial.print("Glycol is: ");

printTemperature(glycol);

//Serial.print("\n");

//Serial.print("Dog House3 temperature is: ");

// printTemperature(dogHouse3Thermometer);

Serial.print("\n");

}

So I did modify my code after I made post yesterday.

  1. printTemperature(ferm3);
  2. Serial.print(",");
  3. Originally it was serial.print(“\n”)
  4. The last line that is Serial.print(“\n”) was (“\n\r”)

I changed them so the message will change how it is sent.

  1. All 4 temps will print on same line but be sepperated by a “,”
  2. So there is no empty line between each message.

As soon as I get to brewery ill update the Arduino, and see if it made it easier for me to separate data.

Here is the flow im working on for node-red

[{"id":"a4a4cc05.c99a4","type":"function","z":"91e83857.47b1e8","name":"","func":"var outputMsgs = [];\nvar values = msg.payload.trim().split(\",\");\nfor(var v in values) {\n outputMsgs.push({payload:values[v]});\n}\nreturn outputMsgs;","outputs":4,"noerr":0,"initialize":"","finalize":"","x":460,"y":500,"wires":[["b5ac65dc.434cd8"],[],[],[]]},{"id":"6a850ce1.55a334","type":"debug","z":"91e83857.47b1e8","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":820,"y":800,"wires":[]},{"id":"67f304e4.fda95c","type":"split","z":"91e83857.47b1e8","name":"","splt":"\\n","spltType":"str","arraySplt":"1","arraySpltType":"len","stream":true,"addname":"","x":500,"y":700,"wires":[["6a850ce1.55a334"]]},{"id":"bdc65909.716dc8","type":"serial in","z":"91e83857.47b1e8","name":"","serial":"1b6f2bb3.a6e3f4","x":220,"y":700,"wires":[["a4a4cc05.c99a4","b5097512.401748","730a6754.81c128"]]},{"id":"b5097512.401748","type":"csv","z":"91e83857.47b1e8","name":"","sep":",","hdrin":true,"hdrout":"all","multi":"one","ret":"\\n","temp":"","skip":"0","strings":true,"include_empty_strings":true,"include_null_values":true,"x":500,"y":700,"wires":[[]]},{"id":"730a6754.81c128","type":"debug","z":"91e83857.47b1e8","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":520,"y":800,"wires":[]},{"id":"b5ac65dc.434cd8","type":"debug","z":"91e83857.47b1e8","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":620,"y":600,"wires":[]},{"id":"1b6f2bb3.a6e3f4","type":"serial-port","serialport":"/dev/ttyACM0","serialbaud":"9600","databits":"8","parity":"none","stopbits":"1","waitfor":"","dtr":"none","rts":"none","cts":"none","dsr":"none","newline":"\\n","bin":"false","out":"char","addchar":":","responsetimeout":"20000"}]

so i replied to post in email and the ''' didnt work so i had to edit post onlnine.

Edit You already did it! :grinning:

It might be a good plan to get your arduino to send the data in Json format
{
ferm1: 11,
ferm2: 22,
ferm3: 33,
glycol: 44
}
Then Node-red can access the data as msg.payload.ferm1 or msg.payload.glycol etc.

There is a tutorial at https://www.youtube.com/watch?v=z_rPvQhKTfY It looks good but I have not tested it because I don't have a spare arduino.

Edit - I fished out an ESP and tried following this tutorial, it seems it's out of date. Looking for a more recent library.

1 Like

yes the replying in email adding the quotes didnt work so i edited online.
second
see my pictures of the serial monitor when connected to arduino with computer. temp reads great. but when i have connected to raspberry pi you can see with debug that its not always getting the temp.

is this a timing thing. obviously with the serial monitor its real time and quick. however im assuming there is a delay with the usb communication that is causing the error.

I do not know much coding. and i really dont understand the Json string stuff you guys talk about.

It may be a timing problem in the arduino yes.
Certainly in your code editor you are getting reliable readings and in Node-red you have lots of error messages. The messages are specified in the arduino code, so it is not a comms problem.

Essentially I'm suggesting that your Arduino code collects the data from the four sensors and sends it all together to the Raspberry Pi, rather than measuring the first sensor, printing it, measuring the next, printing it, ...

well im not good at coding as you can see from sketch i just tweaked what someoe else wrote.
i though maybe it was a power supply issue.
so i hardwired arduino to external power supply rather than trust usb power being enough to feed 5 volts from arduino to the 4 sensors (about 30ft.)
but i still have the same issue. weird thing is my code says to type that if it fails to read sensor.

i'm obviously gonna have to smooth data to feed to dashboard ui.
but weird because i dont have to do that with the 1 wire sensors hooked directly to the pi.

Sorry my responses are scattered and confusing. Yes I agree on getting them as one however, I have a feeling that unless I figure the correct timing I may still have same issue. But I'm not a coder, so I'll need help with how to get all read at once. The main thing is that the addresses in my code now reflect the correct fermenter or glycol tank

Try this arduino code and let us see what it produces.
I can't guarantee it will work since I dont have your arduino or sensors, and even if it runs OK it might not resolve any timing issue.

I had to install the ArduinoJson library v5.13.5 not the most recent version.

I changed the printTemperature() function so that it returns a value rather than Serial.print(), and made sure that it returns -127 rather than an error message because I put te function output into a variable of type float.

And in loop() it constructs the output as Json and prints it to the serial port all at once.

#include <OneWire.h>
#include <ArduinoJson.h>
#include <DallasTemperature.h>
// Data wire is plugged into pin 3 on the Arduino
#define ONE_WIRE_BUS 4
// Setup a oneWire instance to communicate with any OneWire devices
OneWire oneWire(ONE_WIRE_BUS);
// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);
// Assign the addresses of your 1-Wire temp sensors.
// See the tutorial on how to obtain these addresses:
// http://www.hacktronics.com/Tutorials/arduino-1-wire-address-finder.html
DeviceAddress ferm1 = { 0x28, 0x9D, 0xFD, 0x07, 0xD6, 0x01, 0x3C, 0x38 };//0x28, 0x9D, 0xFD, 0x07, 0xD6, 0x01, 0x3C, 0x38
DeviceAddress ferm2 = {0x28, 0xAA, 0x5A, 0x07, 0xD6, 0x01, 0x3C, 0x32 };
DeviceAddress ferm3 = { 0x28, 0x1B, 0x55, 0x07, 0xD6, 0x01, 0x3C, 0x6D };
DeviceAddress glycol = { 0x28, 0xD9, 0xD7, 0x96, 0xF0, 0x01, 0x3C, 0xFF };//0x28, 0xD9, 0xD7, 0x96, 0xF0, 0x01, 0x3C, 0xFF
//DeviceAddress dogHouse3Thermometer = { 0x28, 0x9B, 0xE1, 0x96, 0xF0, 0x01, 0x3C, 0xFC };

void setup(void)
{
// start serial port
Serial.begin(9600);
// Start up the library
sensors.begin();
// set the resolution to 10 bit (good enough?)
// sensors.setResolution(ferm1, 10);
sensors.setResolution(ferm1, 10);
sensors.setResolution(ferm2, 10);
sensors.setResolution(ferm3, 10);
sensors.setResolution(glycol, 10);
}

float printTemperature(DeviceAddress deviceAddress)
{
  float tempC = sensors.getTempC(deviceAddress);
  if (tempC == -127.00) {
    return(-127.00);
  } else {
    return(DallasTemperature::toFahrenheit(tempC));
  }
}

void loop() {
  delay(1000);
    StaticJsonBuffer<400> jBuffer;
    JsonObject& mydata = jBuffer.createObject();
   
  sensors.requestTemperatures();
  
    float glycoltemp = printTemperature(glycol);
    float ferm1temp =  printTemperature(ferm1);
    float ferm2temp =  printTemperature(ferm2);
    float ferm3temp =  printTemperature(ferm3);
    
    mydata["ferm1"] =  ferm1temp;
    mydata["ferm2"] =  ferm2temp;
    mydata["ferm3"] =  ferm3temp;
    mydata["glycol"] = glycoltemp;
    
    mydata.prettyPrintTo(Serial);   
    Serial.println();
}
1 Like

i get this error message

BlockquoteArduino: 1.8.19 (Windows Store 1.8.57.0) (Windows 10), Board: "Arduino Mega or Mega 2560, ATmega2560 (Mega 2560)"

sketch_feb11c:45:11: error: StaticJsonBuffer is a class from ArduinoJson 5. Please see Redirecting… to learn how to upgrade your program to ArduinoJson version 6

 StaticJsonBuffer<400> jBuffer;

       ^~~~~~~~~~~~~~~~~~~~~~~~                                                                                                                                   

exit status 1

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException

at org.fife.ui.rsyntaxtextarea.TokenMakerBase.addNullToken(TokenMakerBase.java:80)

at org.fife.ui.rsyntaxtextarea.modes.CPlusPlusTokenMaker.yylex(CPlusPlusTokenMaker.java:2327)

at org.fife.ui.rsyntaxtextarea.modes.CPlusPlusTokenMaker.getTokenList(CPlusPlusTokenMaker.java:1919)

at org.fife.ui.rsyntaxtextarea.RSyntaxDocument.getTokenListForLine(RSyntaxDocument.java:431)

at org.fife.ui.rsyntaxtextarea.SyntaxView.getLineWidth(SyntaxView.java:306)

at org.fife.ui.rsyntaxtextarea.SyntaxView.calculateLongestLine(SyntaxView.java:110)

at org.fife.ui.rsyntaxtextarea.RSyntaxTextArea.refreshFontMetrics(RSyntaxTextArea.java:2106)

at org.fife.ui.rsyntaxtextarea.RSyntaxTextArea.setFont(RSyntaxTextArea.java:2545)

at processing.app.EditorTab.applyPreferences(EditorTab.java:333)

at processing.app.Editor.lambda$selectTab$52(Editor.java:1457)

at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:311)

at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:758)

at java.awt.EventQueue.access$500(EventQueue.java:97)

at java.awt.EventQueue$3.run(EventQueue.java:709)

at java.awt.EventQueue$3.run(EventQueue.java:703)

at java.security.AccessController.doPrivileged(Native Method)

at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:74)

at java.awt.EventQueue.dispatchEvent(EventQueue.java:728)

at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:205)

at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)

at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)

at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)

at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)

at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)

StaticJsonBuffer is a class from ArduinoJson 5. Please see Redirecting… to learn how to upgrade your program to ArduinoJson version 6

This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.

says i need to update program to arduinojson 6

Probably this:

https://arduinojson.org/v6/error/jsonbuffer-is-a-class-from-arduinojson-5/

ok it took me a minute. but instead of upgrading code to 6 i just installed that last ver.5 of Json
now i do still have an issue of it retrieving data. its not always getting the communication.
see pictures



i may not be wording this question correctly.....
so i am getting good readings most of the time.
is there a way to filter out the readings that are "-127"
can this be done in arduino in the json program or should it be done in node red using something like a function node or a smotthing node?
aka if " " is "-127" replace with last valid reading....
and thanks again.i never say that enough.

Yes you can filter out the bad readings.
But first let's try and eliminate them on the Arduino.

Can you try moving sensors.requestTemperatures(); to the top of the printTemperature function?

Note: I don't know what requestTemperatures() does, or if it's needed at all.

If that's no better, put it back where it was and try a delay of 250ms between successive calls to printTemperature.

It might be worth looking on Arduino forums to see if someone else has been getting bad readings and solved it.