Le DHT22 s'arrete inopinément (demande d'aide)

Bonjour à tous,
J'espère que vous allez bien en ces temps de confinement.
Quelle meilleur période pour se mettre a faire des choses que l'on a jamais fait. De mon coté je me met a l'arduino et surtout a l'IOT.
Profiter de ce temps de confinement pour faire une petit serre d'intérieur afin de faire germer tout les plans qui viendront ensuite au jardin.

Dans un premier temps je cherche a faire simplement du monitoring, pour lire les conditions de la serre. Je passerai un de ces jours si tout se passe bien a un contrôleur avec relai et tout pour contrôler la serre.

L'idée est a priori simple, Je contrôle deux capteur un DHT22 pour la température et l'hygrométrie et un SEN0193 pour l'humidité du sol. Le tout est traité par un ESP32 puis envoyé en wifi Sur le site thingspeak.
Ce qui me permet de pouvoir lire soit sur mon navigateur soit sur smartphone les résultats.

Pour réaliser ce montage j'ai utilisé ce code.

#include "DHT22.h"
#include "SEN0193.h"
#include "MAX44009.h"
#include <WiFi.h>
#include <HTTPClient.h>

// WIFI SETTINGS
#define WIFI_SSID "XXXXXX"
#define WIFI_KEY "XXXXXXX"

// THINGSPEAK SETTINGS
#define THINGSPEAK_HOST "api.thingspeak.com"
#define THINGSPEAK_API_KEY "XXXXXXXXXX"

#define FIELD_TEMPERATURE 1
#define FIELD_HUMIDITY 2
#define FIELD_MOISTURE 3
#define FIELD_LIGHT 4

// PIN SETTINGS
#define PIN_SCL T1
#define PIN_SDA T2
#define PIN_DHT 15
#define PIN_SEN0193 33

// PROGRAM SETTINGS
#define TIME_SLEEP 1000
#define CPT_PUBLISH 30

// VAR DECLARATION
HTTPClient http;

DHT dht(PIN_DHT, DHT22);
SEN0193 sen(PIN_SEN0193);
Max44009 max44(0x4A, PIN_SDA, PIN_SCL);

uint16_t cptLoop = 0;

float temperature = 0;
float humidity = 0;
float moisture = 0;
float light = 0;

uint16_t cptTemperature = 0;
uint16_t cptHumidity = 0;
uint16_t cptMoisture = 0;
uint16_t cptLight = 0;

// Fonction exécutée au démarrage du système
void setup()
{
  // Initialisation de la sortie Serial pour nous permettre de monitorer notre système
  Serial.begin(9600);
  Serial.println("\nSetup");
  delay(50);

  // Initialisation du WIFI
  WiFi.begin(WIFI_SSID, WIFI_KEY);

  Serial.printf("Connecting to %s with key %s\n", WIFI_SSID, WIFI_KEY);
  
  uint32_t timer = millis();
  while (WiFi.status() != WL_CONNECTED)
  {
    Serial.print(".");
    delay(200);

    // Si il n'arrive pas à se connecter au bout de 20 secondes, le système redémarre (au cas ou un bug serait survenu)
    if (millis() - timer >= 20000)
    {
      Serial.println("Unable to connect, restarting...");
      ESP.restart();
    }
  }
 
  Serial.println(" WiFi connected");

  // Initialisation pour le DHT22 et le YL100
  dht.begin();
  sen.begin();
}

