Introduction: ESP8266-01 Temp/RH Sensor Readings Over JSON/MQTT

About: Maker of things.... some get completed...

Overview

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.

Data presented in the Domoticz Dashboard

What is MQTT?

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.

Step 1: Building the Sensor

As always I build the prototype on a breadboard and soak test before the final soldering into an 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.

Step 2: Coding

The software is written in Arduino IDE and designed to connect to my local MQTT broker on startup then utilizes Chrono.h library to read and send the temperature and humidity readings once every 60 seconds.

Below is a summary of some aspects of the attached code:

#include "ESPHelper.h"
#include "Chrono.h"
#include "ArduinoJson.h"
#include "DHT.h"

Add Appropriate Libraries

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.

#define DHTPIN 0 

DHT22 Pin Definition

 #define DHTTYPE DHT22 

The library can support other sensors eg 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 change, 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 it does not equal 'Nan' 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, the idx number is the devices individual ID on my home automation system.

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 the topic "domoticz/in" :

myESP.publish(svrtopic, JSONmessageBuffer, false);
Microcontroller Contest

Participated in the
Microcontroller Contest