As part of my Home Automation I wanted to monitor various Rooms mostly temperature, however for a couple of rooms I wanted to monitor relative humidity as well so I purchased a couple of DHT22 sensors which will provide both in a single package. This room would go on to form part of my energy saving project with respect to the average house temperature, for this to work I needed to send the readings to my Domoticz Home Automation system so they can be logged but also sent to other interest clients to use the data, this meant I had to send the data in JSON format in accordance to Domoticz' API over MQTT IoT Protocol via the WiFi connection.
What is JSON?JSON or Java Script Object Notation is a way structuring text to be exchanged as data. So rather just sending a temperature value to a device you could send an id and a time stamp all in the same message as object, this is useful for home automation systems when there are many temperature sensors.
For Example in this project I use the message : {"idx":11, "nvalue":0, "svalue":"19.70;44.00;0"}
Object "idx", is the unique id of this sensor in my system.
Object "nvalue" isn't used and needs a default 0.
Object "svalue" is the temp, hum, and humidity stat values in the prescribed order.
The home automation system will receive this and parse the object into the database.
Taken from MQTT.org: 'MQTT is a machine-to-machine (M2M)/"Internet of Things" connectivity protocol. It was designed as an extremely lightweight publish/subscribe messaging transport.' I use it for the protocol that is end messages over my wifi network. The Raspberry Pi Zero running my Home Automation System is the MQTT broker for the network and runs 'mosquitto' for this service.
Building the SensorAs always I build the prototype on a breadboard and soak test before the final soldering into a install-able solution. Apologies I have no pictures of these steps!! The ESP8266-01 requires a 3.3v power supply so I use a step down converter which has a committed 5vdc Power Supply unit connected, my installation location has local socket outlets so I can plug this sensor in without considerations of powering it too much (for example do I use batteries? how long will they last?). The CH_PD pin of the ESP needs to be pulled high for the ESP to start running so I pulled this via a 10 Kohm resistor. The DHT22 requires a power supply of 3.3-5vdc I chose to power from my 5vdc side additionally a pull up resistor is advised across the VCC and data pin so I placed a 10 Kohm resistor in this place.
The software is written in Arduino IDE and desinged to connect to my local MQTT broker on startup then utilises chrono.h library to read and send the temperature and humidity readings once every 60 seconds.
'Chono.h'
"Chrono myChrono(Chrono::SECONDS);" - this sets up the chrono library to work in seconds, I don't need any scaling below this. used in the initial setup
"myChrono.restart();" this restarts the timer at 0 seconds used in the void setup()
"if (myChrono.hasPassed(60, true)) {" used in the void loop() after 60 seconds run the code in the if statement, the addition of the true reset the timer to 0 when 60 seconds has elapsed.
'DHT.h'
#define DHTPIN 0 Pin Definition
#define DHTTYPE DHT22 the library can support other sensors, e.g. DHT11 so a simple definition to tell the library what sensor I am using
DHT dht(DHTPIN, DHTTYPE); supply the above info to the library
dht.begin(); used in void setup(); to start the DHT software
float h = dht.readHumidity(); take a Humidity reading and place in the float variable 'h'
float hum = h - HCal; I noticed the readings needed calibrating so I have an offset that I can changed, the result being the value I send for use
float t = dht.readTemperature(); take a Temperature reading and place in the float variable 't'
float tmp = t - TCal; again I noticed the readings needed calibrating so I have an offset that I can change, the result being the value I send for use
'ArduinoJson.h'
String mystring1;
mystring1 = String(hum);
String mystring2;
mystring2 = String(tmp);
As mentioned above the JSON message needs to be text so I convert the float values into strings that can be added the message.
if (mystring1 != mystring2){
LastKnownT = mystring2;
LastKnownH = mystring1;
}
else if (mystring1 == mystring2){
Serial.println("Sensor Error");
mystring2 = LastKnownT;
mystring1 = LastKnownH;
}
I put it this piece in case of sensor errors so I don't send 'NaN' and other unreasonable values to the log. When the sensor is missing the values returned are NaN so if both temp and humidity equals NaN then I send the last good value else if does not then the last good reading is sent.
StaticJsonBuffer<300> JSONbuffer; firstly create a buffer to store the message
JsonObject& JSONencoder = JSONbuffer.createObject();
JSONencoder["idx"] = 11; Start adding the objects with text associations
JSONencoder["nvalue"] = 0;
JSONencoder["svalue"] = LastKnownT+";"+LastKnownH+";"+HumStat;
char JSONmessageBuffer[100];
JSONencoder.printTo(JSONmessageBuffer, sizeof(JSONmessageBuffer));
The above builds the JSON message and adds the last known readings and creates a JSON message like this:
{"idx":11, "nvalue":0, "svalue":"19.70;44.00;0"}
Finally I send it to the MQTT broker in topic "domoticz/in" :
myESP.publish(svrtopic, JSONmessageBuffer, false);
As you can see my sensor has been working for some time, being reliable and accurate:
Comments