// Fonction exécutéee en boucle une fois la fonction setup() terminée
void loop()
{
  // Incrémentation de 1 du compteur de boucle
  cptLoop++;
  
  // Lecture des capteurs
  float _temperature = dht.readTemperature();
  if (_temperature >= -40 && _temperature <= 80)
  {
    temperature += _temperature;
    cptTemperature++;
  }

  float _humidity = dht.readHumidity();
  if (_humidity >= 0 && _humidity <= 200)
  {
    humidity += _humidity;
    cptHumidity++;
  }

  float _moisture = sen.readSoilMoisture();
  if (_moisture >= 0 && _moisture <= 200)
  {
    moisture += _moisture;
    cptMoisture++;
  }

  float _light = max44.getLux();
  if (_light >= 0 && _light <= 1000000)
  {
    light += _light;
    cptLight++;
  }

  // Si le compteur de boucle arrive à CPT_PUBLISH
  if (cptLoop >= CPT_PUBLISH)
  {
    temperature = temperature / cptTemperature;
    humidity = humidity / cptHumidity;
    moisture = moisture / cptMoisture;
    light = light / cptLight;
    
    // Affichage à l'écran des valeurs lues
    Serial.println("======");
    Serial.printf("Temperature : %s C°\n", String(temperature).c_str());
    Serial.printf("Humidity : %s %%\n", String(humidity).c_str());
    Serial.printf("Moisture : %s %%\n", String(moisture).c_str());
    Serial.printf("Light : %s lux\n", String(light).c_str());

    // Si nous ne sommes plus connectés au WiFi
    if (WiFi.status() != WL_CONNECTED)
    {
      Serial.println("Connection to the SSID lost, trying to reconnect...");
      
      uint32_t timer = millis();
      while (WiFi.status() != WL_CONNECTED)
      {
        Serial.print(".");
        delay(200);
    
        if (millis() - timer >= 20000)
        {
          Serial.println(" Unable to connect, restarting...");
          ESP.restart();
        }
      }
    }

    // Création de l'URL
    String url;
    url.reserve(256);
    url = "http://"+ String(THINGSPEAK_HOST) +"/update?api_key="+ String(THINGSPEAK_API_KEY);

    // Ici on intègre les champs et leurs valeurs.
    if (cptTemperature > 0)
      url += "&field"+ String(FIELD_TEMPERATURE) +"="+ temperature;
    else
      Serial.println("Unable to read temperature");

    if (cptHumidity > 0)
      url += "&field"+ String(FIELD_HUMIDITY) +"="+ humidity;
    else
      Serial.println("Unable to read humidity");

    if (cptMoisture > 0)
      url += "&field"+ String(FIELD_MOISTURE) +"="+ moisture;
    else
      Serial.println("Unable to read soil moisture");

    if (cptLight > 0)
      url += "&field"+ String(FIELD_LIGHT) +"="+ light;
    else
      Serial.println("Unable to read lux");
        
    Serial.printf("Fetching %s\n", url.c_str());      

    // Etablissement de la communication HTTP
    http.begin(url);
    int httpCode = http.GET();

    // Si nous n'avons pas réussi à émettre les données, nous redémarrons le système (au cas ou un bug serait survenu)
    if(httpCode != HTTP_CODE_OK)
    {
      Serial.printf("[HTTP] GET... failed, code: %d, error: %s\n", httpCode, http.errorToString(httpCode).c_str());
      ESP.restart();
    }
  
    Serial.println("Data sent !");
  
    http.end();

    // Remise à zéro
    cptLoop = 0;
    
    temperature = 0;
    humidity = 0;
    moisture = 0;
    light = 0;

    cptTemperature = 0;
    cptHumidity = 0;
    cptMoisture = 0;
    cptLight = 0;
  }

  // Temps en millisecondes où le programme ne fait rien
  delay(TIME_SLEEP);
}

trouvé smartgrow
le DHT22.h et le DHT.cpp

Après nombre de déboires j'ai fini par réussir.
Seulement voilà au bout d'un certain temps Le DHT22 n'envoie plus d'informations.
Même si le deuxième capteur lui continue a me donner l'humidité du sol.
Voyez vous quelque chose qui clocherais dans le code?
De mon coté pour ne comprennant pas.

  • J'ai refait toutes les soudures du montage
  • Changer plusieurs fois d'alimentations.
  • Essayé de passer par blynk
  • Essayé de mettre un ESP.restart() si la arte ne reçoit plus d'info du DHT22

J'ai pensé

  • Mettre un programme qui ferait redémarrer la carte régulièrement .
  • Utiliser un Watchdog
  • Que peut être je n'était pas branché au bon PIN (ESP32 étant un peu particulier)

Malheureusement je n'y arrive pas... Je ne comprends pas Voyez vous quelque chose d'évident?quelqu'un aurait une idée? de ce que je devrait faire et comment faire?
Merci et bises de coudes

Il est toujours bien d'indiquer quelle librairie on utilise.
DHT22.h cela ne dit pas grand chose.

J'ai 3 DTH22 reliés à une carte Uno. De temps en temps l'un d'entre eux se mettait en erreur, ou ne répondait pas, enfin il était planté.

J'ai fini par alimenter ces capteurs, non pas par le broche +5 de la carte, mais par une sortie GPIO que je peux contrôler.

Ainsi, lorsque l'un des capteurs dcnne, même pas peur : je coupe l'alim (disons 500ms), je rétablis l'alim, j'attends 2 secondes et je relance les lectures.

Le plus souvent ça marche, rarement ça ne change rien : là seulement je remonte une erreur.

Oui pardon, merci j'étais en train de lire les bons usage du forum en cherchant ce que j'aurais pu oublié. En effet. les bibliothèques se trouve dans le lien vers le GITHUB J'avais peur d'alourdir le message mais vous avez raison je vais les poster ici aussi.
Merci

Voici la bibliothèque pour le DHT22.h

/* DHT library

MIT license
written by Adafruit Industries
*/
#ifndef DHT_H
#define DHT_H

