Station météo wifi – Partie 2

Après un premier essai de capteurs météo avec retransmission sans fil vers le web (Adafruit IO), voici un second projet dont l’objectif est de permettre le stockage en local des données. Trois avantages : vous êtes maître de vos données, pas de coût de stockage en ligne, et pas d’envoi en ligne en continu.

Passons à la description du projet…

Matériel utilisé

Carte NodeMCU ESP8266-12E

La carte utilisée (dénommée NodeMCU) s’appuie sur un module ESP-12E qui intègre un microcontrôleur ESP8266. L’ESP8266 est un circuit intégré à microcontrôleur avec connexion Wi-Fi développé par le fabricant chinois Espressif.

Cette carte regroupe donc :

  • un microcontrôleur ESP8266 notamment programmable avec l’IDE ARDUINO,
  • un module WIFI pour communiquer avec le vaste mnde,
  • une liaison série,
  • des entrées/sorties.

Capteur de température et d’hygrométrie DHT22

Ce capteur est utilisé pour capter température et hygrométrie à l’intérieur.

Capteur de température, humidité et pression atmosphérique bme280

Ce capteur est utilisé pour capter les données extérieures. Il est installé dans une petite capsule plastique. Il ne faut pas que la boîte soit étanche afin que le capteur puisse mesurer correctement la pression atmosphérique :

Le reste de l’électronique (carte ESP8266 + capteur DHT22) est positionné à l’intérieur :

Raspberry Pi 4

Ce mini-ordinateur (la framboise en français) va permettre de gérer le serveur de données (stockage, visualisation).

Programmation du ESP8266 sous ARDUINO

Le programme ci-dessous permet de :

  • récupérer les données des différents capteurs :
    • DHT22 (température, humidité) en direct sur une entrée de la carte NodeMCU
    • BME280 (pression, température, humidité) via un bus I2C géré par la carte NodeMCU
  • transmettre les données en wifi vers le serveur hébergé sur le Raspberry.

Les données sont transmises en utilisant le protocole MQTT (Message Queuing Telemetry Transport).

// ZapGillouMTO
// v2.0 - 05/2020
//
// DHT22  : capteur température et humidité
// BME280 : capteur température, humidité, et pression atmosphérique

// Bibliothèques
#include <Adafruit_Sensor.h>
#include <DHT.h>                // gestion DHT22
#include <DHT_U.h>              // gestion DHT22
#include <Adafruit_BME280.h>    // gestion BME280
#include <Wire.h>               // gestion bus I2C
#include "EspMQTTClient.h"      // gestion MQTT - Transfert de données

// MQTT/WIFI Config
EspMQTTClient client(
  "XXXXX",     // WIFI - Nom du réseau WIFI
  "XXXXX",     // WIFI - Mot de passe du réseau WIFI
  "XXXXX",     // MQTT - Serveur IP - Adresse Raspberry (192.168.1.XX)
  "XXXXX",     // MQTT - Login
  "XXXXX",     // MQTT - Psw
  "XXXXX",     // MQTT - Identifiant
  1883         // MQTT - port
  );

#define DHTPIN 14                   // Correspond à D5 sur la carte NodeMCU
#define DHTTYPE DHT22               // DHT 22 (AM2302)

DHT_Unified dht(DHTPIN, DHTTYPE);   // Variable capteur DHT22
Adafruit_BME280 bme;                // Variable capteur bmpe280

// Déclaration des variables globales utilisées pour l'aquisition des données
float ValeurTempin;
float ValeurTempout;
float ValeurHygroin;
float ValeurHygroout;
float ValeurPressout;

