I am periodically reading the temperature and Humidity values from a DHT22 sensor in a green house tunnel.
The sensor is attached to a Arduino Pro Mini. The Pro Mini also has a nF24l01 transceiver attached to it, and the readings are transmitted to another nF24L01/Arduino Pro Mini in my office.
The Arduino is connected to a desktop PC via a USB serial cable.
The intention is to write the received Temperatue and Humidity readings to a file in a CSV format.
I am receiving all the data over the radio link which in-turn is feed to my PC via my USB port. I am running Node with a file called index.js.
Below is the code from the Arduino connected to the PC. It is the receiver side of the radio link.
[code] /* See documentation at https://nRF24.github.io/RF24 See License information at root directory of this library Author: Brendan Doherty (2bndy5) */ /** A simple example of sending data from 1 nRF24L01 transceiver to another. String message = ""; This example was written to be used on 2 devices acting as "nodes". Use the Serial Monitor to change each node's behavior. */ #include <SPI.h> #include <printf.h> #include <nRF24L01.h> #include <RF24.h> struct dataStruct { float HumH; float TempC; } myData; bool newData = false; RF24 radio(9, 10); // using pin 7 for the CE pin, andradio.read(&data, sizeof(MyData)); pin 8 for the CSN pin uint8_t address[][6] = {"1Node", "2Node"}; bool radioNumber = 1; // 0 uses address[0] to transmit, 1 uses address[1] to transmit bool role = false; // true = TX role, false = RX role void setup() { Serial.begin(115200); if (!radio.begin()) { Serial.println(F("radio hardware is not responding!!")); while (1) {} // hold in infinite loop } radio.setPALevel(RF24_PA_HIGH); // RF24_PA_MAX is default. radio.setPayloadSize(sizeof(dataStruct)); // float datatype occupies 4 bytes radio.openWritingPipe(address[radioNumber]); // always uses pipe 0 radio.openReadingPipe(1, address[!radioNumber]); // using pipe 1 radio.startListening(); // put radio in RX mode // For debugging info printf_begin(); // needed only once for printing details radio.printDetails(); // (smaller) function that prints raw register values radio.printPrettyDetails(); // (larger) function that prints human readable data } // end of setup void getData() { if (radio.available()) { //Serial.println("Radio is available******"); radio.read(&myData, sizeof(dataStruct)); newData = true; } //Serial.println("Radio is NOT available******"); } void showData() { if (newData == true) { String message = ""; message = message + "{"humidity": "; message = message + myData.HumH; message = message + ", "temperature": "; message = message + myData.TempC; message = message + "}"; Serial.println(message); newData = false; } } void loop() { getData(); showData(); } [/code]
Below is a screen shot of the serial output of the Arduino Pro Mini connected to my PC shown what is being received from the green house and what is being sent to the PC.
Arduino Serial port screen shot
The index2.js code is listed below
const SerialPort = require('serialport'); //const Readline = new SerialPort.parsers.Readline('n'); const port = new SerialPort('/dev/ttyUSB0', { baudRate: 115200 }); const fs = require('fs'); const { endianness } = require('os'); const { exit } = require('process'); const { Console } = require('console'); //const logIntervalMinutes = 1; let lastMoment = new Date(); function tryParseJson(str) { try { JSON.parse(str); } catch (e) { console.log("JSON error") return false; } return JSON.parse(str); } console.log('Initialising...'); port.on('open', function () { console.log('Opened port...'); port.on('data', function (data) { const sensorData = tryParseJson(data); console.log('Data: ' + data); const moment = new Date(); fs.appendFile('log.txt', `n${sensorData.temperature} , ${sensorData.humidity} , ${moment}`, function (err) { if (err) { console.log('Your Jason has failed to get a complete string...'); } else { console.log('Logged data: ', moment); }; }); }); });
When I run node index2.js and look at the log.txt file I see that sometimes the temp/Hum values are listed as undefined as show in the screen shot below.
After a bit of debugging I saw the following in the console.log() as show in the screen shot below.
Console.log() screen shot with program running.
So my problem is that every now and again, the fs.append can’t determine the value of sensorData.temperature and sensorData.humidity. The fs.append still appends a record to the log.txt file but the 1st two fields have undefined in them.
fs.appendFile('log.txt', `n${sensorData.temperature} , ${sensorData.humidity} , ${moment}`, function (err) { if (err) { console.log('Your Jason has failed to get a complete string...'); } else { console.log('Logged data: ', moment); }; });
It appears that function tryParseJson(str) sometimes only gets some of the data and not the full JSON object. see code below,
function tryParseJson(str) { try { JSON.parse(str); } catch (e) { console.log("JSON error") return false; } return JSON.parse(str);
I see that catch (e) gets called and my console.log(“JSON error”) gets printed.
I need some help to work out how to resolve this..
Advertisement
Answer
I did some changes to my code to check the contents of the const sensorData = tryParseJson(data) as shown below.
const sensorData = tryParseJson(data); if (sensorData.temperature == undefined || sensorData.humidity == undefined){ //console.log('Temperature or Humidity is undefined'); } else {
and then used a IF statement to append or not append to the log.txt file.
Everything is now working, however there is still one minor issue.
I noticed something in the log.txt file. If the value of the temp or humidity is say 25.00, then the file will have 25. will no trailing zero’s. This will not happen say if the temp is 25.4
if I check the values of sensorData in this line of code const sensorData = tryParseJson(data); the values are correct. They seem to change with fs.appendFile
Any idea why?