#if ARDUINO >= 100
 #include "Arduino.h"
#else
 #include "WProgram.h"
#endif


// Uncomment to enable printing out nice debug messages.
//#define DHT_DEBUG

// Define where debug output will be printed.
#define DEBUG_PRINTER Serial

// Setup debug printing macros.
#ifdef DHT_DEBUG
  #define DEBUG_PRINT(...) { DEBUG_PRINTER.print(__VA_ARGS__); }
  #define DEBUG_PRINTLN(...) { DEBUG_PRINTER.println(__VA_ARGS__); }
#else
  #define DEBUG_PRINT(...) {}
  #define DEBUG_PRINTLN(...) {}
#endif

// Define types of sensors.
#define DHT11 11
#define DHT22 22
#define DHT21 21
#define AM2301 21


class DHT {
  public:
   DHT(uint8_t pin, uint8_t type, uint8_t count=6);
   void begin(void);
   float readTemperature(bool S=false, bool force=false);
   float convertCtoF(float);
   float convertFtoC(float);
   float computeHeatIndex(float temperature, float percentHumidity, bool isFahrenheit=true);
   float readHumidity(bool force=false);
   boolean read(bool force=false);

 private:
  uint8_t data[5];
  uint8_t _pin, _type;
  #ifdef __AVR
    // Use direct GPIO access on an 8-bit AVR so keep track of the port and bitmask
    // for the digital pin connected to the DHT.  Other platforms will use digitalRead.
    uint8_t _bit, _port;
  #endif
  uint32_t _lastreadtime, _maxcycles;
  bool _lastresult;

  uint32_t expectPulse(bool level);

};

class InterruptLock {
  public:
   InterruptLock() {
    noInterrupts();
   }
   ~InterruptLock() {
    interrupts();
   }

};

#endif

biggil:
J'ai 3 DTH22 reliés à une carte Uno. De temps en temps l'un d'entre eux se mettait en erreur, ou ne répondait pas, enfin il était planté.

J'ai fini par alimenter ces capteurs, non pas par le broche +5 de la carte, mais par une sortie GPIO que je peux contrôler.

Ainsi, lorsque l'un des capteurs dcnne, même pas peur : je coupe l'alim (disons 500ms), je rétablis l'alim, j'attends 2 secondes et je relance les lectures.

Le plus souvent ça marche, rarement ça ne change rien : là seulement je remonte une erreur.

Ha ok c'est malin, je pense comprendre, au fait ça me fait pensé que je l'ai alimenté sur le le 3.3v de l'ESP32 au lieu comme vous du 5V

est ce que ça peut être ça?

faut regarder les spécs du capteur.

OK j'ai regardé les specs (data sheet) et on peut l'alimenter en 3,3 ou 5V.
Sur quel GPIO devrais je brancher l'alimentation à votre avis. (pin analogue ou digital?)
sachant que l'ESP32 est un peu particulier je vous laisse un Schéma.

Quel serait le bout de code pour couper et remettre en route la connexion?
Merci

Quelques remarques :

  1. Fichier du premier message : J'espère que le SSID et le mot de passe sont faux parce que sinon tu les a communiqué au monde entier. Idem pour THINGSPEAK_API_KEY.
    Si ce sont les vrais tu peux les changer vite fait.

  2. Une bibliothèques ne se limite par à un fichier *.h, c'est même le fichier le moins important. Le fichier le plus important est le fichier c ou cpp : c'est dans ce fichier que se trouve le code.
    Le fichier h contient seulement les définitions à destination du compilateur.
    Pour indiquer la bibliothèque utilisée le plus simple est de faire un lien cliquable (icône avec une chaîne) vers le dépôt de la bibliothèque.

  3. Le DHT22 incorpore un petit microcontrôleur, il est possible que se dernier se bloque. La méthode de couper l'alim un bref instant afin de provoquer un reset du microcontroleur est parfaitement logique.

En effet. les bibliothèques se trouve dans le lien vers le GITHUB

On a déjà un indice : Adafruit

Je pense qu'il doit s'agir de l'ancienne librairie, que je ne retrouve plus.

Depuis ils ont sorti celle-ci : GitHub - adafruit/DHT-sensor-library: Arduino library for DHT11, DHT22, etc Temperature & Humidity Sensors

Installable depuis l'IDE.

68tjs:
Quelques remarques :

  1. Fichier du premier message : J'espère que le SSID et le mot de passe sont faux parce que sinon tu les a communiqué au monde entier. Idem pour THINGSPEAK_API_KEY.
    Si ce sont les vrais tu peux les changer vite fait.

Oups la boulette! Merci voilà c'est corrigé

