IOT Sensor Project: ESP8266 with DHT11 Sensor sends Data to MQTT

PlattformIO Setup

  1. Copy & reload UDEV Rules that govern necessary permission rights to access hardware
$> curl -fsSL https://raw.githubusercontent.com/platformio/platformio-core/master/scripts/99-platformio-udev.rules | sudo tee /etc/udev/rules.d/99-platformio-udev.rules$> udevadm control --reload-rules
sudo usermod -a -G dialout $USER
sudo usermod -a -G plugdev $USER

Adding ESP8266 Support to PlatformIO

  1. Determine the correct version of your esp8266 board, and download the correct board version

Part 1: Test Program to Output Serial Data

#include <Arduino.h>void setup()  
{
Serial.begin(115200);
}
void loop() {
digitalWrite(LED_BUILTIN, HIGH);
delay(1000);
digitalWrite(LED_BUILTIN, LOW);
Serial.println("Hello World!");
}
> Executing task: platformio run --target upload <Processing nodemcuv2 (platform: espressif8266; board: nodemcuv2; framework: arduino)
---------------------------------------------------------------------------------------------
Verbose mode can be enabled via `-v, --verbose` option
CONFIGURATION: https://docs.platformio.org/page/boards/espressif8266/nodemcuv2.html
PLATFORM: Espressif 8266 (2.6.2) > NodeMCU 1.0 (ESP-12E Module)
HARDWARE: ESP8266 80MHz, 80KB RAM, 4MB Flash
PACKAGES:
- framework-arduinoespressif8266 3.20704.0 (2.7.4)
- tool-esptool 1.413.0 (4.13)
- tool-esptoolpy 1.20800.0 (2.8.0)
- tool-mklittlefs 1.203.210628 (2.3)
- tool-mkspiffs 1.200.0 (2.0)
- toolchain-xtensa 2.40802.200502 (4.8.2)
LDF: Library Dependency Finder -> http://bit.ly/configure-pio-ldf
LDF Modes: Finder ~ chain, Compatibility ~ soft
Found 29 compatible libraries
Scanning dependencies...
No dependencies
Building in release mode
Compiling .pio/build/nodemcuv2/src/main.cpp.o
Linking .pio/build/nodemcuv2/firmware.elf
Retrieving maximum program size .pio/build/nodemcuv2/firmware.elf
Checking size .pio/build/nodemcuv2/firmware.elf
Advanced Memory Usage is available via "PlatformIO Home > Project Inspect"
RAM: [=== ] 32.9% (used 26916 bytes from 81920 bytes)
Flash: [=== ] 25.1% (used 262200 bytes from 1044464 bytes)
...
Configuring upload protocol...
AVAILABLE: espota, esptool
CURRENT: upload_protocol = esptool
Looking for upload port...
Auto-detected: /dev/ttyUSB0
Uploading .pio/build/nodemcuv2/firmware.bin
esptool.py v2.8
Serial port /dev/ttyUSB0
Connecting....
Chip is ESP8266EX
Features: WiFi
Crystal is 26MHz
MAC: 8c:aa:b5:7c:2f:21
Uploading stub...
Running stub...
Stub running...
Configuring flash size...
Auto-detected Flash size: 4MB
Compressed 266352 bytes to 196349...
Writing at 0x00000000... (8 %)
Writing at 0x00004000... (16 %)
Writing at 0x00008000... (25 %)
Writing at 0x0000c000... (33 %)
Writing at 0x00010000... (41 %)
Writing at 0x00014000... (50 %)
Writing at 0x00018000... (58 %)
Writing at 0x0001c000... (66 %)
Writing at 0x00020000... (75 %)
Writing at 0x00024000... (83 %)
Writing at 0x00028000... (91 %)
Writing at 0x0002c000... (100 %)
Wrote 266352 bytes (196349 compressed) at 0x00000000 in 17.3 seconds (effective 122.9 kbit/s)...
Hash of data verified.