void setup()
  {
  
  // A des fins de test, transmission des infos sur la liaison série
  // Toute cette transmission peut être supprimée si non utilisée

  // Ouverture liaison série
  Serial.begin(115200);
  Serial.println("");
  Serial.println("_Station Meteo ZapGillou");
 
  // Initialisation liaison I2C
  Wire.begin(0, 2);   // Correspond aux broches D3/D4 sur la carte
 
  if (!bme.begin(0x76)) {
    Serial.println("_Capteur BME280 : NOK");
    while (1);
  }
  else
    {
    Serial.println("_Capteur BME280 : OK");
    }

  dht.begin();
  sensor_t sensor;
  dht.temperature().getSensor(&sensor);
  Serial.println("_Capteur DHT22");
  Serial.println("_ 1.DHT22 : Capteur temperature");
  Serial.print  ("_ 1.Type       : "); Serial.println(sensor.name);
  Serial.print  ("_ 1.Version    : "); Serial.println(sensor.version);
  Serial.print  ("_ 1.ID         : "); Serial.println(sensor.sensor_id);
  Serial.print  ("_ 1.Valeur min : "); Serial.print(sensor.min_value); Serial.println(F("°C"));
  Serial.print  ("_ 1.Valeur max : "); Serial.print(sensor.max_value); Serial.println(F("°C"));
  Serial.print  ("_ 1.Precision  : "); Serial.print(sensor.resolution); Serial.println(F("°C"));
  // Print humidity sensor details.
  dht.humidity().getSensor(&sensor);
  Serial.println("_ 2.DHT22 : Capteur humidite");
  Serial.print  ("_ 2.Type       : "); Serial.println(sensor.name);
  Serial.print  ("_ 2.Version    : "); Serial.println(sensor.version);
  Serial.print  ("_ 2.ID         : "); Serial.println(sensor.sensor_id);
  Serial.print  ("_ 2.Valeur min : "); Serial.print(sensor.min_value); Serial.println(F("%"));
  Serial.print  ("_ 2.Valeur max : "); Serial.print(sensor.max_value); Serial.println(F("%"));
  Serial.print  ("_ 2.Precision  : "); Serial.print(sensor.resolution); Serial.println(F("%"));
  }

void onConnectionEstablished()
{
  // Envoi MQTT des données sur les différents flux (pressout, tempout, hygroout, tempin, hygroin)
  client.publish("pressout", String(ValeurPressout));
  client.publish("tempout", String(ValeurTempout));
  client.publish("hygroout", String(ValeurHygroout));
  client.publish("tempin", String(ValeurTempin));
  client.publish("hygroin", String(ValeurHygroin));
}

void loop()
  {
 
  ValeurPressout = bme.readPressure() / 100.0F;
  Serial.print("_BME280 - Pression (hPA)  = ");     Serial.println(ValeurPressout);
 
  ValeurTempout = bme.readTemperature();
  Serial.print("_BME280 - Temperature (°C) = ");    Serial.println(ValeurTempout);
 
  ValeurHygroout = bme.readHumidity();
  Serial.print("_BME280 - Humidite (%) = ");        Serial.println(ValeurHygroout);
   
  sensors_event_t event;
  dht.temperature().getEvent(&event);
  ValeurTempin = event.temperature;
  Serial.print("_DHT22  - Temperature (°C) = ");    Serial.println(ValeurTempin);
     
  dht.humidity().getEvent(&event);
  ValeurHygroin = event.relative_humidity;
  Serial.print("_DHT22  - Humidite (%)     = ");    Serial.println(ValeurHygroin);
 
  client.loop();   // Publication MQTT
 
  // Tempo
  Serial.println("_Tempo");
  delay(60000);    // 1 acquisition par minute
  }

Et côté Raspberry

Ça a été le plus délicat car je découvrais tout de ce côté là…

On trouve donc sur le Raspberry :

  • Mosquitto : Gestion de l’interface MQTT sur le Raspberry en réceptionnant les flux arrivant de la carte NodeMCU.
  • InfluxDB : Système de gestion de base de données dédié au stockage de séries temporelles (time series), c’est à dire des données horodatées.
  • Node-RED : Permet de faire le lien entre Mosquitto et InfluxDB. Node-RED

Node-RED permet ici de récupérer chaque flux MQTT (ex: tempin) et de le renvoyer vers la base de données ZGMTO gérée par InfluxDB, dans la table nommée DATAMTO. Cette table contient l’ensemble des valeurs des capteurs, la fonction intermédiaire permet d’affecter l’étiquette ad hoc à chaque flux (ici tempin) :

Le bloc vert « msg.payload » permet simplement de visualiser les données dans l’onglet DEBUG de Node-RED :

  • Grafana : Visualisation des données sous une forme sympathique (graphes, valeurs instantanée, etc…).

1 commentaire pour “Station météo wifi – Partie 2”

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *