Problème lecture température DHT22 dans un programme de couveuse

Bonjour!

Je poste ce sujet car je ne trouve pas la raison de mon problème!... Après avoir bien essayer... Longtemps!!! AHHHH!!!

Mon projet consiste en une petite couveuse automatique (je suis un peu tête en l'air!)
Dans cette couveuse, il y a un DHT22 pour surveiller la température et l'humidité, un chauffage (lampe + cordon chauffant) piloté par un gradateur, un ventilateur, un servo-moteur pour retourner les oeufs régulièrement, une petite pompe eau pour réinjecter de l'eau lorsque le bac a eau est vide et que l'humidité est trop faible et enfin un écran LCD pour contrôler le tout!

Mon problème est qu'au bout d'un certain temps, la lecture de la température de la sonde DHT22 me donne "nan"... Mon programme commence par une phase de chauffe (chauffe=0 dans le code). J'ai l'impression que c'est une fois que la phase de chauffe est passé que la lecture ne fonctionne plus (d'abord de manière aléatoire puis rapidement plus du tout).

Le problème ne vient pas de ma sonde car avec un programme ou je demande juste la lecture de la température, cela marche tout le temps...

Je vous joins mon code à la suite (trop long sinon ...), si quelqu'un peut y jeter un œil, ça serait génial!

Merci d'avance
Quentin

#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <Adafruit_Sensor.h>
#include <DHT.h>
#include <DHT_U.h>
#include <Servo.h>


#define DHTPIN            8         // Pin du capteur DHT22


// Variable Chauffage!
const int  pinChauffagePWM = 3; // Pin PWM
const int zcPin = 2; // Pin ZC
unsigned char PWMChauffe; // Variable de la fonction zero_cross créer pour faire varier la lumière
int Dividende = 100 ; // A choisir tel que : Dividende = (10000-10)/(Nombre de palier de variation)

// Variable Ventilation!
const int pinVentilation=6; //Pin branchement ventilo

// Variable Pompe a eau!
const int pinPompe=11; //Pin branchement pompe a eau 

// Declaration servomoteur
Servo myservo;//create servo object to control a servo

  // Pin servomoteur
  int servoPin=12;

// Déclaration des variables!
unsigned long int TempsPasse; // Recueil millis pour l'expoiter
unsigned long int NombreDeJour;  // Variable a afficher
unsigned long int ResteJour; // Variable pour determiner les heures
unsigned long int NombreHeure;  // Variable a afficher
unsigned long int TempsDepuisBascule;  // Variable pour le retournement
unsigned long int HeureDepuisBascule;  // Variable a afficher
unsigned long int ResteJourDepuisBascule;  // Variable pour determiner les minutes
unsigned long int MinuteDepuisBascule;  // Variable a afficher
unsigned long int TempsArrosage;  // Recueil millis pour savoir quand a été faite la dernière arrivee d'eau
unsigned long int DelaisArrosage;  // millis()-TempsArrosage
float  ValeurTemperature;  // Variable a afficher
float  ValeurHumidite;  // millis()-TempsArrosage


float ActTemp=0;  // Variable pour enregistrer la température actuelle
float LastTemp=0;  // Variable pour enregistrer la dernière température

int nbStagne = 0; // Nombre de fois ou la température reste la même
int nbCycle = 0; // Nombre de cycle de rotation

unsigned long int ValeurChauffage;  // Valeur PWM pour gradateur
int Chauffe = 0; // Cycle démarrage chauffage
int FindeCycle=0; // Pour l'humidité début =0, humidité>50, si fin =1 humidité>90


// Définition capteur
#define DHTTYPE           DHT22     // DHT 22 (AM2302)

DHT_Unified dht(DHTPIN, DHTTYPE);

//LiquidCrystal_I2C lcd(0x3F,20,4);
LiquidCrystal_I2C
lcd(0x27, 20, 4);

uint32_t delayMS;

void setup() {

  Serial.begin(9600);
  Serial.print("Hello ");

  // initialisation des broches entree/sortie
  pinMode(pinChauffagePWM, OUTPUT); 
  attachInterrupt(digitalPinToInterrupt(zcPin), zero_cross, RISING);

  pinMode(pinVentilation,OUTPUT);
  analogWrite(pinVentilation, 150);

  pinMode(pinPompe,OUTPUT);
  digitalWrite(pinPompe, LOW);


  // Mise en position servomoteur
    myservo.attach(servoPin);
    myservo.write(0);
    myservo.detach();
  
  // initialisation de l'afficheur
  lcd.init(); 
  // Initialize device.
  dht.begin();
  // Print temperature sensor details.
  sensor_t sensor;
  dht.temperature().getSensor(&sensor);

  // Print humidity sensor details.
  dht.humidity().getSensor(&sensor);

  // Set delay between sensor readings based on sensor details.
  delayMS = sensor.min_delay / 1000;
  Serial.print(delayMS);

  // Temps pour l'arrosage
  TempsArrosage<-millis();
}