Part 2: Connecting the DHT11 Sensor

#include <Arduino.h>
#include <Adafruit_Sensor.h>
#include <DHT.h>
#include <DHT_U.h>
#define DHTPIN 5
#define DHTTYPE DHT11
DHT_Unified dht(DHTPIN, DHTTYPE);void MQTT_connect();void setup() {
Serial.begin(9600);
dht.begin();
delay(10);
}
void blink() {
digitalWrite(LED_BUILTIN, HIGH);
delay(300);
digitalWrite(LED_BUILTIN, LOW);
}
void loop() {
blink();
sensors_event_t event;
dht.temperature().getEvent(&event);
String message = "\{\"node\":\"esp8266_dht11\", \"alive\":1, "
+ String("\"temperature\": ")
+ String(event.temperature);
dht.humidity().getEvent(&event);
message = message + String(", \"humidity\": ")
+ String(event.relative_humidity)
+ String("}");
Serial.println(message);
delay(50000);
}
  • The DHT sensor object is created with dht(DHTPIN, DHTTYPE) - be sure to use the correct data pin to which you connected, and to specify the correct sensor type
  • The sensor is started with dht.begin(), and then readings are executed by calling dht.temperature() and dht.humidity()
  • Concreate measurements are stored in an event object, which contains the concrete values.

Part 3: Adding Wi-Fi Connection

#include <Arduino.h>
#include <ESP8266WiFi.h>
#define WLAN_SSID "WLAN_SSID"
#define WLAN_PASS "WLAN_PASSWORD"
WiFiClient client;void setup() {
Serial.begin(9600);
delay(10);
Serial.print("Connecting to ");
Serial.println(WLAN_SSID);
WiFi.begin(WLAN_SSID, WLAN_PASS);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println();
}
void blink() {
digitalWrite(LED_BUILTIN, HIGH);
delay(300);
digitalWrite(LED_BUILTIN, LOW);
}
void loop() {
blink();
Serial.println("WiFi connected");
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
delay(5000);
}
Connecting to WIFI
........
WiFi connected
IP address:
192.168.42.112

Part 4: Connecting to MQTT and Sending Data

#include <Arduino.h>
#include <ESP8266WiFi.h>
#include "Adafruit_MQTT.h"
#include "Adafruit_MQTT_Client.h"
#define WLAN_SSID "WLAN_SSID"
#define WLAN_PASS "WLAN_PASSWORD"
#define SERVER "192.168.42.1"
#define SERVERPORT 1883
WiFiClient client;
Adafruit_MQTT_Client mqtt(&client, SERVER, SERVERPORT, "", "");
Adafruit_MQTT_Publish node = Adafruit_MQTT_Publish(&mqtt, "/sensors");
void MQTT_connect();void setup() {
digitalWrite(LED_BUILTIN, LOW);
Serial.begin(9600);
delay(10);
Serial.println("DHT11 MQTT Publisher");
Serial.print("Connecting to ");
Serial.println(WLAN_SSID);
WiFi.begin(WLAN_SSID, WLAN_PASS);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println();
Serial.println("WiFi connected");
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
MQTT_connect();
}
void loop() {
String message = "\{\"node\":\"esp8266_dht11_test\", \"alive\":1}"
Serial.println(message); char buffer[message.length() + 1];
message.toCharArray(buffer, message.length() + 1);
node.publish(buffer); delay(1000);
}
void MQTT_connect() {
int8_t ret;
Serial.print("Connecting to MQTT... "); uint8_t retries = 3;
while ((ret = mqtt.connect()) != 0) {
Serial.println(mqtt.connectErrorString(ret));
Serial.println("Retrying MQTT connection in 5 seconds...");
mqtt.disconnect();
delay(5000);
retries--;
if (retries == 0) {
while (1);
}
}
Serial.println("MQTT Connected!");
}
  • The MQTT client is created with Adafruit_MQTT_Client mqtt(&client, SERVER, SERVERPORT, "", ""), to which you pass the Wi-Fi client objects, then the IP and port of the MQTT server
  • An MQTT publisher is created with Adafruit_MQTT_Publish(&mqtt, "/sensors"), which receives the MQTT client and a topic name to which it should publish
  • To prevent compilation errors, its important to define void MQTT_connect(); before the setup() and loop() method, and then redefine it later
  • The connection is established by calling mqtt.connect() and checking that its return code is not 0; this is tried for three times with an additional waiting period in between
  • To publish a message, it needs to be converted to a char[], then call node.publish()

