ESP8266 + DHT22 + MQTT, here’s how we will learn how to make our first connected object (a temperature probe) and connect it to the Home Assistant server. To realize this connected object we will need a WiFi module ESP8266, a DHT22 temperature and humidity sensor and an LED (to simulate the control of a lamp). For the home automation part, we will use the Home Assistant software.
Configuration required
You will need a computer with the following software installed:
- A Broker (server) MQTT. I recommend Mosquitto already presented in this article
- A home automation server. The easiest thing if you’re new to home automation and that English does not put you off too much, is to install Home-Assistant described in this article.
To make this article, I used a Raspberry Pi 3 with an active SSH connection (if you need to know more about SSH, read this article first).
Necessary material
To complete this project, you will need the following equipment
Circuit
The Wemos D1 mini is cable like a classic Arduino. When the Wemos D1 Mini is connected to the USB port of the computer, the power supply is recovered on the Pin + 5V. To operate the Wemos on battery LiPo or batteries it will suffice to connect to the Pin 5V and G.
In the program, the DHT22 is connected to the Pin D4, the Led on the Pin D2.
Code
The ESP8266 (ESP-12) can be programmed in Lua or using the Arduino IDE. Once again it’s about taste. I have a preference for IDE by habit but especially ESP8266Wifi and PubSub libraries really simplify the lives of developers.
To publish the measurements on the MQTT Mosquitto Broket, we will need to integrate the following 3 libraries into our Arduino project:
- ESP8266WiFi.h: this library and the ideal toolbox to connect (and reconnect) an ESP8266 to the internet, to a server …
- PubSubClient.h: This library allows you to send and receive MQTT messages and manage QoS
DHT.h: this library makes it possible to easily recover the measurements of the DHT11 or DHT22 sensor
Create a new project and paste the following code to fit your configuration.
/* Projet d'apprentissage d'un objet connecté (IoT) pour réaliser une sonde de température ESP8266 + DHT22 + LED + MQTT + Home-Assistant Projets DIY (http://www.projetsdiy.fr) - Mai 2016 Licence : MIT */ #include <ESP8266WiFi.h> #include <PubSubClient.h> #include "DHT.h" // Librairie des capteurs DHT #define wifi_ssid "yourSSID" #define wifi_password "yourPASSWORD" #define mqtt_server "ipMOSQUITTO" #define mqtt_user "guest" // if exist #define mqtt_password "guest" //idem #define temperature_topic "sensor/temperature" //Topic temperature #define humidity_topic "sensor/humidity" //Topic humidity //Buffer to decode MQTT messages char message_buff[100]; long lastMsg = 0; long lastRecu = 0; bool debug = false; //Display log message if True #define DHTPIN D4 // DHT Pin // Un-comment you sensor //#define DHTTYPE DHT11 // DHT 11 #define DHTTYPE DHT22 // DHT 22 (AM2302) // Create abjects DHT dht(DHTPIN, DHTTYPE); WiFiClient espClient; PubSubClient client(espClient); void setup() { Serial.begin(9600); pinMode(D2,OUTPUT); //Pin 2 for LED setup_wifi(); //Connect to Wifi network client.setServer(mqtt_server, 1883); // Configure MQTT connexion client.setCallback(callback); // callback function to execute when a MQTT message dht.begin(); } //Connexion au réseau WiFi void setup_wifi() { delay(10); Serial.println(); Serial.print("Connecting to "); Serial.println(wifi_ssid); WiFi.begin(wifi_ssid, wifi_password); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println(""); Serial.println("WiFi OK "); Serial.print("=> ESP8266 IP address: "); Serial.print(WiFi.localIP()); } //Reconnexion void reconnect() { while (!client.connected()) { Serial.print("Connecting to MQTT broker ..."); if (client.connect("ESP8266Client", mqtt_user, mqtt_password)) { Serial.println("OK"); } else { Serial.print("KO, error : "); Serial.print(client.state()); Serial.println(" Wait 5 secondes before to retry"); delay(5000); } } } void loop() { if (!client.connected()) { reconnect(); } client.loop(); long now = millis(); // Send a message every minute if (now - lastMsg > 1000 * 60) { lastMsg = now; // Read humidity float h = dht.readHumidity(); // Read temperature in Celcius float t = dht.readTemperature(); // Oh, nothing to send if ( isnan(t) || isnan(h)) { Serial.println("KO, Please chez DHT sensor !"); return; } if ( debug ) { Serial.print("Temperature : "); Serial.print(t); Serial.print(" | Humidity : "); Serial.println(h); } client.publish(temperature_topic, String(t).c_str(), true); // Publish temperature on temperature_topic client.publish(humidity_topic, String(h).c_str(), true); // and humidity } if (now - lastRecu > 100 ) { lastRecu = now; client.subscribe("homeassistant/switch1"); } } // MQTT callback function // D'après http://m2mio.tumblr.com/post/30048662088/a-simple-example-arduino-mqtt-m2mio void callback(char* topic, byte* payload, unsigned int length) { int i = 0; if ( debug ) { Serial.println("Message recu => topic: " + String(topic)); Serial.print(" | longueur: " + String(length,DEC)); } // create character buffer with ending null terminator (string) for(i=0; i<length; i++) { message_buff[i] = payload[i]; } message_buff[i] = '\0'; String msgString = String(message_buff); if ( debug ) { Serial.println("Payload: " + msgString); } if ( msgString == "ON" ) { digitalWrite(D2,HIGH); } else { digitalWrite(D2,LOW); } }
If you discover the ESP8266 modules, read this article first to learn how to program and upload a program using the Arduino IDE.
Integration with a home automation server Home Assistant
If you do not know Home-Assistant, I invite you to read this article that explains how to install it and configure your box to access it from the internet.
The great thing about Home-Assistant is that there is only one script to edit to display the temperature and humidity published by the ESP8266 on Mosquitto. Go to the installation directory of Home-Assistant.io
cd ~ /.homeassistant
then open the configuration file
sudo nano configuration.yaml
We add a section mqtt
mqtt: broker: localhost #if broker installed on the same computer than Home-Assistant port: 1883 #by default client_id: home-assistant-1 keepalive: 60 username: USERNAME #optional password: PASSWORD #optional; protocol: 3.1 #by default
Now we add a new sensor (sensor) and we get the temperature on the topic sensor / temperature. The value is in the payload
sensor: platform: mqtt state_topic: "sensor/temperature" name: "Temperature" qos: 0 unit_of_measurement: "°C" #value_template: '{{ payload }}'
We do the same for humidity by adding a sensor 2
sensor 2: platform: mqtt state_topic: "sensor/humidity" name: "Humidity" qos: 0 unit_of_measurement: "°C" #value_template: '{{ payload }}'
Save the configuration (Ctrl + X then O) and launch the server with the hass command. Refresh the page in your browser to see the temperature and humidity measurement.
Turn on, turn off an LED from Home-Assistant
Now add a switch that will allow us to turn on or off an LED. This is a general example. We just activate an Arduino output. We could very simply replace the Led with a relay.
Stop Home-Assistant and reopen the configuration.yaml file where we will add a switch block
switch: platform: mqtt name: "Kitchen" command_topic: "homeassistant/switch1" #Topic sur lequel on publie l'état de l'interrupteur payload_on: "ON" # A vous de choisir le message envoyé lorsque l'interrupteur est allumé payload_off: "OFF" # et éteint optimistic: true # Mettez à true pour maintenir l'état qos: 0 retain: true value_template: '{{ value.x }}'
Restart Home-Assistant. You now have a new widget named “Switch” in which is located the kitchen switch. Press the lightning bolt to turn on the LED.
If you have configured your box to make the Home-Assistant server accessible from the internet, you can even switch the LED on and off from your smartphone.
- How to store data on a micro SD card. Arduino code compatible ESP32, ESP8266
- Getting started Arduino. Receive commands from the serial port (ESP32 ESP8266 compatible)
- C++ functions print•println•printf•sprintf for Arduino ESP32 ESP8266. Combine•format → serial port
- C++ String functions. concat•c_srt•indexOf•replace•subString… for Arduino, ESP32, ESP8266
- How to assign a fixed IP to an ESP32 ESP8266 or ESP01 project
- ESP01. Get started with the Arduino or PlatformIO IDE. Which module to choose? Pinout