void loop()
{

    // Délais entre les mesures
     delay(delayMS);
  
  sensors_event_t event;  
  dht.temperature().getEvent(&event);
  ValeurTemperature=event.temperature;

  dht.humidity().getEvent(&event);
  ValeurHumidite=event.relative_humidity;

  TempsDepuisBascule=millis()-(nbCycle*60000); // Bascule toutes les 2 heures


  // Cycle de démarrage on part à 50% du PWM et on chauffe soit jusqu'à passer au dessus de 38,2 degré, soit jusqu'à un arret de la montée de température (besoin de plus de puissance pour atteindre la température voulue!
  if(Chauffe==0){
    PWMChauffe=15;
    
    Serial.print("Chauffe Temp: ");
    Serial.print(ValeurTemperature);
    Serial.println(); 


  // Interrogation température au dessus valeurs souhaité? 
    if(ValeurTemperature>38.3){         // Consigne température haute
    PWMChauffe=PWMChauffe+1;
    Chauffe=1;
  }

  // Interrogation augmentation témpérature (10 répétitions avec temp = a 0.1 degré près!
    if(ValeurTemperature<38.4){         // Consigne température basse


// On récupère la température et on la compare a la valeurs du cycle précédent!
      ActTemp=round(ValeurTemperature * 10)/10.0;
      if(ActTemp==LastTemp){ 
        nbStagne++; stagnation;  
        }

  }
  
}

  if(Chauffe==1){

  // On ajuste la température

if(ValeurTemperature<38.2){     // Consigne température basse
    if(PWMChauffe==10){
      PWMChauffe=PWMChauffe;
    }
    else {
      PWMChauffe=PWMChauffe-1;
    }
}
if(ValeurTemperature>38.3){     // Consigne température haute
    if(PWMChauffe==85){
      PWMChauffe=PWMChauffe;
    }
    else {
      PWMChauffe=PWMChauffe+1;
    }
}
}
  
  // On rajoute le temps avec millis

  TempsPasse=millis();
  NombreDeJour=TempsPasse/86400000;
  ResteJour=TempsPasse%86400000;
  NombreHeure=ResteJour/3600000;

  

  //Retournement Incrementation de nbcycle a chaque fois 
if(TempsDepuisBascule>10800000){
  // En fonction du cycle(pair ou impair, myservo(0) ou myservo(180)
  if(nbCycle%2 == 0){
    
    myservo.attach(servoPin);
    myservo.write(90);
    delay(1000);
    myservo.detach();    
    Serial.print(nbCycle);
    Serial.print("X"); 
  }
  if(nbCycle%2 == 1){
    myservo.attach(servoPin);
    myservo.write(0);
    delay(1000);
    myservo.detach();
    
    Serial.print(nbCycle);
    Serial.print("X"); 
    
  }
  
       nbCycle=nbCycle+1;    

}


// Controle Humidité:
DelaisArrosage=millis()-TempsArrosage;
    Serial.print("DelaisArrosage:");
    Serial.print(DelaisArrosage);
    Serial.println(); 


if(FindeCycle==0){
if(ValeurHumidite<50){
 if(DelaisArrosage>300000){
  digitalWrite(pinPompe, HIGH);
  delay(10000);
  digitalWrite(pinPompe, LOW);
  TempsArrosage=millis();
}
}
}

if(FindeCycle==1){
if(ValeurHumidite<90){
  if(DelaisArrosage>300000){
  digitalWrite(pinPompe, HIGH);
  delay(14000);
  digitalWrite(pinPompe, LOW);
  TempsArrosage=millis();
}
}
}







// Affichage des informations
  //Temps depuis dernière bascule
  HeureDepuisBascule=TempsDepuisBascule/3600000;
  ResteJourDepuisBascule=TempsDepuisBascule%3600000;
  MinuteDepuisBascule=ResteJourDepuisBascule/60000;
  
lcd.backlight();
// Envoi du message
lcd.setCursor(0, 0);
lcd.print("Incubation ");
lcd.setCursor(13, 0);
lcd.print(NombreDeJour);
lcd.setCursor(15, 0);
lcd.print("J");
lcd.setCursor(16, 0);
lcd.print(NombreHeure);
lcd.setCursor(18, 0);
lcd.print("H");

lcd.setCursor(0,1);
lcd.print("Temperature ");

lcd.setCursor(12,1);
lcd.print(ValeurTemperature);
lcd.setCursor(17,1);
lcd.print("*C");

lcd.setCursor(0, 2);
lcd.print("Hygrometrie ");
lcd.setCursor(12, 2);
lcd.print(ValeurHumidite);
lcd.setCursor(18,2);
lcd.print("%");

lcd.setCursor(0, 3);
lcd.print("Last bascul");
lcd.setCursor(12, 3);
lcd.print(HeureDepuisBascule);
lcd.setCursor(13, 3);
lcd.print("H");
lcd.setCursor(14, 3);
lcd.print(MinuteDepuisBascule);
lcd.setCursor(16, 3);
lcd.print("min");

// Enregistrement de la température
LastTemp=round(ValeurTemperature * 10)/10.0;

// Ecriture de la variable PWM sur moniteur
    Serial.print("PWM: ");
    Serial.print(PWMChauffe);
    Serial.println(); 

}