Storing and Visualizing DHT11 data

influx
Connected to http://localhost:8086 version 1.8.9
InfluxDB shell version: 1.8.9
> use sensors
Using database sensors
> show measurements
name: measurements
name
----
alive
cpu
cpu_temperatures
disk
environment
mem
system
> select * from environment
name: environment
time humidity room temperature
---- -------- ---- -----------
1632043840635145467 24.1 living_room 24.1
1632043856234155020 24 living_room 24
1632043871847026601 24 living_room 24
1632043887467691275 24 living_room 24
1632043903050309596 24 living_room 24
1632043918636092355 24 living_room 24
1632043934233190398 24 living_room 24
1632043949829200309 24 living_room 24
1632043965430243112 24 living_room 24
1632043981010088416 24 living_room 24
1632043996630429169 24 living_room 24

Complete Source Code

#include <Arduino.h>
#include <ESP8266WiFi.h>
#include "Adafruit_MQTT.h"
#include "Adafruit_MQTT_Client.h"
#include <Adafruit_Sensor.h>
#include <DHT.h>
#include <DHT_U.h>
#define WLAN_SSID "WLAN_SSID"
#define WLAN_PASS "WLAN_PASSWORD"
#define SERVER "192.168.42.200"
#define SERVERPORT 1883
#define DHTPIN 5
#define DHTTYPE DHT11
#define DEEP_SLEEP_TIME 1800WiFiClient client;
Adafruit_MQTT_Client mqtt(&client, SERVER, SERVERPORT, "", "");
Adafruit_MQTT_Publish node = Adafruit_MQTT_Publish(&mqtt, "/sensors");
DHT_Unified dht(DHTPIN, DHTTYPE);void MQTT_connect();void setup() {
//pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, LOW);
Serial.begin(9600);
delay(10);
dht.begin();
delay(10);
Serial.println("DHT11 MQTT Publisher");
Serial.print("Connecting to ");
Serial.println(WLAN_SSID);
WiFi.begin(WLAN_SSID, WLAN_PASS);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println();
Serial.println("WiFi connected");
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
}
void blink() {
digitalWrite(LED_BUILTIN, HIGH);
delay(300);
digitalWrite(LED_BUILTIN, LOW);
}
void loop() {
MQTT_connect();
blink();
sensors_event_t event;
dht.temperature().getEvent(&event);
String message = "\{\"node\":\"esp8266_dht11\", \"alive\":1, "
+ String("\"temperature\": ")
+ String(event.temperature);
dht.humidity().getEvent(&event);
message = message + String(", \"humidity\": ")
+ String(event.relative_humidity)
+ String("}");
Serial.println(message); char buffer[message.length() + 1];
message.toCharArray(buffer, message.length() + 1);
node.publish(buffer); if(! mqtt.ping()) {
mqtt.disconnect();
}
ESP.deepSleep(DEEP_SLEEP_TIME * 1000000);
yield();
}
void MQTT_connect() {
int8_t ret;
if (mqtt.connected()) {
return;
}
Serial.print("Connecting to MQTT... "); uint8_t retries = 3;
while ((ret = mqtt.connect()) != 0) {
Serial.println(mqtt.connectErrorString(ret));
Serial.println("Retrying MQTT connection in 5 seconds...");
mqtt.disconnect();
delay(5000);
retries--;
if (retries == 0) {
while (1);
}
}
Serial.println("MQTT Connected!");
}

Summary

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store