Hello again. As I said, I have managed to get my Arduino MQTT to do pretty well. So having managed to parse the payload, now I want to decode the parsed payload, in partic DHT22 temp and humidity. So here's my code -
#include <Ethernet.h>
#include <PubSubClient.h>
#include <SPI.h>
#include <ArduinoJson.h>
#include <String.h>
#include <lmic.h>
//#include <math.h>
StaticJsonDocument < 512 > doc;
boolean TimeToParse = false;
char data[20] = "";
char devEUI[17] = "";
char node5[] = { "01f3b8fb5a1c1050" }; // Node 5 devEUI
char node4[] = { "007e47c0ac6183b2" }; // Node 4 devEUI
float temperature;
float humidity;
float rawTemp;
float rawHumid;
var decoded = {};
byte mac[] = { 0xA8, 0x61, 0x0A, 0xAE, 0x6a, 0x0b }; // (grey) MAC address Arduino Ethernet Shield MQTT client
IPAddress ip(192, 168, 1, 51); // associated static IP address Arduino MQTT client
// byte mac[] = { 0xA8, 0x61, 0x0A, 0xAE, 0x64, 0x3a }; // (red) MAC address Arduino Ethernet Shield MQTT client
// IPAddress ip(192, 168, 1, 52); // associated static IP address Arduino MQTT client
IPAddress server(192, 168, 1, 227); // Static IP address RAK7249 built-in LoRa server Barn
// IPAddress server(192, 168, 1, 250); // Static IP address RAK7249 built-in LoRa server network room
void callback(char *topic, byte *payload, unsigned int length) // ISR
{
deserializeJson(doc, payload, length); // Deserialize the JSON document
TimeToParse = true; // set flag for loop to parse payload
}
EthernetClient ethClient;
PubSubClient mqttClient(ethClient);
String clientID = String(mac[4]) + String(mac[5]) ; // use mac address to create clientID
void reconnect()
{
while (!mqttClient.connected()) // Loop until reconnected
{
if (mqttClient.connect(clientID.c_str())) // Attempt to connect
{
mqttClient.subscribe("application/+/device/+/rx");
} else {
delay(5000); // Wait 5 seconds before retrying
}
}
}
void setup()
{
Serial.begin(115200);
Ethernet.begin(mac, ip);
delay(5000); // Allow the hardware to sort itself out
mqttClient.setServer(server, 1883);
mqttClient.setCallback(callback);
}
void loop()
{
if (!mqttClient.connected())
{
reconnect();
}
mqttClient.loop();
if (TimeToParse) // if true, then there's data to be parsed from the ISR
{
strlcpy(devEUI, doc["devEUI"], sizeof(devEUI)); // parse payload
strlcpy(data, doc["data"], sizeof(data));
if (strcmp(devEUI, node4) == 0) // Hello, world
{
Serial.print ("\nNode 4 devEUI = ");
Serial.print(devEUI);
Serial.print(" data = ");
Serial.print(data);
Serial.print("\n");
}
if (strcmp(devEUI, node5) == 0 ) // DHT22
{
// temperature
rawTemp = data[0] + data[1] * 256;
decoded.temperature = sflt162f(rawTemp) * 100;
// humidity
rawHumid = data[2] + data[3] * 256;
decoded.humidity = sflt162f(rawHumid) * 100;
Serial.print ("\nNode 5 devEUI = ");
Serial.print (devEUI);
Serial.print (" data = ");
Serial.print (data);
Serial.print (" temperature = ");
Serial.print (temperature);
Serial.print ("° C Humidity = ");
Serial.print (humidity);
Serial.print ("% RHC");
Serial.print ("\n");
}
TimeToParse = false; // turn off the parsing flag
}
}
function sflt162f(rawSflt16)
{
// rawSflt16 is the 2-byte number decoded from wherever;
// it's in range 0..0xFFFF
// bit 15 is the sign bit
// bits 14..11 are the exponent
// bits 10..0 are the the mantissa. Unlike IEEE format,
// the msb is transmitted; this means that numbers
// might not be normalized, but makes coding for
// underflow easier.
// As with IEEE format, negative zero is possible, so
// we special-case that in hopes that JavaScript will
// also cooperate.
//
// The result is a number in the open interval (-1.0, 1.0);
//
// throw away high bits for repeatability.
rawSflt16 &= 0xFFFF;
// special case minus zero:
if (rawSflt16 == 0x8000)
return -0.0;
// extract the sign.
var sSign = ((rawSflt16 & 0x8000) != 0) ? -1 : 1;
// extract the exponent
var exp1 = (rawSflt16 >> 11) & 0xF;
// extract the "mantissa" (the fractional part)
var mant1 = (rawSflt16 & 0x7FF) / 2048.0;
// convert back to a floating point number. We hope
// that Math.pow(2, k) is handled efficiently by
// the JS interpreter! If this is time critical code,
// you can replace by a suitable shift and divide.
var f_unscaled = sSign * mant1 * Math.pow(2, exp1 - 15);
return f_unscaled;
}
The relevant output from the compiler is this -
c:\Users\johno\Documents\Arduino\sketch_may13a v20.0\sketch_may13a v20.0.ino:40:1: error: 'var' does not name a type
var decoded = {};
^~~
c:\Users\johno\Documents\Arduino\sketch_may13a v20.0\sketch_may13a v20.0.ino:130:1: error: 'function' does not name a type; did you mean 'union'?
function sflt162f(rawSflt16)
^~~~~~~~
union
c:\Users\johno\Documents\Arduino\sketch_may13a v20.0\sketch_may13a v20.0.ino: In function 'void loop()':
c:\Users\johno\Documents\Arduino\sketch_may13a v20.0\sketch_may13a v20.0.ino:109:7: error: 'decoded' was not declared in this scope
decoded.temperature = sflt162f(rawTemp) * 100;
^~~~~~~
c:\Users\johno\Documents\Arduino\sketch_may13a v20.0\sketch_may13a v20.0.ino:109:29: error: 'sflt162f' was not declared in this scope
decoded.temperature = sflt162f(rawTemp) * 100;
^~~~~~~~
c:\Users\johno\Documents\Arduino\sketch_may13a v20.0\sketch_may13a v20.0.ino: At global scope:
c:\Users\johno\Documents\Arduino\sketch_may13a v20.0\sketch_may13a v20.0.ino:130:1: error: 'function' does not name a type; did you mean 'union'?
function sflt162f(rawSflt16)
^~~~~~~~
union
I have taken the basic decoder from arduino-lmic/ttn-otaa-feather-us915-dht22.ino at master · mcci-catena/arduino-lmic · GitHub
Can anyone please help me with these errors. Many thanks.