Ventilateur Salle de Bain avec detection d'hygrométrie de référence

Bonjour à tous,

Tout d’abord je tiens à vous informer que je ne suis pas électronicien, mon métier c’est l’informatique.

Je suis occupé à développé un circuit de remplacement pour mon ventilateur de salle de bain.

L’idée est la suivante : A l’allumage de la lampe d’éclairage salle de bain (entrée en boucle while(digitalRead(12)), une humidité de référence est stockée. Si cette humidité de référence est dépassée de 5% (seuil de tolérance) cela signifie que la salle de bain a été utilisée pour une douche un bain ou autre. La ventilation s’enclenche et une variable est d’activité est stockée tant que l’humidité n’est pas revenue sous le seuil.
Si l’éclairage est coupé (sortie de boucle while) alors que l’humidité n’est pas revenue sous le seuil le ventilateur continue à tourner pendant 20 minutes max ou jusqu’à ce que le seuil de tolérance soit atteint.
Dans un des deux cas le ventilateur se coupe et le système repasse en veille après avoir mis la variable d’activité à 0.

J’ai écrit le code et il fonctionne, j’ai déjà fait le circuit de mesure avec un DHT22 et le circuit de puissance avec un TRIAC.

Mon problème ce situe dans la détection d’allumage de la lumière que je veux électrique parce que la salle de bain est naturellement éclairée.

J’ai trouvé un circuit basé sur un TIL111 (voir attachement) mais je n’arrive pas à faire basculer mon entrée digitale (12) d’une manière nette.

Le but étant que lorsque la lampe est éteinte l’état de l’entrée soit à LOW et lorsqu’elle est allumée l’état soit à HIGH ou inversement mais en tout cas sans rebond.
Est-ce qu’une âme charitable pourrais m’aiguiller un peu ?
Voici le schéma sur lequel je me suis appuyé.

Une fois le projet achevé je publierai l’intégralité du Projet.

D’avance merci.

Olivier

220v-power-interface-diagram.gif

Salut ... J'ai fais ce montage dans ma salle de bain mais sans tenir compte de l'éclairage ... Je n'en vois pas l'utilité, d'autant que si ta salle de bain est éclairée naturellement ... On peut y prendre une douche sans allumer la lumière ?

Bref ... Pour moi je fais une mesure de l'humidité moyennée sur 10 min, si on dépasse de 5% on allume le ventilo et on garde comme référence l'humidité à la mise en marche du ventilo ... Quand elle revient sous cette valeur, on ventile encore 20 min puis on éteint ...

Pendant que le ventilo est en marche je ne fais pas de moyennage de l'humidité, juste une mesure...

J'ai aussi remarqué qu'avec le chauffage, l'humidité n'était pas toujours suffisante pour déclencher le ventilo, je fais donc de même sur la mesure de température (moyennage sur 10 min, marche si +2°)

Si tu tiens à ta mesure d'éclairage, une photo résistance orientée vers la lumière (avec un pare soleil) pourrait faire l'affaire. Attention aux risques électriques sur le 220V, surtout dans une salle de bain ...

Il y a aussi des capteurs de courant dans ce genre ...ici

Merci tout d'abord pour ta réponse B83s,

Concernant la lumière, la salle de bain est naturellement éclairée et parfois en plein soleil. Mais je dois quand même allumer l'interrupteur pour avoir de la musique. Donc la photorésistance n'est pas une solution. C'est pourquoi je comptais sur cet événement pour fixer l'humidité de référence.

Ton idée n'est vraiment pas mauvaise de mesurer l'humidité sur les 5 ou 10 dernières minutes. Mais je ne vois pas comment coder cela. Serrais-tu disposé à en partager le code ?

Bien à toi

Olivier

bonjour pas sur que la la led du TIL111 apprecie tres longtemps une simple 200K perso lorsque je veux recuperer "de la presence secteur" j'utilise simplement un luciole neon avec sa R et une LDR je tube les 2 .

Pas de soucis …

sur le principe, le code prend une mesure toutes les 10s,
toutes les 2 minutes on insère la mesure dans un tableau de 10 valeurs (quand on atteint le dernier point du tableau on revient au début, c’est la variable index qui pointe dans le tableau)
on calcule donc la moyenne glissante (sur 10 points, un toutes les 2 minutes) sur 20 minutes (la moyenne permet de tenir compte des variations naturelles et lentes du climat) … quand le ventilo est en marche, on n’actualise pas la moyenne.
une douche se traduit par une hausse brutale de l’humidité ou de la température (chauffage). Un seuil relatif (+ 5%) permet de déclencher le ventilo facilement.

pour géré le ventilo, j’ai choisi un compteur (appelé decompte) …

  • si decompte = 0 ventilo à l’arrêt,
  • si decompte != 0 ventil en marche …
  • le decompte est initialisé à 120 tant que le seuil est dépassé
  • le décompte est décrémenté de 1 toutes les 10s si le seuil n’est pas dépassé … ça permet de maintenir la ventilation en marche encore 20 minutes (120 * 10s) pour finir d’assécher l’ambiance
#include <dht.h>

#define DEBUG 1
#define DHT11_PIN 6
#define RELAI_VMC 12

dht DHT;

#define NB 10 //nombre de mesures pour la moyenne
byte decompte = 0;
unsigned long next;

float RH[NB];
float Temp[NB];
byte index;
int moyTemp = 18;
int moyRH = 15;


void setup()
{
  wdt_disable();
  Serial.begin(9600);
  
  pinMode(RELAI_VMC,OUTPUT);
  pinMode(13,OUTPUT);
   
  //tourne pdt 1 min au démarrage
  decompte = 6; 
  digitalWrite(RELAI_VMC,HIGH);
  
  //lit les premières mesures jusqu'à avoir des valeurs correctes
  getTRH();
         
  //init du tableau et moyennes
  for (byte i = 0; i < NB; i++) {
     RH[i] = DHT.humidity;
     Temp[i] = DHT.temperature;
  }
  mean();
}

void mean() {
  //calcule les moyennes
  float m1, m2;
  for (byte i = 0; i < NB; i++) {
    m1 +=  RH[i];
    m2 += Temp[i];
  }
  moyRH = m1/NB;
  moyTemp = m2/NB;

  if (DEBUG) {
    Serial.print("moy= "); Serial.print(moyRH); 
    Serial.print(" ");  Serial.println(moyTemp);
  }
}

void getTRH() {
    int chk;
    do {
     chk = DHT.read11(DHT11_PIN);
     if (DHT.temperature <= 0) DHT.temperature = 10; //en cas de bug sonde
     if (DHT.humidity    <= 0) DHT.humidity    = 20;
     if (DEBUG) {
       if (chk != DHTLIB_OK) Serial.println("Erreur");
     }
    } while (chk != DHTLIB_OK); //plante si defaut de sonde permanent
}

void loop() {  
  if (millis() > next) {
    getTRH();
    
    if (DEBUG) {
      Serial.print(cptboucle);     Serial.print(F(",\t"));
      Serial.print(DHT.temperature, 1);    Serial.print(F(",\t"));
      Serial.print(DHT.humidity, 1);      Serial.print(F("; moy=\t")); 
      Serial.print(moyTemp, 1);    Serial.print(F(",\t"));
      Serial.print(moyRH, 1);      Serial.print(F(",\t"));   
      Serial.print(decompte, 1);   Serial.println(F(",\t")); 
    }
    
    //toutes les 2 minutes on ajoute un point à l'historique, sauf si ventil en marche
    if (cptboucle % 12 == 0 && decompte == 0) { 
      if (++index >= NB) index = 0;
      if (DHT.humidity > 5)    RH[index]   = DHT.humidity;
      if (DHT.temperature > 5) Temp[index] = DHT.temperature;
      //calcul des moyennes lissées
      mean();
    }
    
    //mise en marche si on dépasse la moyenne de 5% ou de 2°
    if (DHT.humidity >= moyRH + 5 || DHT.temperature >= moyTemp + 2 ) decompte = 120; // 120x10s = 20 minutes
    //qd RH revient sous l'ancienne moyenne+5%, on commence à décompter
    if (decompte > 0 && DHT.humidity <= moyRH + 5) decompte--;
  
    if (decompte > 0) digitalWrite(RELAI_VMC,HIGH); //MARCHE
    else   digitalWrite(RELAI_VMC,LOW); //ARRET
    
      
    //prochaine mesure dans 10s
    cptboucle++;
    next += 10000; 
  }
  
}

Merci pour ton Code,

J'utilise personnellement un DHT22 qui d'après mes infos semble plus rapide, plus fiable et plus précise.

Pour le reste, j'ai juste un truc qui me chiffonne au sujet de l'arduino et ce quelque soit le projet. C'est le millis(), c'est un entier long et tout les 50 jours il repasse par zéro.

Tu incrémentes ton next de 10000 toutes les 10 secondes. Au bout de 50 jours est-ce que cela ne va pas coincer ?

if (millis() > next)

Au bout de 50 jours millis()=0 et next =+/- 4 294 967 295

@+ Olivier

oui et non

quand on arrivera aux 50 jours next sera incrémenté et il y aura un débordement ... next repassera par 0 et aura une valeur comprise entre 0 et 10000 (mais ça ne fera pas planter l'arduino)

on aura alors pendant 10 s (le temps que millis() déborde aussi) le cas ou millis() > next est toujours vrai même si on incrémente next de 10000. On va donc entrer dans la boucle très vite et au pire le ventilo s'arrêtera plus vite que prévu parce que le décompte sera effectué plus vite.

j'y avais pensé mais sans en tenir compte car pour moi ce passage a des effets négligeables pour moi.

Correction possible ...

next += 10000; if (millis() > next) delay(10000); //next a débordé ... on attend que millis() déborde aussi, au prochain passage, les millis() et next auront repris leur cours croissant

Pour ne pas être embêté avec le roll over de la fonction millis(), le mieux est de toujours considérer un délai. Ce n'est pas très compliqué. Juste une bonne habitude à prendre.

const unsigned long intervalle = 10000UL;
unsigned long millis_dernier_declenchement = 0;

void loop() {

  unsigned long delai_depuis_dernier_declenchement = millis() - millis_dernier_declenchement;
  //NB : la soustraction est insensible au roll over de millis()

  if (delai_depuis_dernier_declenchement >= intervalle) {
    millis_dernier_declenchement = millis();
  ...

Avec ce code, le tout premier déclenchement intervient 10 secondes après démarrage de l'arduino. Pour avoir un premier déclenchement dès la première exécution de la fonction loop(), on peut ajouter

void setup {
  ...
  millis_dernier_declenchement -= intervalle;
}

Merci pour votre aide à vous deux.

Je vais réétudier mon projet.

Bien à vous et bon réveillon.

Olivier

En allant au plus simple, si ta carte ne fait rien d'autre que de lire le dht22 et activer le ventilo, tu oublies les millis() et tu mets un delay(10000) dans le loop ... Le temps n'est pas critique dans ton montage

Bonnes fêtes !

Me revoilà,

J’ai mis en application le code de B83s, que j’ai un peu saucé.

En gros le principe est le même sauf :
-Qu’il ne tient pas compte de la température dans le calcule.
-Qu’une LED clignote lorsque le DHT renvoie des valeurs erronées NAN.
-Que le circuit pilote un TRIAC plutôt qu’un relais.

Je l’ai testé sur un arduino UNO, cela fonctionne très bien. (Merci B83s pour l’inspiration).

Fort de ce succès, j’ai voulu le porter sur un Atmega328P-PU et là déception apparemment le système plante lors des tentatives de lecture du DHT22.

J’ai parcouru quelques pages WEB et apparemment il y avait un problème avec les anciennes librairies sous 8mhz, les nouvelles librairies sont censées tenir compte de la fréquence du processeur.
Mais apparemment ce n’est pas le cas.

Mais question est la suivante : Est-il possible de faire fonctionner un Atmega328P-PU à 16Mhz quitte à utiliser un quartz externe.
Et si oui avez-vous une référence de mise en oeuvre ?

J’ai mis toutes infos en attachement

D’avance Merci

Final_Bathroom_Fan_Average.ino (4.45 KB)