Dans ce tutoriel nous allons apprendre comment réaliser un petit objet connecté à l'aide d'un ESP8266. On collectera à intervalle régulier la température et l'humidité d'un capteur DHT22. Les données seront envoyées (publiées) vers un broker (serveur) MQTT en WiFi puis intégrées au serveur domotique Home Assistant.
Ce petit projet permet d'aborder de nombreuses notions utiles Pour réaliser cet objet connecté nous aurons besoin d'un module WiFi ESP8266, d'un capteur de température et d'humidité DHT22 et d'une Led (pour simuler la commande d'une lampe).
Configuration nécessaire avant de débuter
Vous aurez besoin d'un ordinateur avec les logiciels suivants installés :
- Un Broker (serveur) MQTT. Mosquitto est un choix simple et gratuit super facile à installer en quelques minutes
- Un serveur domotique. Pour de projet nous utiliserons Home Assistant mais vous pouvez également essayer avec Jeedom (logiciel français) ou Domoticz (en français également et très simple d'utilisation). Si vous ne connaissez pas Home-Assistant, je vous invite à lire cet article qui explique étape par étape comment l'installer et le configurer.
- Eventuellement une connexion SSH qui facilite la vie pour exécuter les commandes Linux?
Matériel nécessaire
Pour réaliser ce projet, vous aurez besoin du matériel suivant
LoLin WeMos D1 Mini (compact et économique) ou n'importe quel autre ESP8266 ESP-12 | |
Alimentation 5/3A micro-usb | |
Led (optionnelle) | |
Résistance 220Ω (optionnel) | |
DHT22 | |
Jumper Dupont (optionnel) | |
Breadboard (optionnel) |
Tous les shields compatibles avec la LoLin d1 Mini
Circuit
L'ESP8266 LoLin Wemos d1 mini se câble comme un Arduino classique. Pour faire fonctionner la Wemos sur batterie LiPo ou piles il suffira de brancher sur les Pin 5V et G.
Dans le programme, le DHT22 est branché sur le Pin D4, la Led (optionnelle) sur la broche D2.
Schéma de branchement du DHT22 et de la Led au module ESP8266 Wemos D1 Mini
Code
L'ESP8266 (ESP-12) permet d'exécuter du code C++ développé à l'aide de l'IDE Arduino comme n'importe quelle autre carte Arduino. Pour ce projet, nous allons utiliser trois librairies suivantes :
- ESP8266WiFi.h : cette librairie et la boîte à outil idéal pour connecter (et reconnecter) un ESP8266 au réseau local en Wi-Fi internet, à un serveur...
- PubSubClient.h : cette librairie permet d'envoyer et de recevoir des messages MQTT et de gérer le QoS.
- DHT.h : cette librairie permet de récupérer facilement les mesures du capteur DHT11 ou DHT22
Créez un nouveau projet et collez le code suivant en modifiant les variables suivantes :
- remplacer VOTRE_SSID par l'identifiant du réseau Wi-Fi sur lequel l'ESP8266 doit se connecter
- remplacer MOT_DE_PASSE_WIFI par le mot de passe du réseau Wi-Fi
- remplacer par l'adresse IP du broker MQTT
/*
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 "VOTRE_SSID"
#define wifi_password "MOT_DE_PASSE_WIFI"
#define mqtt_server "IP_MOSQUITTO"
#define mqtt_user "guest" //s'il a été configuré sur Mosquitto
#define mqtt_password "guest" //idem
#define temperature_topic "sensor/temperature" //Topic température
#define humidity_topic "sensor/humidity" //Topic humidité
//Buffer qui permet de décoder les messages MQTT reçus
char message_buff[100];
long lastMsg = 0; //Horodatage du dernier message publié sur MQTT
long lastRecu = 0;
bool debug = false; //Affiche sur la console si True
#define DHTPIN D4 // Pin sur lequel est branché le DHT
// Dé-commentez la ligne qui correspond à votre capteur
//#define DHTTYPE DHT11 // DHT 11
#define DHTTYPE DHT22 // DHT 22 (AM2302)
//Création des objets
DHT dht(DHTPIN, DHTTYPE);
WiFiClient espClient;
PubSubClient client(espClient);
void setup() {
Serial.begin(9600); //Facultatif pour le debug
pinMode(D2,OUTPUT); //Pin 2
setup_wifi(); //On se connecte au réseau wifi
client.setServer(mqtt_server, 1883); //Configuration de la connexion au serveur MQTT
client.setCallback(callback); //La fonction de callback qui est executée à chaque réception de message
dht.begin();
}
//Connexion au réseau WiFi
void setup_wifi() {
delay(10);
Serial.println();
Serial.print("Connexion a ");
Serial.println(wifi_ssid);
WiFi.begin(wifi_ssid, wifi_password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("Connexion WiFi etablie ");
Serial.print("=> Addresse IP : ");
Serial.print(WiFi.localIP());
}
//Reconnexion
void reconnect() {
//Boucle jusqu'à obtenur une reconnexion
while (!client.connected()) {
Serial.print("Connexion au serveur MQTT...");
if (client.connect("ESP8266Client", mqtt_user, mqtt_password)) {
Serial.println("OK");
} else {
Serial.print("KO, erreur : ");
Serial.print(client.state());
Serial.println(" On attend 5 secondes avant de recommencer");
delay(5000);
}
}
}
void loop() {
if (!client.connected()) {
reconnect();
}
client.loop();
long now = millis();
//Envoi d'un message par minute
if (now - lastMsg > 1000 * 60) {
lastMsg = now;
//Lecture de l'humidité ambiante
float h = dht.readHumidity();
// Lecture de la température en Celcius
float t = dht.readTemperature();
//Inutile d'aller plus loin si le capteur ne renvoi rien
if ( isnan(t) || isnan(h)) {
Serial.println("Echec de lecture ! Verifiez votre capteur DHT");
return;
}
if ( debug ) {
Serial.print("Temperature : ");
Serial.print(t);
Serial.print(" | Humidite : ");
Serial.println(h);
}
client.publish(temperature_topic, String(t).c_str(), true); //Publie la température sur le topic temperature_topic
client.publish(humidity_topic, String(h).c_str(), true); //Et l'humidité
}
if (now - lastRecu > 100 ) {
lastRecu = now;
client.subscribe("homeassistant/switch1");
}
}
// Déclenche les actions à la réception d'un message
// 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] = '';
String msgString = String(message_buff);
if ( debug ) {
Serial.println("Payload: " + msgString);
}
if ( msgString == "ON" ) {
digitalWrite(D2,HIGH);
} else {
digitalWrite(D2,LOW);
}
}
Si vous découvre les modules ESP8266, lisez d'abord cet article pour apprendre comment le programmer et téléverser un programme à l'aide de l'IDE Arduino.
Intégrer l'objet connecté ESP8266 au serveur domotique Home Assistant
Ce qui est génial avec Home-Assistant c'est qu'il n'y a qu'un script à modifier pour pouvoir afficher la température et l'humidité publiée par l'ESP8266 sur Mosquitto. Allez dans le répertoire d'installation d'Home-Assistant.io
cd ~/.homeassistant
puis ouvrez le fichier de configuration
sudo nano configuration.yaml
On ajoute une section mqtt
mqtt:
broker: localhost #si le Broker est installé sur le même poste qu'Home-Assistant
port: 1883 #par défaut
client_id: home-assistant-1
keepalive: 60
username: USERNAME #optionnel
password: PASSWORD #optionnel
protocol: 3.1 #par défaut
Maintenant on ajoute un nouveau capteur (sensor) et on récupère la température sur le topic sensor/temperature. La valeur se trouve dans le payload
sensor:
platform: mqtt
state_topic: "sensor/temperature"
name: "Température"
qos: 0
unit_of_measurement: "°C"
#value_template: '{{ payload }}'
On fait de même pour l'humidité en ajoutant un sensor 2
sensor 2:
platform: mqtt
state_topic: "sensor/humidity"
name: "Humidité"
qos: 0
unit_of_measurement: "°C"
#value_template: '{{ payload }}'
Enregistrez la configuration (Ctrl + X puis O) et lancez le serveur avec la commande hass. Actualisez la page dans votre navigateur pour voir apparaître la mesure de température et d'humidité.
Bonus : piloter (allumer, éteindre) une Led ou un relais depuis Home-Assistant
Ajoutons maintenant un interrupteur qui va nous permettre d'allumer ou d'éteindre un Led. C'est un exemple général. On active simplement une sortie de l'Arduino. On pourrait très simplement remplacer la Led par un relai.
Arrêtez Home-Assistant et ouvrez de nouveau le fichier de configuration.yaml dans lequel on va ajouter un bloc switch
switch:
platform: mqtt
name: "Cuisine"
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 }}'
Relancez Home-Assistant. Vous avez maintenant un nouveau widget nommé "Switch" dans lequel se trouve l'interrupteur de la cuisine. Appuyez sur l'éclair pour allumer la LED.
Si vous avez configuré votre box pour rendre accessible le serveur Home-Assistant depuis internet, vous pouvez même allumer et éteindre la led depuis votre smartphone.
J'espère que vous avez apprécié ce petit projet de découverte des modules ESP8266 intégrés à un serveur domotique.
Projets et tutoriels sur les objets connectés
Prêt à vous lancer dans d'autres projets, voici d'autres tutoriels qui devrait vous intéresser
- Stocker des données sur une carte micro SD. Code Arduino compatible ESP32, ESP8266
- Débuter Arduino. Recevoir des commandes depuis le port série (compatible ESP32 ESP8266)
- Fonctions C++ print•println•printf•sprintf pour Arduino ESP32 ESP8266. Combiner•formater → port série
- String C++. concat•c_srt•indexOf•replace•subString… pour Arduino ESP32 ESP8266
- ESP01. Débuter avec l’IDE Arduino ou PlatformIO. Quel module choisir ? Repérage des broches
- Comment attribuer une IP fixe à un projet ESP32 ESP8266 ou ESP01