(résolu) Plage horaire pour déclenchement d'une action

Bonjour à tous,

Je bloque sur un problème. J’ai installé une sonde DHT11 pour mesurer l’humidité de l’air. L’objectif est de déclencher via un relay un déshumidificateur. ça fonctionne a peu près correctement. Maintenant je cherche à ce que le déclenchement du relais ne sois opérationnelle que de 6h du matin à 21h le soir.

J’ai installé la librairie Time, mais mon code ne fonctionne pas…

 if (hour() <= 9 && hour() >= 22 && dht.readHumidity() < 30){ 
  digitalWrite (relais,HIGH); 
  
   lcd.setCursor(11, 1);
  lcd.print("Off");
 // digitalWrite (relais, 1);

  }

else {
  digitalWrite(relais,0);
  lcd.setCursor(11, 1);
  lcd.print("On");
}

Je peux poster le code complet si besoin

Salut,

La lib Time ne fonctionne pas tel quel, elle doit être couplée à une référence de temps : internet, une RTC, DFC77, liaison série ou GPS.

Achète toi un ptit module DS1307 ou similaire (PCF8583 par exemple)

Salut,

C’est juste une «bête» erreur de logique :slight_smile:

if (hour() <= 9 && hour() >= 22 && dht.readHumidity() < 30){

Sauf cas extrêmement particuliers et hors de propos ici, un nombre ne peut pas être à la fois inférieur ou égal à 9 et supérieur ou égal à 22… donc la condition d’exécution du if n’est jamais remplie.

Ce qu’il te faut c’est un «ou logique» :

if ((hour() <= 9 || hour() >= 22) && dht.readHumidity() < 30){

Merci B@tto pour ta réponse, j'aurais dû préciser que j'avais déjà installé un DS1307.

Le || était la bonne solution, j'ai donc bien ma plage horaire qui est opérationnelle !!

Un grand merci pour vos réponses, Haifger, tu avais juste !

Bon maintenant je vais mettre en boite mon petit montage et travailler sur un vieux projet heure d'été/ heure d'hiver que je n'avais pas encore pu terminer...

Bonne nouvelle :slight_smile:

Pour être tout à fait complet, note que la solution du ou logique n’en est qu’une parmi d’autres. Par exemple tu aurais pus tout aussi bien garder le principe du et logique mais en inversant le «sens» des opérateurs de comparaisons, comme ceci par exemple :

if (!(hour() >= 9 && hour() <= 22) && dht.readHumidity() < 30){

Les 2 solutions donnent les mêmes résultats, c’est juste une question de choix personnel, de ce que tu trouves le plus facile à appréhender, et il est fort probable que le compilateur génère le même code au final.

Merci pour ton aide.

Je suis en train de faire des essais et ça ne marche pas comme je veux en fait.

gunsman76: Je suis en train de faire des essais et ça ne marche pas comme je veux en fait.

Va quand même falloir donner un peu plus de détails sur les symptômes parce que là... :)

En gros ça marche pô…

Je mets mon code complet :

#include <DHT.h> //Librairie pour le capteur DHT
#include <Wire.h>
#include <RTClib.h> 
#include <LiquidCrystal_I2C.h> //librairie i2c
#include <Time.h> 

RTC_DS1307 RTC; 
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);

 
#define DHTPIN 9 //Pin auquel est connecté le capteur DHT
 
#define DHTTYPE DHT11 //Si vous utiliser le DHT 11
//#define DHTTYPE DHT22 //Si vous utiliser le DHT 22  (AM2302)
//#define DHTTYPE DHT21 //Si vous utiliser le DHT 21 (AM2301)
 
const int intTimePause = 5000; //Par défaut on actualise les valeures toutes les 5 secondes
//const int Ledverte=13;
const int relais = 6;

float fltHumidity; //Pourcentage d'humidité mesuré
float fltTemperature; //Température mesurée en Celsius
 
DHT dht(DHTPIN, DHTTYPE); //On initialise le capteur DHT
 
boolean running = false;
 
void setup()
{
  lcd.begin(16, 2); //On indique le nombre de colonnes et de lignes de l'écran
  lcd.clear(); //On efface tout ce qui se trouve sur l'écran

pinMode (relais, OUTPUT);

    Serial.begin(57600);
    Wire.begin();
    RTC.begin();

  if (! RTC.isrunning()) {
    Serial.println("RTC is NOT running!");
    // following line sets the RTC to the date & time this sketch was compiled
    RTC.adjust(DateTime(__DATE__, __TIME__));

}
} 

 
void loop(){
  
   
  //RTC.adjust(DateTime(__DATE__, __TIME__));

  
  DateTime now = RTC.now();
  lcd.setCursor(0, 1);
  //lcd.print (now.day(),DEC);
  //lcd.print("/");
  //lcd.print (now.month(),DEC);
  //lcd.print("/");
  //lcd.print (now.year(),DEC);
  //lcd.print("  ");
  lcd.print (now.hour(),DEC);
  lcd.print(":");
  lcd.print(now.minute(), DEC);
  //lcd.print(":");
  //lcd.print(now.second(), DEC);
  

  fltHumidity = dht.readHumidity(); //On lit le pourcentage d'humidité
  fltTemperature = dht.readTemperature(); //On lit la température en degrés Celsuis
  if (isnan(fltTemperature) || isnan(fltHumidity)) //Si les valeures retournées ne sont pas des nombres :
  {
    lcd.setCursor(0, 1); //Positionnement du curseur
    lcd.print(DHTTYPE); //On affiche le type de capteur
    lcd.setCursor(5, 1);
    lcd.print(" illisible"); //On affiche l'erreur
  }
  else
  {
    //mise en forme et affichage des informations sur l'écran LCD
    lcd.setCursor(0, 0); //Positionnement du curseur
    lcd.print("T: ");
    lcd.setCursor(3, 0);
    lcd.print(fltTemperature,0); //Affichage de la température
    lcd.setCursor(5, 0);
    lcd.print((char)223); //Affiche le caractère ° (degrés)
    //lcd.setCursor(14, 0);
    //lcd.print("C"); //En degrés Celsuis
    lcd.setCursor(10, 0);
    lcd.print("H: ");
    lcd.setCursor(13, 0);
    lcd.print(fltHumidity,0); //Affichage de l'humidité
    lcd.setCursor(15, 0);
    lcd.print("%");
  }

    
  if ((hour() <= 8 || hour() >= 5) && dht.readHumidity() < 30){ 
  digitalWrite (relais,HIGH); 
  
   lcd.setCursor(11, 1);
  lcd.print("Off");


  }


else {
  digitalWrite(relais,0);
  lcd.setCursor(11, 1);
  lcd.print("On");
}
  
  delay(intTimePause); //On actualise les informations toutes les x millisecondes.




}

En gros je n’arrive pas à couper mon relay en dehors de la plage d’utilisation.

Par exemple si je veux que le relay déclenche si il est entre 9h et 10h si le degré d’humidité est superieur à 30% et bien ça reste sur ON dès l’instant ou la 3e consigne (l’humidité) est ok.

En gros

9h/10h la plage horaire qui vérifie que l’humidité est supérieur à 30%. Mais en dehors de cette plage pas de vérification.

Tu as vraiment un problème avec les opérateurs logiques toi :slight_smile:

  if ((hour() <= 8 || hour() >= 5) && dht.readHumidity() < 30){

Si je traduis ça en français ça donne :
«si heure est inférieure ou égale à 8 ou supérieure ou égale à 5, alors …»
Cette condition est toujours vraie (c’est le problème inverse de ton premier post). Il faut corriger cela en fonction des éléments déjà donnés plus haut, mais ce n’est pas le seul problème de ton code, essaie plutôt comme ça (vérif entre 10H et 11H) :

if (hour() >= 10 && hour() < 11) {
  if (dht.readHumidity() < 30) {
    digitalWrite (relais,HIGH);
    lcd.setCursor(11, 1);
    lcd.print("Off");
  }
  else { // Si humidité >= 30, relais activé
    digitalWrite(relais,0);
    lcd.setCursor(11, 1);
    lcd.print("On");
  }
else { // Relais toujours éteint en dehors de la plage horaire définie
  digitalWrite(relais, HIGH);
  lcd.setCursor(11, 1);
  lcd.print("Off");
}

Je viens d’essayer ton dernier code Haifger. Le double else ne fonctionne pas. J’ai donc remis un seul else en modifiant le code comme ceci :

 if (hour() >= 5 && hour() < 11) {
  //if (dht.readHumidity() < 30) {
    digitalWrite (relais,LOW);
    lcd.setCursor(11, 1);
    lcd.print("Off");
 // }
 // else { // Si humidité >= 30, relais activé
 //   digitalWrite(relais,0);
 //   lcd.setCursor(11, 1);
 //   lcd.print("On");
  } 

else { // Relais toujours éteint en dehors de la plage horaire définie
  if (dht.readHumidity() < 30) 
  digitalWrite(relais, HIGH);
  lcd.setCursor(11, 1);
  lcd.print("On");

}
 }

Mais quel que soit la plage horaire, ça ne fonctionne pas. J’ai bien relu ton explication, c’est vrai que les opérateurs logiques étaient un peu illogique, là j’ai bien compris.

J’essaye donc de résonner de la façon suivante :

Si l’heure est entre 9h et 11h relay off sinon % hygrométrie supérieur à 30 relay ON

Mais ça ne marche pas non plus, l’action sur l’hygrométrie fonctionne parfaitement. Si je note 50%, ça coupe bien.

Il me reste donc la plage horaire.

Ok, je crois qu’en fait on ne se comprend pas bien sur le mode de fonctionnement que tu désires :slight_smile: Déjà, tes horaires changent à chaque message, et ceux placés dans tes codes ne correspondent pas à ceux de tes commentaires, faudrait essayer de fixer un peu tout ça, ou au moins décider d’un exemple que tu pourra éventuellement changer plus tard.

Concernant le fonctionnement souhaité ça n’est pas clair également, puisque tu change d’un message à l’autre :grin: :

gunsman76:
En gros
9h/10h la plage horaire qui vérifie que l’humidité est supérieur à 30%. Mais en dehors de cette plage pas de vérification.

gunsman76:
Si l’heure est entre 9h et 11h relay off sinon % hygrométrie supérieur à 30 relay ON

Le code que j’avais proposé correspond à la première citation : à l’intérieur de la plage horaire définie on vérifie si le taux d’hygrométrie nécessite une mise en route ou non, mais en dehors de cette plage le relais est toujours éteint.

Maintenant si ce que tu veux c’est plutôt ce qui est écrit dans la deuxième citation, alors il faut plutôt faire ça :

if (hour() >= 9 && hour() < 11) { // Relais toujours éteint pendant la plage horaire définie
  digitalWrite(relais, HIGH);
  lcd.setCursor(11, 1);
  lcd.print("Off");
}
else {
  if (dht.readHumidity() < 30) {
    digitalWrite (relais,HIGH);
    lcd.setCursor(11, 1);
    lcd.print("Off");
  }
  else { // Si humidité >= 30, relais activé
    digitalWrite(relais,0);
    lcd.setCursor(11, 1);
    lcd.print("On");
  }
}

Oui désolé pour les heures, c'est parce que je fais des essais en même temps...

En gros là on se comprend, il faut simplement que la détection de l'humidité soit en route sur une plage horaire qu'on défini, en dehors de cette plage, pas besoin de détection et donc on met le relay sur OFF.

Merci de passer autant de temps sur mon problème.

Je repars faire des essais !

if (hour() >= 9 && hour() < 12) { // Relais toujours éteint pendant la plage horaire définie
  digitalWrite(relais, HIGH);
  lcd.setCursor(11, 1);
  lcd.print("On");
}
else {
  if (dht.readHumidity() < 30) {
    digitalWrite (relais,HIGH);
    lcd.setCursor(11, 1);
    lcd.print("On");
  }
  else { // Si humidité >= 30, relais activé
    digitalWrite(relais,0);
    lcd.setCursor(11, 1);
    lcd.print("Off");
  }
}
}

Bon j’ai remis de l’ordre dans le code, déjà le Off quand c’est arrêté et le on quand c’est en route. C’est déjà plus clair :grin:

Bon maintenant le soucis est simple, quelque soit la plage horaire, c’est sur off à l’écran mais le relay est sur ON… déjà rien que là j’ai un problème. J’avais donc inversé le on et le off au niveau du code pour que ce soit plus logique une fois tout mis en boite.

Seulement là, en remettant bien dans l’ordre avec l’ajout de la plage horaire j’ai toujours ce problème en pire.

J’ai raté quelque chose ?

Es-tu bien certains de la pertinence de cette modification ? La grande majorité des cartes relais qu'on trouve à-pas-cher sont actives bas, c'est à dire que le contact normalement ouvert du relais est ouvert quand la broche du microcontrôleur est à l'état haut et fermé quand la broche est à l'état bas.

Ce qui donne : digitalWrite(relais, HIGH) = relais OFF digitalWrite(relais, LOW) = relais ON

Mais tout ça dépend de ta carte d'interface avec le relais, de ton relais (SPDT ?), le cas échéant de la sortie du relais sur laquelle tu es branché (NO/NF), ...

Bref, je pense que ce changement n'est pas pertinent, mais il n'y a que toi qui peut en être sûr...

Je fais les modifications tout de suite et je te tiens au courant.

Normalement lorsque l'on alimente la broche in du relai, on l'active. Donc en passant la sortie de la carte en HIGH, le relais dois s'enclencher.

Cela dit je tests tout de suite ton idée.

bon je viens de refaire le test complet, rien à faire ça ne veut pas.

Je remet mon code complet histoire de :

#include <DHT.h> //Librairie pour le capteur DHT
#include <Wire.h>
#include <RTClib.h> 
#include <LiquidCrystal_I2C.h> //librairie i2c
#include <Time.h> 

RTC_DS1307 RTC; 
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);

 
#define DHTPIN 9 //Pin auquel est connecté le capteur DHT
 
