Pour le vérifier, il suffit de mettre la ligne v_vent = 10.0; dans la routine AnemoTicks(), à la fin de préférence.
Et regarder ce qu'affiche le panel.
-----
Pour le vérifier, il suffit de mettre la ligne v_vent = 10.0; dans la routine AnemoTicks(), à la fin de préférence.
Et regarder ce qu'affiche le panel.
je fais comment pour voir si anemotick est appelé
Bjr BrainMan,
çà n'y fait rien,je l'ai mis à cet endroit
// Met le resultat en km/h
v_vent = v_vent * 3.6;
v_vent = 10.0;
si je le met au debut
void AnemoTicks()
{
anemoTickCompteur++;
v_vent = 10.0;
l'ecran indque
l'ecran indique 10km/h et des que l'anemo tourne il inscrit 10 km/h tout le temp avec une variation de courant tant que le relais est actionné
Voilà bravo, c'est parfait.Bjr BrainMan,
çà n'y fait rien,je l'ai mis à cet endroit
// Met le resultat en km/h
v_vent = v_vent * 3.6;
v_vent = 10.0;
si je le met au debut
void AnemoTicks()
{
anemoTickCompteur++;
v_vent = 10.0;
l'ecran indque
l'ecran indique 10km/h et des que l'anemo tourne il inscrit 10 km/h tout le temp avec une variation de courant tant que le relais est actionné
C'est ce qu'on appelle débugger.
L'important, ce n'est pas tant d'y arriver du premier coup (on ne peut pas tout savoir, surtout lorsqu'on commence à découvrir un des multiples domaines de l'informatique), mais comme vous le faites là, de faire appel à "la science expérimentale" pour arriver rapidement à identifier des "choses" qu'on ne savait pas.
Donc ici, je vais vous donner la "solution", c'est qu'il y a eu confusion depuis le début entre le signe d'affectation = et le signe de comparaison ==
https://bentek.fr/7-arduino-operateurs/
J'ai remplacé les = en cause par ==
Bon, il va y avoir les même bugs de majuscule minuscule (je ne sais pas où elles sont) puisque je doit repartir de la dernière version que je vous ai envoyé.Code:#include <LiquidCrystal.h> int etat_serre =0; // Indicateur d'état de la serre (0 = Ouvert/ 1=fermée) unsigned long fermeture_serre_tic = 0; // tic de fermeture de la serre (le tic c'est "le temps") unsigned long duree_fermeture_serre = 120 * 60000; // Durée max de fermeture de la serre en millisecondes (2 heures) // On démarre par le cycle Serre (donc on initialise avec la valeur Anemo... pour switcher tout de suite vers le cycle Serre) int cycle = 0; // Indicateur de Cycle, 0=Cycle gestion Anemo, 1=Cycle gestion Serre usigned long TicProchainCycle = 0; // "Temps" précalculé à atteindre pour changer de Cycle unsigned long DureeCycleSerre = 30000; // Durée du Cycle Serre 30 Secondes unsigned long DureeCycleAnemo = 15000; // Durée du Cycle Anemomètre 15 Secondes int relaisPin = 3; int anemo = 2; // initialisation, on définit les ports pour RS, E et D4 à D7 LiquidCrystal lcd(8, 9, 4, 5, 6, 7); // Temps en millisecondes depuis lequel le programme tourne // Est déclaré volative pour permettre de transmettre cette valeur de manière fiable // vers une SP de type ISR (SP de type Interruption) volatile unsigned long timeRun; // Employé pour calculer l'interval de temps entre deux appels à la routine AnemoTicks() volatile unsigned long timeLast; float periode; const int RELAY = 3; /***************Variables pour la vitesse du vent*****************************/ float v_vent = 0.00; //var qui contiendra la vitesse du vent float rayonBras = 0.01; //rayon du bras 9cm => 0.09m int anemoTickCompteur = 0; //variable pour le comptage du nombre de "TICKS" du capteur ILS de l'anemo float FEtalonage = 3.1; unsigned long previousMillis = 0; const unsigned long TimePause = 30 * 60000; const unsigned long TimeMarche = 5 * 60000 ; enum {ARRET, MARCHE} etat; /*************************************************************************/ /* Lancé automatiquement, avant loop(),au démarrage du programme */ /*************************************************************************/ void setup() { // Definit l'écran sur caractères (16) et de lignes (2) lcd.begin(16, 2); lcd.setCursor(0, 0); // Place le curseur delay(100); // Pause lcd.setCursor(1, 0); // Place le curseur lcd.print("initialisation"); // Affiche le message delay(500); // Pause lcd.clear(); // Efface l'écran delay(250); // Pause lcd.print("vent: "); // Affiche le texte lcd.setCursor(6, 0); // Place le curseur lcd.print(v_vent); // Affiche la valeur de la vitesse du vent égale à 0.00 au départ lcd.setCursor(11, 0); // Place le curseur lcd.print("km/h"); // Affiche le texte // Initialisation des entrées/sorties etat = MARCHE; /***************************************************************/ /* Mise en place des broches avec les fonctions d'interruption */ /***************************************************************/ pinMode(anemo, INPUT); // On écrit l'état du relais, definit la pin anemo(2) comme une entrée pinMode(relaisPin, OUTPUT); // Prépare l'activation du relai relié au PIN 3 // On commence par interdire les interruptions noInterrupts(); // Dès que la broche anemo(2) changera d'etat (RISING = état BAS vers HAUT (front montant)) // on appelle le SP AnemoTicks attachInterrupt(digitalPinToInterrupt(anemo), AnemoTicks, RISING); } /*****************************************************/ /** Boucle lancée automatiquement après Setup() **/ /*****************************************************/ void loop() { timeRun = millis(); if (timeRun > TicProchainCycle) {// Le tic (temps actuel en millisecondes) a dépassé le tic indiquant qu'il faut changer de cycle // Préparation de la valeur à dépasser pour lancer un prochain cycle de lecture Anemo ou Gestion Serre if (Cycle == 0) { // On est actuellement dans le cycle Anemo // On interdit les interruptions noInterrupts(); TicProchainCycle = timeRun + DureeCycleSerre; // On indique qu'on est maintenant dans le cycle Gestion Serre Cycle = 1; } else {// On est actuellement dans le cycle Gestion Serre TicProchainCycle = timeRun + DureeCycleAnemo; // On indique qu'on est maintenant dans le cycle Lecture Anemo Cycle = 0; // Charge timeLast avec la valeur timeRun, pour indiquer qu'il faut éviter de calculer la vitesse // du vent la premiere fois que le cycle anemo démarre timeLast = timeRun; // On autorise les interruptions Interrupts(); } } if (cycle == 0) {// On est dans le cycle Anemo, ne rien faire } else {// On est dans le cycle interdisant les interruption // Appelle le SP de Gestion de la Serre GereSerre(); } // Appelle à tous les coups le SP d'affichage des informations sur le panel LCD Afficher(); } /***********************************************************/ /** Sous-programme (ISR) appelé par interruption anemo **/ /** (Note : delay() ne peut pas fonctionner à ce niveau) **/ /** Une seule interruption sur 4 est prise en compte **/ /***********************************************************/ void AnemoTicks() { anemoTickCompteur++; if (anemoTickCompteur >= 4) { // Remise à 0 du compteur anemoTickCompteur anemoTickCompteur = 0; if (timeLast == timeRun) { // Ne pas Calculer la valeur du vent ce tour ci (la valeur actuelle du vent est conservée) } else { // Calcul la période et on divise par 1000.0 pour obtenir le résultat en seconde periode = (timeRun - timeLast) / 1000.0; // On initialise timeLast pour préparer le prochaine calcul de la période timeLast = timeRun; // calcul de la vitesse du vent avec la formule // vitesse du vent = rayonBras * 2pi * fréquence (frequence=nb_tour/s) // => résultat en m/s 2 Ticks = 1 tour/ 4 Ticks = 2 tours v_vent = rayonBras * 2 * 3.14 * (4 / periode) * FEtalonage; // Met le resultat en km/h v_vent = v_vent * 3.6; } } } /***********************************************/ /** Affichage des informations sur le PANEL **/ /***********************************************/ void Afficher() { lcd.setCursor(6, 0); // Place le curseur lcd.print(v_vent); // Affiche la valeur de la vitesse du vent lcd.setCursor(7, 1); // Place le curseur ??? Pourquoi faire.... } /***************************************************/ /** Gestion de la Serre (commande l'ouverture et **/ /** la fermeture) **/ /***************************************************/ void GereSerre() { if (v_vent > 27.77) // condition Km/h selon affichage sur l'écran (100/3.6) { // On ferme la serre digitalWrite(RELAY, LOW); // On notifie la fermeture etat_serre = 1; // On mémorise le Tic de fermeture fermeture_serre_tic = timeRun; } else { if (etat_serre == 1) {// La serre a été fermée suite à un vent trop fort if ((timeRun - fermeture_serre_tic) > duree_fermeture_serre ) { // On reouvre la serre préalablement fermée à cause du vent digitalWrite(RELAY, HIGH); // On notifie l'ouverture etat_serre = 0; } else { // On ferme la serre (ou on termine de la fermer) digitalWrite(RELAY, LOW); } } else { // On ouvre la serre digitalWrite(RELAY, HIGH); } } }
Mais sinon, ça doit mieux fonctionner.
Voici le corrigé dans les min et Maj,mais je suis désolé négatif, là le relais ne s'accione même pas ,vent 0 à l'ecran?????
Code:#include <LiquidCrystal.h> int etat_serre =0; // Indicateur d'état de la serre (0 = Ouvert/ 1=fermée) unsigned long fermeture_serre_tic = 0; // tic de fermeture de la serre (le tic c'est "le temps") unsigned long duree_fermeture_serre = 120 * 60000; // Durée max de fermeture de la serre en millisecondes (2 heures) // On démarre par le cycle Serre (donc on initialise avec la valeur Anemo... pour switcher tout de suite vers le cycle Serre) int cycle = 0; // Indicateur de Cycle, 0=Cycle gestion Anemo, 1=Cycle gestion Serre usigned long TicProchainCycle = 0; // "Temps" précalculé à atteindre pour changer de Cycle unsigned long DureeCycleSerre = 30000; // Durée du Cycle Serre 30 Secondes unsigned long DureeCycleAnemo = 15000; // Durée du Cycle Anemomètre 15 Secondes int relaisPin = 3; int anemo = 2; // initialisation, on définit les ports pour RS, E et D4 à D7 LiquidCrystal lcd(8, 9, 4, 5, 6, 7); // Temps en millisecondes depuis lequel le programme tourne // Est déclaré volative pour permettre de transmettre cette valeur de manière fiable // vers une SP de type ISR (SP de type Interruption) volatile unsigned long timeRun; // Employé pour calculer l'interval de temps entre deux appels à la routine AnemoTicks() volatile unsigned long timeLast; float periode; const int RELAY = 3; /***************Variables pour la vitesse du vent*****************************/ float v_vent = 0.00; //var qui contiendra la vitesse du vent float rayonBras = 0.01; //rayon du bras 9cm => 0.09m int anemoTickCompteur = 0; //variable pour le comptage du nombre de "TICKS" du capteur ILS de l'anemo float FEtalonage = 3.1; unsigned long previousMillis = 0; const unsigned long TimePause = 30 * 60000; const unsigned long TimeMarche = 5 * 60000 ; enum {ARRET, MARCHE} etat; /*************************************************************************/ /* Lancé automatiquement, avant loop(),au démarrage du programme */ /*************************************************************************/ void setup() { // Definit l'écran sur caractères (16) et de lignes (2) lcd.begin(16, 2); lcd.setCursor(0, 0); // Place le curseur delay(100); // Pause lcd.setCursor(1, 0); // Place le curseur lcd.print("initialisation"); // Affiche le message delay(500); // Pause lcd.clear(); // Efface l'écran delay(250); // Pause lcd.print("vent: "); // Affiche le texte lcd.setCursor(6, 0); // Place le curseur lcd.print(v_vent); // Affiche la valeur de la vitesse du vent égale à 0.00 au départ lcd.setCursor(11, 0); // Place le curseur lcd.print("km/h"); // Affiche le texte // Initialisation des entrées/sorties etat = MARCHE; /***************************************************************/ /* Mise en place des broches avec les fonctions d'interruption */ /***************************************************************/ pinMode(anemo, INPUT); // On écrit l'état du relais, definit la pin anemo(2) comme une entrée pinMode(relaisPin, OUTPUT); // Prépare l'activation du relai relié au PIN 3 // On commence par interdire les interruptions noInterrupts(); // Dès que la broche anemo(2) changera d'etat (RISING = état BAS vers HAUT (front montant)) // on appelle le SP AnemoTicks attachInterrupt(digitalPinToInterrupt(anemo), AnemoTicks, RISING); } /*****************************************************/ /** Boucle lancée automatiquement après Setup() **/ /*****************************************************/ void loop() { timeRun = millis(); if (timeRun > TicProchainCycle) {// Le tic (temps actuel en millisecondes) a dépassé le tic indiquant qu'il faut changer de cycle // Préparation de la valeur à dépasser pour lancer un prochain cycle de lecture Anemo ou Gestion Serre if (Cycle == 0) { // On est actuellement dans le cycle Anemo // On interdit les interruptions noInterrupts(); TicProchainCycle = timeRun + DureeCycleSerre; // On indique qu'on est maintenant dans le cycle Gestion Serre Cycle = 1; } else {// On est actuellement dans le cycle Gestion Serre TicProchainCycle = timeRun + DureeCycleAnemo; // On indique qu'on est maintenant dans le cycle Lecture Anemo Cycle = 0; // Charge timeLast avec la valeur timeRun, pour indiquer qu'il faut éviter de calculer la vitesse // du vent la premiere fois que le cycle anemo démarre timeLast = timeRun; // On autorise les interruptions Interrupts(); } } if (cycle == 0) {// On est dans le cycle Anemo, ne rien faire } else {// On est dans le cycle interdisant les interruption // Appelle le SP de Gestion de la Serre GereSerre(); } // Appelle à tous les coups le SP d'affichage des informations sur le panel LCD Afficher(); } /***********************************************************/ /** Sous-programme (ISR) appelé par interruption anemo **/ /** (Note : delay() ne peut pas fonctionner à ce niveau) **/ /** Une seule interruption sur 4 est prise en compte **/ /***********************************************************/ void AnemoTicks() { anemoTickCompteur++; if (anemoTickCompteur >= 4) { // Remise à 0 du compteur anemoTickCompteur anemoTickCompteur = 0; if (timeLast == timeRun) { // Ne pas Calculer la valeur du vent ce tour ci (la valeur actuelle du vent est conservée) } else { // Calcul la période et on divise par 1000.0 pour obtenir le résultat en seconde periode = (timeRun - timeLast) / 1000.0; // On initialise timeLast pour préparer le prochaine calcul de la période timeLast = timeRun; // calcul de la vitesse du vent avec la formule // vitesse du vent = rayonBras * 2pi * fréquence (frequence=nb_tour/s) // => résultat en m/s 2 Ticks = 1 tour/ 4 Ticks = 2 tours v_vent = rayonBras * 2 * 3.14 * (4 / periode) * FEtalonage; // Met le resultat en km/h v_vent = v_vent * 3.6; } } } /***********************************************/ /** Affichage des informations sur le PANEL **/ /***********************************************/ void Afficher() { lcd.setCursor(6, 0); // Place le curseur lcd.print(v_vent); // Affiche la valeur de la vitesse du vent lcd.setCursor(7, 1); // Place le curseur ??? Pourquoi faire.... } /***************************************************/ /** Gestion de la Serre (commande l'ouverture et **/ /** la fermeture) **/ /***************************************************/ void GereSerre() { if (v_vent > 27.77) // condition Km/h selon affichage sur l'écran (100/3.6) { // On ferme la serre digitalWrite(RELAY, LOW); // On notifie la fermeture etat_serre = 1; // On mémorise le Tic de fermeture fermeture_serre_tic = timeRun; } else { if (etat_serre == 1) {// La serre a été fermée suite à un vent trop fort if ((timeRun - fermeture_serre_tic) > duree_fermeture_serre ) { // On reouvre la serre préalablement fermée à cause du vent digitalWrite(RELAY, HIGH); // On notifie l'ouverture etat_serre = 0; } else { // On ferme la serre (ou on termine de la fermer) digitalWrite(RELAY, LOW); } } else { // On ouvre la serre digitalWrite(RELAY, HIGH); } } }
Dernière modification par Jack ; 08/02/2021 à 13h14. Motif: Balises code
Faut faire des test...
Sinon, juste pour voir, on peut aussi tenter de faire tourner une des précédentes versions en corrigeant le problème du = et ==
Code:#include <LiquidCrystal.h> int etat_serre =0; // Indicateur d'état de la serre (0 = Ouvert/ 1=fermée) unsigned long fermeture_serre_tic = 0; // tic de fermeture de la serre (le tic c'est "le temps") unsigned long duree_fermeture_serre = 60 * 60000; // Durée max de fermeture de la serre en millisecondes (1 heures) int relaisPin = 3; int anemo = 2; LiquidCrystal lcd(8, 9, 4, 5, 6, 7); // initialisation, on définit les ports pour RS, E et D4 à D7 // Temps en millisecondes depuis lequel le programme tourne // Est déclaré volative pour permettre de transmettre cette valeur de manière fiable // vers une SP de type ISR (SP de type Interruption) volatile unsigned long timeRun; unsigned long timeLast; float periode; const int RELAY = 3; /***************Variables pour la vitesse du vent*****************************/ //declare un var anemo qui = 2 float v_vent = 0.00; //var qui contiendra la vitesse du vent float rayonBras = 0.01; //rayon du bras 9cm => 0.09m int anemoTickCompteur = 0; //variable pour le comptage du nombre de "TICKS" du capteur ILS de l'anemo float FEtalonage = 3.1; unsigned long previousMillis = 0; const unsigned long TimePause = 30 * 60000; const unsigned long TimeMarche = 5 * 60000 ; enum {ARRET, MARCHE} etat; void setup() { lcd.setCursor(0, 0); // Place le c lcd.begin(16, 2); // definit l'écran sur caractères (16) et de lignes (2) delay(100); // Pause lcd.setCursor(1, 0); // Place le cursor lcd.print("initialisation"); // Affiche le message delay(500); // Pause lcd.clear(); // Efface l'écran delay(250); // Pause lcd.print("vent: "); // Affiche texte lcd.setCursor(6, 0); // Place le cursor lcd.print(v_vent); // Affiche la valeur de la vitesse du vent égale à 0.00 au départ lcd.setCursor(11, 0); // Place le cursor lcd.print("km/h"); // Affiche le texte // On initialise les entrées/sorties etat = MARCHE; /********************************************************************* Mise en place des broches avec les fonctions d'interruption *********************************************************************/ pinMode(anemo, INPUT); // On écrit l'état du relais, definit la pin anemo(2) comme une entrée // Dès que la broche anemo(2) changera d'etat (RISING = état BAS vers HAUT (front montant)) on appelle le SP AnemoTicks attachInterrupt(digitalPinToInterrupt(anemo), AnemoTicks, RISING); // On initialise timeLast timeLast = millis(); } /*****************************************************/ /** Boucle lancée automatiquement après Setup() **/ /*****************************************************/ void loop() { // Interdit les interruptions, le temps que la variable timeRun soit chargée // pour éviter que AnemoTicks() soit lancé en plein chargement de la variable noInterrupts(); // Affecte le temps depuis lequel le programme tourne à la variable timeRun timeRun = millis(); // Autorise à nouveau les interruptions Interrupts(); } /***********************************************************/ /** Sous-programme (ISR) appelé par interruption anemo **/ /** (Note : delay() ne peut pas fonctionner à ce niveau) **/ /** Une seule interruption sur 4 est prise en compte **/ /***********************************************************/ void AnemoTicks() { anemoTickCompteur++; if (anemoTickCompteur >= 4) { // Remise à 0 du compteur anemoTickCompteur anemoTickCompteur = 0; // Calcul la période et on divise par 1000.0 pour obtenir le résultat en seconde periode = (timeRun - timeLast) / 1000.0; // On initialise timeLast pour préparer le prochaine calcul de la période timeLast = timeRun; // calcul de la vitesse du vent avec la formule // vitesse du vent = rayonBras * 2pi * fréquence (frequence=nb_tour/s) // => résultat en m/s 2 Ticks = 1 tour/ 4 Ticks = 2 tours v_vent = rayonBras * 2 * 3.14 * (4 / periode) * FEtalonage; // Met le resultat en km/h v_vent = v_vent * 3.6; // Appelle le SP d'affichage des informations surle panel LCD Afficher(); // Appelle le SP de Gestion de la Serre GereSerre(); } } /***********************************************/ /** Affichage des informations sur le PANEL **/ /***********************************************/ void Afficher() { lcd.setCursor(6, 0); // Place le cursor lcd.print(v_vent); // Affiche la valeur de la vitesse du vent lcd.setCursor(7, 1); // Place le cursor pinMode( 3, OUTPUT); // Prépare l'activation du relai relié au PIN 3 } /***************************************************/ /** Gestion de la Serre (commande l'ouverture et **/ /** la fermeture) **/ /***************************************************/ void GereSerre() { if (v_vent > 27.77) // condition Km/h selon affichage sur l'écran (100/3.6) { // On ferme la serre digitalWrite(RELAY, LOW); // On notifie la fermeture etat_serre = 1; // On mémorise le Tic de fermeture fermeture_serre_tic = timeRun; } else { if (etat_serre == 1) { // La serre a été fermée suite à un vent trop fort if ((timeRun - fermeture_serre_tic) > duree_fermeture_serre ) { // On reouvre la serre préalablement fermée à cause du vent digitalWrite(RELAY, HIGH); // On notifie l'ouverture etat_serre = 0; } else { // On ferme la serre (ou on termine de la fermer) digitalWrite(RELAY, LOW); } } else { // On ouvre la serre digitalWrite(RELAY, HIGH); } } }
Je viens de voir que la fonction millis() fonctionnait par interruption.
C'est donc une très mauvaise idée d'interdire les interruptions si on veut obtenir une valeur...
J'ai modifié le code en conséquence :
A voir si ça règle le problème.Code:#include <LiquidCrystal.h> int etat_serre = 0; // Indicateur d'état de la serre (0 = Ouvert/ 1=fermée) unsigned long fermeture_serre_tic = 0; // tic de fermeture de la serre (le tic c'est "le temps") unsigned long duree_fermeture_serre = 60 * 60000; // Durée max de fermeture de la serre en millisecondes (1 heure) // On démarre par le cycle Serre (donc on initialise avec la valeur Anemo... pour switcher tout de suite vers le cycle Serre) int cycle = 0; // Indicateur de Cycle, 0=Cycle gestion Anemo, 1=Cycle gestion Serre usigned long TicProchainCycle = 0; // "Temps" précalculé à atteindre pour changer de Cycle unsigned long DureeCycleSerre = 30000; // Durée du Cycle Serre 30 Secondes unsigned long DureeCycleAnemo = 15000; // Durée du Cycle Anemomètre 15 Secondes int relaisPin = 3; int anemo = 2; // initialisation, on définit les ports pour RS, E et D4 à D7 LiquidCrystal lcd(8, 9, 4, 5, 6, 7); // Temps en millisecondes depuis lequel le programme tourne // Est déclaré volative pour permettre de transmettre cette valeur de manière fiable // vers une SP de type ISR (SP de type Interruption) volatile unsigned long timeRun; // Employé pour calculer l'interval de temps entre deux appels à la routine AnemoTicks() volatile unsigned long timeLast; float periode; const int RELAY = 3; /***************Variables pour la vitesse du vent*****************************/ float v_vent = 0.00; //var qui contiendra la vitesse du vent float rayonBras = 0.01; //rayon du bras 9cm => 0.09m int anemoTickCompteur = 0; //variable pour le comptage du nombre de "TICKS" du capteur ILS de l'anemo float FEtalonage = 3.1; /*************************************************************************/ /* Lancé automatiquement, avant loop(),au démarrage du programme */ /*************************************************************************/ void setup() { // Definit l'écran sur caractères (16) et de lignes (2) lcd.begin(16, 2); lcd.setCursor(0, 0); // Place le curseur delay(100); // Pause lcd.setCursor(1, 0); // Place le curseur lcd.print("initialisation"); // Affiche le message delay(500); // Pause lcd.clear(); // Efface l'écran delay(250); // Pause lcd.print("vent: "); // Affiche le texte lcd.setCursor(6, 0); // Place le curseur lcd.print(v_vent); // Affiche la valeur de la vitesse du vent égale à 0.00 au départ lcd.setCursor(11, 0); // Place le curseur lcd.print("km/h"); // Affiche le texte /***************************************************************/ /* Mise en place des broches avec les fonctions d'interruption */ /***************************************************************/ pinMode(anemo, INPUT); // On écrit l'état du relais, definit la pin anemo(2) comme une entrée pinMode(relaisPin, OUTPUT); // Prépare l'activation du relai relié au PIN 3 // Dès que la broche anemo(2) changera d'etat (RISING = état BAS vers HAUT (front montant)) // on appelle le SP AnemoTicks attachInterrupt(digitalPinToInterrupt(anemo), AnemoTicks, RISING); } /*****************************************************/ /** Boucle lancée automatiquement après Setup() **/ /*****************************************************/ void loop() { timeRun = millis(); if (timeRun > TicProchainCycle) {// Le tic (temps actuel en millisecondes) a dépassé le tic indiquant qu'il faut changer de cycle // Préparation de la valeur à dépasser pour lancer un prochain cycle de lecture Anemo ou Gestion Serre if (Cycle == 0) { // On est actuellement dans le cycle Anemo TicProchainCycle = timeRun + DureeCycleSerre; // On indique qu'on est maintenant dans le cycle Gestion Serre Cycle = 1; } else {// On est actuellement dans le cycle Gestion Serre TicProchainCycle = timeRun + DureeCycleAnemo; // On indique qu'on est maintenant dans le cycle Lecture Anemo Cycle = 0; // Charge timeLast avec la valeur timeRun, pour indiquer qu'il faut éviter de calculer la vitesse // du vent la premiere fois que le cycle anemo démarre timeLast = timeRun; } } if (cycle == 0) {// On est dans le cycle Anemo, ne rien faire } else {// On est dans le cycle Gestion de Serre // Appelle le SP de Gestion de la Serre GereSerre(); } // Appelle à tous les coups le SP d'affichage des informations sur le panel LCD Afficher(); } /***********************************************************/ /** Sous-programme (ISR) appelé par interruption anemo **/ /** (Note : delay() ne peut pas fonctionner à ce niveau) **/ /** Une seule interruption sur 4 est prise en compte **/ /***********************************************************/ void AnemoTicks() { anemoTickCompteur++; if (anemoTickCompteur >= 4) { // Remise à 0 du compteur anemoTickCompteur anemoTickCompteur = 0; if (timeLast == timeRun) { // Ne pas Calculer la valeur du vent ce tour ci (la valeur actuelle du vent est conservée) } else { // Calcul la période et on divise par 1000.0 pour obtenir le résultat en seconde periode = (timeRun - timeLast) / 1000.0; // On initialise timeLast pour préparer le prochaine calcul de la période timeLast = timeRun; // calcul de la vitesse du vent avec la formule // vitesse du vent = rayonBras * 2pi * fréquence (frequence=nb_tour/s) // => résultat en m/s 2 Ticks = 1 tour/ 4 Ticks = 2 tours v_vent = rayonBras * 2 * 3.14 * (4 / periode) * FEtalonage; // Met le resultat en km/h v_vent = v_vent * 3.6; } } } /***********************************************/ /** Affichage des informations sur le PANEL **/ /***********************************************/ void Afficher() { lcd.setCursor(6, 0); // Place le curseur noInterrupts(); // Empeche l'interruption puisque v_vent peut changer via une interruption lcd.print(v_vent); // Affiche la valeur de la vitesse du vent Interrupts(); // Permet à nouvau les interruptions } /***************************************************/ /** Gestion de la Serre (commande l'ouverture et **/ /** la fermeture) **/ /***************************************************/ void GereSerre() { if (v_vent > 27.77) // condition Km/h selon affichage sur l'écran (100/3.6) { // On ferme la serre digitalWrite(RELAY, LOW); // On notifie la fermeture etat_serre = 1; // On mémorise le Tic de fermeture fermeture_serre_tic = timeRun; } else { if (etat_serre == 1) {// La serre a été fermée suite à un vent trop fort if ((timeRun - fermeture_serre_tic) > duree_fermeture_serre ) { // On reouvre la serre préalablement fermée à cause du vent digitalWrite(RELAY, HIGH); // On notifie l'ouverture etat_serre = 0; } else { // On ferme la serre (ou on termine de la fermer) digitalWrite(RELAY, LOW); } } else { // On ouvre la serre digitalWrite(RELAY, HIGH); } } }
Bjr,BrainMan,
çà y est, çà fonctionne, excellent, je le remet dans le forum (car un faute de Maj)comme çà s'a pourra aider d'autre.En attendant encore un grand merci, et aussi merci de votre patience.Peut-être à bientôt,en attendant prenez bien soin de vous
Code HTML:#include <LiquidCrystal.h> int etat_serre = 0; // Indicateur d'état de la serre (0 = Ouvert/ 1=fermée) unsigned long fermeture_serre_tic = 0; // tic de fermeture de la serre (le tic c'est "le temps") unsigned long duree_fermeture_serre = 1 * 60000; // Durée max de fermeture de la serre en millisecondes (1 heures) int relaisPin = 3; int anemo = 2; LiquidCrystal lcd(8, 9, 4, 5, 6, 7); // initialisation, on définit les ports pour RS, E et D4 à D7 // Temps en millisecondes depuis lequel le programme tourne // Est déclaré volative pour permettre de transmettre cette valeur de manière fiable // vers une SP de type ISR (SP de type Interruption) volatile unsigned long timeRun; unsigned long timeLast; float periode; const int RELAY = 3; /***************Variables pour la vitesse du vent*****************************/ //declare un var anemo qui = 2 float v_vent = 0.00; //var qui contiendra la vitesse du vent float rayonBras = 0.01; //rayon du bras 9cm => 0.09m int anemoTickCompteur = 0; //variable pour le comptage du nombre de "TICKS" du capteur ILS de l'anemo float FEtalonage = 3.1; unsigned long previousMillis = 0; const unsigned long TimePause = 30 * 60000; const unsigned long TimeMarche = 5 * 60000 ; enum {ARRET, MARCHE} etat; void setup() { lcd.setCursor(0, 0); // Place le c lcd.begin(16, 2); // definit l'écran sur caractères (16) et de lignes (2) delay(100); // Pause lcd.setCursor(1, 0); // Place le cursor lcd.print("initialisation"); // Affiche le message delay(500); // Pause lcd.clear(); // Efface l'écran delay(250); // Pause lcd.print("vent: "); // Affiche texte lcd.setCursor(6, 0); // Place le cursor lcd.print(v_vent); // Affiche la valeur de la vitesse du vent égale à 0.00 au départ lcd.setCursor(11, 0); // Place le cursor lcd.print("km/h"); // Affiche le texte // On initialise les entrées/sorties etat = MARCHE; /********************************************************************* Mise en place des broches avec les fonctions d'interruption *********************************************************************/ pinMode(anemo, INPUT); // On écrit l'état du relais, definit la pin anemo(2) comme une entrée // Dès que la broche anemo(2) changera d'etat (RISING = état BAS vers HAUT (front montant)) on appelle le SP AnemoTicks attachInterrupt(digitalPinToInterrupt(anemo), AnemoTicks, RISING); // On initialise timeLast timeLast = millis(); } /*****************************************************/ /** Boucle lancée automatiquement après Setup() **/ /*****************************************************/ void loop() { // Interdit les interruptions, le temps que la variable timeRun soit chargée // pour éviter que AnemoTicks() soit lancé en plein chargement de la variable noInterrupts(); // Affecte le temps depuis lequel le programme tourne à la variable timeRun timeRun = millis(); // Autorise à nouveau les interruptions interrupts(); } /***********************************************************/ /** Sous-programme (ISR) appelé par interruption anemo **/ /** (Note : delay() ne peut pas fonctionner à ce niveau) **/ /** Une seule interruption sur 4 est prise en compte **/ /***********************************************************/ void AnemoTicks() { anemoTickCompteur++; if (anemoTickCompteur >= 4) { // Remise à 0 du compteur anemoTickCompteur anemoTickCompteur = 0; // Calcul la période et on divise par 1000.0 pour obtenir le résultat en seconde periode = (timeRun - timeLast) / 1000.0; // On initialise timeLast pour préparer le prochaine calcul de la période timeLast = timeRun; // calcul de la vitesse du vent avec la formule // vitesse du vent = rayonBras * 2pi * fréquence (frequence=nb_tour/s) // => résultat en m/s 2 Ticks = 1 tour/ 4 Ticks = 2 tours v_vent = rayonBras * 2 * 3.14 * (4 / periode) * FEtalonage; // Met le resultat en km/h v_vent = v_vent * 3.6; // Appelle le SP d'affichage des informations surle panel LCD Afficher(); // Appelle le SP de Gestion de la Serre GereSerre(); } } /***********************************************/ /** Affichage des informations sur le PANEL **/ /***********************************************/ void Afficher() { lcd.setCursor(6, 0); // Place le cursor lcd.print(v_vent); // Affiche la valeur de la vitesse du vent lcd.setCursor(7, 1); // Place le cursor pinMode( 3, OUTPUT); // Prépare l'activation du relai relié au PIN 3 } /***************************************************/ /** Gestion de la Serre (commande l'ouverture et **/ /** la fermeture) **/ /***************************************************/ void GereSerre() { if (v_vent > 25) // condition Km/h selon affichage sur l'écran (100/3.6) { // On ferme la serre digitalWrite(RELAY, LOW); // On notifie la fermeture etat_serre = 1; // On mémorise le Tic de fermeture fermeture_serre_tic = timeRun; } else { if (etat_serre == 1) { // La serre a été fermée suite à un vent trop fort if ((timeRun - fermeture_serre_tic) > duree_fermeture_serre ) { // On reouvre la serre préalablement fermée à cause du vent digitalWrite(RELAY, HIGH); // On notifie l'ouverture etat_serre = 0; } else { // On ferme la serre (ou on termine de la fermer) digitalWrite(RELAY, LOW); } } else { // On ouvre la serre digitalWrite(RELAY, HIGH); } } }