68tjs:
2) Une bibliothèques ne se limite par à un fichier *.h, c'est même le fichier le moins important. Le fichier le plus important est le fichier c ou cpp : c'est dans ce fichier que se trouve le code.
Le fichier h contient seulement les définitions à destination du compilateur.
Pour indiquer la bibliothèque utilisée le plus simple est de faire un lien cliquable (icône avec une chaîne) vers le dépôt de la bibliothèque.

OK merci pour ces infos et bonnes pratiques

68tjs:
3) Le DHT22 incorpore un petit microcontrôleur, il est possible que se dernier se bloque.

Le petit morceau de pcb sur lequel il est soudé? J'ai essayé aussi avec un capteur sans ce microcontroleur, même résultat.

68tjs:
La méthode de couper l'alim un bref instant afin de provoquer un reset du microcontroleur est parfaitement logique.

OK du coup je doit faire comme le propose @biggil c à d connecter l'alimentation du capteur sur un GPIO? comment faire se couper la carte un bref instant. Avec ESPrestart() ?
Merci

Merci @hbachetti je vais essayer de mettre a jour la bibliothèque

Donc si j'ai bien compris. Pour résumer je rajoute

Serial.println("Redémarre dans une heure");
  delay(3600000);
  ESP.restart();

Dans void loop() {}
Et hop il redémarre toute les heures?
C'est Ça, j'ai bon?

Merci

ben tu peux surtout ne redémarrer que ton capteur si tu n'a plus de mesure valable, plutot. Dans ce cas tu passe la pin GPIO utilisée pour l'alimentation du capteur à LOW pendant quelques secondes avant de la remettre à HIGH pour réalimenter le capteur

Ben oui en effet c'est ce que j'aimerais faire! mais je n'ai trouvé que ça comme code...
J'en suis là dans mon niveau de connaissance, a trouver du code :frowning:

digitalWrite(pin, LOW); et l'inverse avec HIGH après un délai... pas trop dur à trouver comme code normalement

Quote from: 68tjs on Today at 02:01 pm

  1. Le DHT22 incorpore un petit microcontrôleur, il est possible que se dernier se bloque.

Le petit morceau de pcb sur lequel il est soudé? J'ai essayé aussi avec un capteur sans ce microcontroleur, même résultat.

Quel morceau de circuit imprimé ?
Si tu appelle un microcontrôleur le circuit imprimé sur lequel est quelquefois soudé le DHT22 on est mal partis.
Je t'ai parlé du DHT22 : dans le boîtier blanc il y a une thermistance, un capteur d'humidité et un microcontrôleur.
Il faut bien convertir les informations analogiques que donnent la thermistance et le capteur d'humidité en communication numérique. Cela ne se fait pas par enchantement.
Un lien vers une expertise du DHT22 (dont le vrai nom est AM2302)
Tu peux voir les nombreux composants à l'intérieur du boîtier.
Plus de photos : Protocol decoder:am230x - sigrok

NON je je posais la question. C'est pour cela que j'avais mis un point d'exclamation à la fin de ma question. :slight_smile:
très interessant tes photos d'AM2302 décortiqués, en effet ça ressemble a un microcontroleur à l'intérieur. Et donc a quoi sert la petite (je sais plus comment l'appeler) sur lequel on trouve l'AM2302 soudé?

bricofoy:
digitalWrite(pin, LOW); et l'inverse avec HIGH après un délai... pas trop dur à trouver comme code normalement

Merci je sais pas vraiment ce qui est normal.

Tu veux parler du bout de circuit imprimé sur lequel on trouve parfois des DHT22 => a rien :grin: .

C'est juste pour les personnes qui ne savent pas se servir d'un fer à souder et d'une plaquette pastillée.
La connectique et les fils Dupont sont bien pratiques pour faire la mise au point (les breadboards aussi) mais dans une installation définitive il faut soit des liaisons vissées soit des liaisons soudées. Sinon avec les vibrations les fils finiront par faire ce qu'ils veulent.

digitalWrite(pin, LOW); et l'inverse avec HIGH après un délai... pas trop dur à trouver comme code normalement

Merci je sais pas vraiment ce qui est normal.

Une bonne lecture des tuto d'Eskimon me semble urgente.
Plus tu partira avec de bonnes bases moins tu aura de problèmes basiques comme celui ci

Pour le circuit imprimé c'est bien ce que je me disais c'est pour les personnes qui ne savent pas souder.
j'ai d'ailleurs tester dans mon cas ça marche aussi bien/mal.
J'ai donc essayé de faire se déconnecter puis reconnecter le capteur. Mais malheureusement ça ne fonctionne pas.
Peut être que je devrais essayer de faire un reset global a intervalle régulier. Mon problème est toujours le même, je ne comprend toujours pas quel est la commande.
Pourriez vous m'aider
Merci