#define DHTTYPE DHT11 //Si vous utiliser le DHT 11
//#define DHTTYPE DHT22 //Si vous utiliser le DHT 22  (AM2302)
//#define DHTTYPE DHT21 //Si vous utiliser le DHT 21 (AM2301)
 
const int intTimePause = 5000; //Par défaut on actualise les valeures toutes les 5 secondes
//const int Ledverte=13;
const int relais = 6;

float fltHumidity; //Pourcentage d'humidité mesuré
float fltTemperature; //Température mesurée en Celsius
 
DHT dht(DHTPIN, DHTTYPE); //On initialise le capteur DHT
 
boolean running = false;
 
void setup()
{
  lcd.begin(16, 2); //On indique le nombre de colonnes et de lignes de l'écran
  lcd.clear(); //On efface tout ce qui se trouve sur l'écran

pinMode (relais, OUTPUT);

    Serial.begin(57600);
    Wire.begin();
    RTC.begin();

  if (! RTC.isrunning()) {
    Serial.println("RTC is NOT running!");
    // following line sets the RTC to the date & time this sketch was compiled
    RTC.adjust(DateTime(__DATE__, __TIME__));

}
} 

 
void loop(){
  
   
  //RTC.adjust(DateTime(__DATE__, __TIME__));

  
  DateTime now = RTC.now();
  lcd.setCursor(0, 1);
  //lcd.print (now.day(),DEC);
  //lcd.print("/");
  //lcd.print (now.month(),DEC);
  //lcd.print("/");
  //lcd.print (now.year(),DEC);
  //lcd.print("  ");
  lcd.print (now.hour(),DEC);
  lcd.print(":");
  lcd.print(now.minute(), DEC);
  //lcd.print(":");
  //lcd.print(now.second(), DEC);
  

  fltHumidity = dht.readHumidity(); //On lit le pourcentage d'humidité
  fltTemperature = dht.readTemperature(); //On lit la température en degrés Celsuis
  if (isnan(fltTemperature) || isnan(fltHumidity)) //Si les valeures retournées ne sont pas des nombres :
  {
    lcd.setCursor(0, 1); //Positionnement du curseur
    lcd.print(DHTTYPE); //On affiche le type de capteur
    lcd.setCursor(5, 1);
    lcd.print(" illisible"); //On affiche l'erreur
    
  }
  else
  {
    //mise en forme et affichage des informations sur l'écran LCD
    lcd.setCursor(0, 0); //Positionnement du curseur
    lcd.print("T: ");
    lcd.setCursor(3, 0);
    lcd.print(fltTemperature,0); //Affichage de la température
    lcd.setCursor(5, 0);
    lcd.print((char)223); //Affiche le caractère ° (degrés)
    //lcd.setCursor(14, 0);
    //lcd.print("C"); //En degrés Celsuis
    lcd.setCursor(10, 0);
    lcd.print("H: ");
    lcd.setCursor(13, 0);
    lcd.print(fltHumidity,0); //Affichage de l'humidité
    lcd.setCursor(15, 0);
    lcd.print("%");
  }

if (hour() >= 13 && hour() < 15) { // Relais toujours éteint pendant la plage horaire définie
  digitalWrite(relais, HIGH);
  lcd.setCursor(11, 1);
  lcd.print("On");
}
else {
  if (dht.readHumidity() < 30) {
    digitalWrite (relais,LOW);
    lcd.setCursor(11, 1);
    lcd.print("On");
  }
  else { // Si humidité >= 30, relais activé
    digitalWrite(relais,LOW);
    lcd.setCursor(11, 1);
    lcd.print("Off");
  }
}
}

