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!
#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;
}
};
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!
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
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. ..
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 ?
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!
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
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