void zero_cross() // Création de la fonction passage du zéro
{
  int dimtime = (Dividende*PWMChauffe);
  delayMicroseconds(dimtime);
  digitalWrite(pinChauffagePWM, HIGH);
  delayMicroseconds(10);
  digitalWrite(pinChauffagePWM, LOW);
}


void stagnation() {
            Serial.print("Début stagnation : ");
            Serial.print(nbStagne);
            Serial.println(); 
  if (nbStagne > 10) { // Vérifie que la température a stagné au moins 10 fois de suite
      Chauffe=Chauffe-1;
      Chauffe=1;
    }
};

Ton code semble très complexe. L'as tu testé par morceaux avant ?

Que signifie cette ligne à la fin du setup

TempsArrosage<-millis();

Bonjour,

Pour la complexité du code, je vais essayer de le découper en plusieurs fonctions pour pouvoir le tester par partie! Je n'y avais pas pensé...

Sinon, la ligne à la fin de mon setup est uniquement pour donner une valeur à "TempsArrosage" pour attendre attendre 5 minutes avant le premier remplissage du bas d'eau. Je pourrais plus simplement mettre TempsArrosage=0 dans la partie déclaration des variables!

Merci de ta réponse!
Quentin

Tu peux faire ça en effet. Mais une affectation de variable se fait avec le signe = pas avec une flèche

variable = valeur ;

Ca n a peut être pas de rapport direct, mais j ai le même problème avec 2 sondes d humidité avec dht22 et sonoff sous espeasy, ca marche 2j et pouf ca envoie nan, je n ai pas trouvé de raisons et c est frustrant, la fiabilité du dht22 me semble assez nulle

la fiabilité du dht22 me semble assez nulle

Il paraît que ce n'est pas très facile à piloter.

J'utilise plutôt le SHT31D en I2C.

Bonjour à tous,

Hier j'ai bidouillé un peu mon code et j'ai remarqué que mon problème est lié au gradateur! A partir du moment où PWMchauffe arrive à 47, la lecture de la sonde DHT22 ne fonctionne plus! De 47 a 85, ca ne marche pas! Comme si les variations du courant délivré par le gradateur influencé la lecture...
Je ne comprend pas trop pourquoi. ..

Quelqu'un aurait une idée?

Merci et bonne journée
Quentin

Bonjour

L'amplitude des parasites émis par le gradateur dépend de l'instant ou le triac du gradateur s'amorce.
Le pire étant un amorçage au sommet de la sinusoïde de la tension du secteur soit un gradateur à 50%
Un récepteur radio en AM à proximité d'un gradateur donne une idée du rayonnement.

Le gradateur comporte-t-il une inductance permettant d'atténuer les parasites émis ?
Le gradateur est-il indispensable ? la régulation du chauffage ne peut elle se faire en tout ou rien ?

Bonsoir,

Merci de ta réponse!
Non, pas d'inductance sur le gradateur! Comment pourrais mettre ca en place?

Au début, la couveuse fonctionnait en tout ou rien avec un relais, mais le relais se couper et s'allumer toutes les 5 secondes... il est donc arriver au terme de sa vie de 100.000 ouverture fermeture...
C'est pour cette raison que je suis passé sur un gradateur!

Quentin

Et pourquoi pas un relais statique ?

Pour l'antiparasitage d'un gradateur voir le schéma 001B sur cette page du site Sonelec
Un relais statique remplacerait semble plus adapté qu'un gradateur pour remplacer un relais electromécanique

Merci de vos réponses!

Je vais commander un relais statique alors! Sur ce type de relais, il n'y a pas de "durée de vie" (nombre de cycle On/Off max)?

En attendant de recevoir le relais, je vais essayer de faire fonctionner le programme avec le gradateur! Est ce que vous pensez qu'un self provenant d'un transformateur 220v->12V pourrait fonctionner pour atténuer les parasites? J'ai trouver ça dans mon bazar

Bonne soirée
Quentin

non, il n'est pas garanti que ce tore convienne ( valeur d'inductance, diamètre du fil, matériau du tore..)