ESP8266 + DHT22 + M...
 
Notifications
Retirer tout

ESP8266 + DHT22 + MQTT : fabriquer un objet connecté et l'inclure dans Home Assistant


fe36ca0d4d6bdcc500dbd432c3c08731?s=80&d=mm&r=g
Posts: 509
Admin
Début du sujet
(@christophe)
Membre
Inscription: Il y a 6 ans
wpf-cross-image

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

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.

 

 

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 :

  • wifi_ssid remplacer VOTRE_SSID par l'identifiant du réseau Wi-Fi sur lequel l'ESP8266 doit se connecter
  • wifi_password remplacer MOT_DE_PASSE_WIFI par le mot de passe du réseau Wi-Fi
  • mqtt_server 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é.

home assistant mqtt sensor esp8266

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 }}'

esp8266 wemos d1 mini home assistant switch interrupteur mqtt  

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.

 

 

IOT object connecté domotique home-assistant ESP8266+DHT22+MQTT wemos d1 mini

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

 

Répondre
4 Réponses
cd6c3d62f9f2c4bce84542d55c497899?s=80&d=mm&r=g
Posts: 4
 visvic
Anonyme
(@visvic)
Inscription: Il y a 5 ans

Bonjour 🙂

Super tuto !! comme dis par email les tutos sont géniaux !

Bon, je me heurte à un petit problème :s. J'ai repris la même base de votre projet et adapté un capteur DS18B20. Je récupère la température, je la convertis pour en faire une chaine et ensuite je publie sur test.mosquitto.fr. SAUF que très souvent les messages ne sont pas publiés. On regarde d'un peu plus près la doc de l'API ( http://pubsubclient.knolleary.net/api.html#publish1) et la le message est soit trop long soit la connection est perdu. Pourtant il y a bien une vérif qui est faite en amont pour la connection wifi ET mqtt.

Voici mon code:

#include
#include
#include

#define wifi_ssid "NUMERICABLE-A9BE"
#define wifi_password "**********"
#define mqtt_server "test.mosquitto.org"

long lastMsg = 0;
float DS18B20_temperature;

WiFiClient espClient;
PubSubClient client(espClient);
OneWire ds(2);

void setup() {
Serial.begin(115200);
setup_wifi();
client.setServer(mqtt_server, 1883);
}

/* --------------- loop ----------------------------------- */
void loop() {
long now = millis();
if (now - lastMsg > 1000 * 10) {
lastMsg = now;

if (WiFi.status() != WL_CONNECTED) {setup_wifi();}
if (!client.connected()) {reconnect();}
client.loop();

char message_temperature[10] = "";
DS18B20_temperature = getTemperatureDS18b20();
dtostrf(DS18B20_temperature, 3, 2, message_temperature);
if (client.publish("victor", message_temperature, true)){
Serial.println("message publie");
} else {
Serial.println("Message non publie");
}
Serial.println(message_temperature);
}
}

/* --------------- Connexion au réseau WIFI ----------------------------------- */
void setup_wifi() {
delay(10);
Serial.println();
Serial.print("Connection a ");
Serial.print(wifi_ssid);

WiFi.begin(wifi_ssid, wifi_password);

while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.print(" .");
}

Serial.println("");
Serial.println("WiFi connecte, ");
Serial.print("adresse IP : ");
Serial.println(WiFi.localIP());
}

/* --------------- Connexion au serveur MQTT ----------------------------------- */
void reconnect() {
while (!client.connected()) {
Serial.print("Connexion au serveur MQTT...");
if (client.connect("ESP8266Client")) {
Serial.println("OK");
} else {
Serial.println("KO, erreur : ");
Serial.print(client.state());
if (client.state() == -2) {
if (WiFi.status() != WL_CONNECTED) {setup_wifi();}
}
Serial.println("On attend 5 secondes avant de recommencer");
delay(5000);
}
}
}

