Domotique et capteurs : Maîtriser le combo DHT11 et Télémètre Laser (VL53L1X) sur ESP32

Faire cohabiter plusieurs capteurs sur un même microcontrôleur ESP32 est un grand classique en domotique. Pourtant, dès que l’on associe des composants aux technologies différentes, la gestion des bus de communication et du timing de la boucle principale (loop) devient cruciale.

Cet article détaille la mise en œuvre de deux capteurs incontournables : le DHT11 (température et humidité) et le VL53L1X (télémètre laser à temps de vol). Voici comment les exploiter proprement, avec des faits techniques vérifiés.

Les forces en présence : protocoles et spécifications

Pour éviter les erreurs d’acquisition, il est nécessaire de comprendre comment ces deux capteurs communiquent avec l’ESP32. Ils utilisent des protocoles totalement distincts.

1. Le VL53L1X : La précision du Temps de Vol (ToF) via le bus I2C

Le VL53L1X de STMicroelectronics est un capteur de distance laser (technologie Flight-of-Time). Il émet des photons invisibles à 940 nm et calcule le temps qu’ils mettent à revenir après avoir frappé une cible.

  • Protocole : I2C (Inter-Integrated Circuit). Il utilise deux lignes : SDA (données) et SCL (horloge).
  • Adresse I2C native : 0x29 (7 bits).
  • Portée réelle : Jusqu’à 4 mètres en conditions optimales (obscurité), réduite en plein soleil à cause des infrarouges parasites.
  • Particularité : Il nécessite l’utilisation des broches matérielles I2C de l’ESP32 (généralement GPIO 21 pour SDA et GPIO 22 pour SCL par défaut sur une carte ESP32 standard).

2. Le DHT11 : Humidité relative et température via protocole propriétaire

Le DHT11 est un capteur composite qui intègre une résistance thermistance (CTN) pour la température et un composant résistif pour mesurer l’humidité.

  • Protocole : Protocole propriétaire Single-Wire (à ne pas confondre avec le protocole 1-Wire de Dallas/Maxim). Il utilise une seule ligne de données bidirectionnelle.
  • Timing strict : La communication repose sur des impulsions de microsecondes bien précises. L’ESP32 doit abaisser la ligne pendant au moins 18 millisecondes pour réveiller le capteur, puis attendre sa réponse.
  • Plage de mesure : 20 à 90% d’humidité relative (précision $\pm5\%$) et 0 à 50 °C (précision $\pm2$ °C).

Le piège technique : Le blocage de la boucle principale

La principale erreur lors de l’intégration de ce combo réside dans la gestion du temps. Le DHT11 est un capteur lent. Sa fréquence d’échantillonnage maximale est de 0,5 Hz, ce qui signifie qu’on ne peut pas l’interroger plus d’une fois toutes les 2 secondes.

Si le code utilise la fonction basique delay(2000) pour attendre entre chaque lecture du DHT11, la boucle de l’ESP32 est totalement gelée pendant ce temps. Conséquence : le télémètre laser VL53L1X, qui peut pourtant rafraîchir ses mesures de distance jusqu’à 50 fois par seconde (50 Hz), devient inutile car il est bloqué par l’attente du DHT11.

La solution : Le multitâche non bloquant (Asynchronisme)

Pour obtenir des mesures de distance fluides tout en interrogeant le DHT11 au bon rythme, il faut utiliser la fonction millis() de l’environnement Arduino pour créer une structure non bloquante.

Voici l’exemple de code standardisé sous PlatformIO, utilisant la bibliothèque Adafruit DHT et la bibliothèque Pololu VL53L1X :

C++

#include <Arduino.h>
#include <Wire.h>
#include <DHT.h>
#include <VL53L1X.h>

// Configuration DHT11
#define DHTPIN 4
#define DHTTYPE DHT11
DHT dht(DHTPIN, DHTTYPE);

// Configuration VL53L1X
VL53L1X sensor;

// Variables de cadencement
unsigned long previousMillisDHT = 0;
const long intervalDHT = 2000; // 2 secondes d'intervalle requis pour le DHT11

void setup() {
    Serial.begin(115200);
    Wire.begin(); // Initialisation du bus I2C (GPIO 21 et 22 par défaut)
    
    dht.begin();
    
    sensor.setTimeout(500);
    if (!sensor.init()) {
        Serial.println("Échec du démarrage du capteur VL53L1X !");
        while (1);
    }
    // Mode de distance longue (jusqu'à 4m) et budget de synchronisation de 50ms
    sensor.setDistanceMode(VL53L1X::Long);
    sensor.setMeasurementTimingBudget(50000);
    sensor.startContinuous(50); // Mesure continue toutes les 50ms
}

void loop() {
    unsigned long currentMillis = millis();

    // 1. Lecture NON BLOQUANTE du DHT11 toutes les 2 secondes
    if (currentMillis - previousMillisDHT >= intervalDHT) {
        previousMillisDHT = currentMillis;

        float h = dht.readHumidity();
        float t = dht.readTemperature();

        if (!isnan(h) && !isnan(t)) {
            Serial.print(F("Humidité : "));
            Serial.print(h);
            Serial.print(F("%  |  Température : "));
            Serial.print(t);
            Serial.println(F("°C"));
        }
    }

    // 2. Lecture FLUIDE et continue du laser VL53L1X (toutes les 50ms)
    sensor.read();
    Serial.print(F("Distance : "));
    Serial.print(sensor.data.range_mm);
    Serial.println(F(" mm"));
}

En conclusion

Associer le protocole I2C et le protocole Single-Wire sur un microcontrôleur comme l’ESP32 ne pose aucun problème matériel, à condition de bannir définitivement la fonction delay(). En appliquant un cadencement basé sur le temps écoulé (millis()), l’ESP32 exécute les mesures de distance laser en temps réel tout en respectant l’inertie du capteur environnemental DHT11.

Laisser un commentaire

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