Guys,
i'm fighting with my Flow. I'm receiving mqqt messages from ESP01 which reads BME280 and 32 ADC channels (NTC resistors for temprature readings). Additionally i hooked up PZEM-004 for power monitoring. All of that to tiny ESP01.
ESP01 firmware i wrote created topic in JSON form manually (i'm not using ArduinoJson lib).
My Flow receives it with no problem, parsing to object then i'm using Function node to make NTC calculations (to translate ADC reading of NTC to its resistances in Ohms and then, using Steinhart-Hart equation, to calculate temperature. In the same Function node im preparing output to InfluxDB.
The problem is i'm getting "NaN" instead of temperature readings...
Here is my function:
let device = msg.payload.dev;
msg.payload = {
"cisnienie" : msg.payload.pre,
"temperatura" : msg.payload.tem,
"wilgotnosc" : msg.payload.hum,
"napiecie_sieciowe" : msg.payload.vol,
"pobor_pradu" : msg.payload.cur,
"moc_pobierana" : msg.payload.pwr,
"licznik_energii" : msg.payload.ene,
"czestotliwosc" : msg.payload.frq,
"PF" : msg.payload.p_f,
"czujnik_gazu" : msg.payload.gaz,
"ADC": msg.payload.ADC}
//now get 32 values from ADC
for (let i = 0; i < 32; i++)
{
let U_ADC_int = Number(msg.payload.ADC[i]); //i have now 16-bit integer value from ADC in
U_ADC_int
if ((U_ADC_int >= 1000)&(U_ADC_int < 40000)) //if integer value is within the range (1000 is ca
50mV, 40000 is ca 2 V) then convert integers to volts (65536 is 3.3V)
{
let U_zasil_int = Number(msg.payload.zas); //U_zasil is measured power supply value
var R = 10000 * (U_ADC_int / (U_zasil_int - U_ADC_int)) //10000 is for 10kOhm resistor used in
divider, calculation is just Ohm Law and voltage divider.
//and then Steinhart-Hart:
var R0 = 10000; //10k type NTC
var T0 = 273.15 + 25;
var B = 3950; //NTC coefficient
var T = 1 / ( (1/T0) + (1/B) * Math.log(R/R0) );
T = T - 273.15;
msg.payload[`kanal_${(i+1)}`] = Number(T.toFixed(1));
} else{
//the rest of the code to process ADC values outside of range: i.e. when i put jumper instead of NTC so i can use ADC channel for switches or connect photoresistor and so on...
}
}
delete msg.payload.ADC;
msg.payload = [msg.payload, {"deviceID" : device, "location": "basement"}];
return msg;
This is the continuation of the threat that was automatically closed... Well, i haven't had time to play with NodeRED... Here is the thread:
As you can see i've changed approach to reduce the amount of data sent via mqtt - shorter names and 16bit ADC values instead of floats. Now i need to calculate voltage value and then resistance value in NodeRed instead of in ESP8266. The reason for that is simplicity of changing things in NodeRED. Imagine i'm connecting photoresistor instead of NTC. In the old approach i would have to redo firmware and flash ESP. By sending raw ADC data to NodeRED i can modify Function node and go further.
The other thing is: sometimes some NTC will be disconnected or values are outside of the range - in this case i need to discard them and not to sent to InfluxDB so it will be not shown in Grafana trends.
For this i'm just using this:
msg.payload[kanal_${(i+1)}
] = Number(T.toFixed(1));
inside the loop. Is there some different approach to achieve it? And regarding toFixed() method - this one is just truncating the value. But 21.19 C become 21.1 C. What is the method for Math rounding? I found too many confusion regarding rounding and in many places it is recommended to use toFixed(). But what about rounding?
I've checked JS Math methods. But Math.round(x) returns x rounded to its nearest integer but i need not integer but float with on decimal place accuracy. The only way i can think to sort it is multiplying my temmperature by 10, applying Math.round(x) and dividing by 10 to go back to float. Kinda stupid.
JavaScript is new to me. I'm C language amateur:)
Thank you for advices!