Que je passe en HIGH en LOW ne change rien au problème, la seule condition qui fonctionne c’est l’humidité. Le reste, je peux mettre l’heure que je veux, ça ne change rien du tout.

Bon je vais faire une pause et reprendre tout à 0, je dois avoir une erreur qui perturbe le fonctionnement des conditions.

Bon bon bon, je crois que la vérité est ailleurs :) (ou du moins qu'il y a plus de problèmes que ceux déjà résolus :grin:)

Si j'ai bien compris, la fonction hour() est définie dans la librairie Time.h, or il me semble qu'à aucun moment dans ton programme tu n'indiques à cette librairie comment elle doit se synchroniser avec la RTC DS1307.

Essaie d'ajouter ça à la fin de ton setup() :

setSyncProvider(RTC.get);

ça ne compile pas, j'ai l'erreur suivante :

DHT_I2C_temperature_humidite.ino: In function 'void setup()': DHT_I2C_temperature_humidite:39: error: 'class RTC_DS1307' has no member named 'get'

Arf, ça dépend de la librairie que tu utilises en fait :slight_smile:

Bon essaie soit avec :

setSyncProvider(RTC.now);

Ou bien (au choix) directement dans le if :

if (now.hour() >= 13 && now.hour() < 15) {

Oui pour la librairie, j’ai d’ailleurs passé beaucoup de temps juste pour le hour().

Bon cela dit tes deux solutions ne fonctionnent pas. J’ai repris tout à 0. j’ai refais un bout de code qui fonctionne parfaitement temps que je n’introduis pas la condition de la plage de temps.

J’en suis arrivé au stade de me dire autant tout mettre sur un programmateur, mais je pense que ce n’est quand même pas la solution.

Si je fais ça :

  if (dht.readHumidity() < 30) {
    digitalWrite (relais,HIGH);
    lcd.setCursor(11, 1);
    lcd.print("On ");
  }
  else { // Si humidité >= 30, relais activé
    digitalWrite(relais,LOW);
    lcd.setCursor(11, 1);
    lcd.print("Off");
  }
}

Sauf que dans ma logique je devrais avoir sur l’écran Off quand le relay est à l’arrêt et On quand il est en marche. Déjà là il y a un problème car j’ai le Off quand le relay est en route et le On quand il est arrêté.

Donc pour que ça marche normalement au niveau des On/Off je dois faire ce code là :

  if (dht.readHumidity() < 30) {
    digitalWrite (relais,LOW);
    lcd.setCursor(11, 1);
    lcd.print("On ");
  }
  else { // Si humidité >= 30, relais activé
    digitalWrite(relais,HIGH);
    lcd.setCursor(11, 1);
    lcd.print("Off");
  }
}