/* --------------- Acquisition de la température ----------------------------------- */
float getTemperatureDS18b20() {
byte i;
byte data[12];
byte addr[8];
float temp = 0.0;

ds.search(addr);

// Cette fonction sert à surveiller si la transmission s'est bien passée
if (OneWire::crc8( addr, 7) != addr[7]) {
Serial.println("CRC is not valid!");
return false;
}

// Demander au capteur de mesure et mémoriser la température
ds.reset();
ds.select(addr);
ds.write(0x44);

delay(800);

// Demander au capteur de nous envoyer la température mémorisé
ds.reset();
ds.select(addr);
ds.write(0xBE);

// Le MOT reçu du capteur fait 9 octets, on les charge donc un par un dans le tableau data[]
for ( i = 0; i < 9; i++) {
data[i] = ds.read();
}

// Puis on converti la température (*0.0625 car la température est stockée sur 12 bits)
temp = ( (data[1] << 8) + data[0] ) * 0.0625;

// Réinitialisation de la recherche (évite erreur CRC !!)
ds.reset_search();
return temp;
}

et voici le moniteur série (extrait):

Connexion au serveur MQTT...OK
Message non publie
27.19
Connexion au serveur MQTT...OK
Connexion au serveur MQTT...OK
Message non publie
27.19
Connexion au serveur MQTT...OK
Message publie <=== HAA il s'envoie enfin :p
27.19
Connexion au serveur MQTT...OK
Message non publie
27.13
Connexion au serveur MQTT...OK
Message non publie
27.19
Connexion au serveur MQTT...OK
Message non publie
27.19

bref, j'espère ne pas avoir été trop bourrin en mettant tout cela ici, et si vous avez une petit idée je suis preneur 🙂

Merci d'avance =))
A très vite

Edit 23/08/2016, 18h09:
Il faut laisser client.loop() en dehors du if qui s'effectue toutes les dix secondes 😉

Répondre
1 Répondre
fe36ca0d4d6bdcc500dbd432c3c08731?s=80&d=mm&r=g
Admin
(@christophe)
Inscription: Il y a 6 ans

Membre
Posts: 509

Bonjour visvic. Tout d'abord merci beaucoup pour votre message. Avez-vous essayé d'installer un serveur (+ client) mosquitto sur un ordi local. J'imagine que le serveur qui fait tourner test.mosquitto.org doit être très sollicité et qu'il n'y a aucune garantie sur son bon fonctionnement (du moins en permanence). Ca vaudrait le coup d'essayer en local avant de remettre en cause le programme. Tenez moi au courant. A très bientôt.

Répondre
1bdb03cc9d2d1169ee518c56ee627af2?s=80&d=mm&r=g
Posts: 2
 Ferhat MAMECHE
Anonyme
(@Ferhat MAMECHE)
Inscription: Il y a 5 ans

Bonjour, je n'ai pas encore acheté le Raspberry Pi 3 mais j'ai tout de même essayé d'installer homeassistant, ce que je remarque par rapport aux vidéos tuto c'est que je n'ai pas forcément les mêmes options et notamment "straming update" est-ce normal? sinon comment installer homeassistant concrètement, étape par étape

Répondre
1 Répondre
2ef56dc296e30d22301058353a8b8600?s=80&d=mm&r=g
 Projets DIY
Anonyme
(@Projets DIY)
Inscription: Il y a 6 ans

Posts: 80

Bonjour Ferhat. Home Assistant est un projet qui bouge beaucoup et rapidement. Pas facile pour moi de connaitre tous les paramètres de tous les logiciels domotiques. Pour installer sur Raspberry, il y a ce tutoriel http://www.projetsdiy.fr/home-assistant-serveur-domotique-raspberry-pi/, sinon on peut aussi tester sur Windows, Linux, macOS, NAS avec Docker ( http://www.projetsdiy.fr/tester-logiciels-domotique-docker-jeedom-openhab-domoticz-ha/). A très bientôt.

Répondre
Share:
Rejoignez nous!
Chercher sur le forum
Derniers tutoriels
Derniers messages postés sur le forum
Domotique et objets connectés à faire soi-même
Domotique et objets connectés à faire soi-même
Vous avez aimé ce tutoriel

Ne manquez plus les prochains projets

Recevez chaque semaine le récapitulatif des tutoriels et projets.

Vous pouvez vous désabonner à tout moment.