3 temporisations avec fonction Millis

Bonjour,

J’ai 3 temporisations avec fonction Millis

Interval_Moniteur = 5000 (Attente 5 secs lecture moniteur série) OK
Interval_Arrosage = 30000 (Attente 30 secs entre arrosage) OK la 1er fois, puis plus après
Ouverture_Vanne = 15000 (15 secs, ouverture vanne, puis OFF) Ne fonctionne pas, ça fait discothèque, passe de ON /OFF toutes les 5 secs

C’est comme si les compteurs Vanne et Arrosage ne se remettais pas à zéro

Merci

//
const int pinA1 = A7;                  // Pin Analogique du capteur (A3 Ardiono Mini/Pro, A7 Arduino Nano)
const int Relay = 2;                   // Pin Relay (électrovanne)
const int Sensor = 3;                  // Pin d'alimentation du Capteur Moisture 
const int Bouton = 4;                  // Broche où on lira la valeur renvoyée par le capteur
const int LedVert = 5;                 // Led Verte (Arrosages ON)
const int LedRouge = 6;                // Led Rouge (Arrosages OFF)

//
byte EtatBouton;                    // Variable où on stockera l'état du bouton 
byte EtatVanne;                     // Variable où on stockera l'état Vanne 

//
unsigned long Interval_Arrosage = 30000;    // Temps d'attente entre les arrosages 60000
unsigned long Ouverture_Vanne = 15000;      // Temps d’ouverture Vanne en millisecondes
unsigned long Interval_Moniteur = 5000;     // Temps d'attente entre les lecture Moniteur (Sonde non active)

//
unsigned long Compteur_Arrosage = 0 ;    // Compteur de Temps en millisecondes
unsigned long Compteur_Vanne = 0 ;       // Compteur de Temps en millisecondes
unsigned long Compteur_Moniteur = 0 ;    // Compteur de Temps en millisecondes

//
void setup() 
{
 Serial.begin(9600);
 pinMode(pinA1,INPUT);
 pinMode(Relay,OUTPUT);
 pinMode(Sensor,OUTPUT);
 pinMode(Bouton,INPUT);          //On créé une entrée : on reçoit l'état du bouton
 pinMode(LedVert,OUTPUT); 
 pinMode(LedRouge,OUTPUT);  
}

//
void loop() {  
//Action     
byte EtatBouton = digitalRead(Bouton);           // Déclartation variable boolean état du bouton 
EtatVanne = digitalRead(Relay);           // NEW
digitalWrite(Sensor,HIGH);
float h=analogRead(pinA1);
float taux = (1023.0-h)/6.45;                      // 6.65; (My valeur 6.45 capeur Non isoler;) (Tester avec 9.10) 3.50 New sonde
if((millis() - Compteur_Moniteur) > Interval_Moniteur) { 
Compteur_Moniteur = millis(); 
// delay(5000);                                       // Donner suffisamment de temps pour ouvrir le moniteur série après le téléchargement
Serial.println("Starting...");
Serial.print(h);
Serial.print("     ");
Serial.print(taux);
Serial.println("%");
Serial.print("Arrosage ON(0)/OFF(1)");
Serial.print(" ");
Serial.println(EtatVanne); 
Serial.print("Bouton   ON(0)/OFF(1)");
Serial.print(" ");
Serial.println(EtatBouton); 
Arrosage(taux);
digitalWrite(Sensor,LOW);     
// End of Action
}}

//
void Arrosage(float taux)                                 // Définir Fonction
{
   
   EtatBouton = digitalRead(Bouton);                      // On lit l'état du bouton

      EtatVanne = digitalRead(Relay);  
    
   
//-------------------- Arrosage ON ----------------         
      if ((millis() - Compteur_Arrosage) > Interval_Arrosage) {       
      Compteur_Arrosage++; // On incrémente le compteur
      digitalWrite(Relay,LOW);
      digitalWrite(LedVert,HIGH);                        // Allumage Led Vert
      digitalWrite(LedRouge,LOW);    
      Compteur_Arrosage = millis();
      Compteur_Vanne = millis();
      Compteur_Vanne = 0; // On remet à zéro pour refaire le cycle de la fonction
      }
//-------------------- Arrosage OFF ---------------- 
      else { ((millis() - Compteur_Vanne) > Ouverture_Vanne);   // Fermeture vanne               
      Compteur_Vanne++; // On incrémente le compteur                                  
      digitalWrite(Relay,HIGH);
      digitalWrite(LedVert,LOW);
      digitalWrite(LedRouge,HIGH);                      // Allumage Led Rouge             
      Compteur_Vanne = millis();
      Compteur_Arrosage = millis();
      Compteur_Arrosage = 0; // On remet à zéro pour refaire le cycle de la fonction (OK)
      } 
}

Bonjour

Désolé mais ce code est truffé d'incohérences. Il n'y a aucune chance qu'il corresponde à ce que tu souhaites faire, souhait qui n'est d'ailleurs pas clair.

Rien que là par exemple :

      else { ((millis() - Compteur_Vanne) > Ouverture_Vanne);   // Fermeture vanne               
      Compteur_Vanne++; // On incrémente le compteur                                 
      digitalWrite(Relay,HIGH);
      digitalWrite(LedVert,LOW);
      digitalWrite(LedRouge,HIGH);                      // Allumage Led Rouge             
      Compteur_Vanne = millis();      
      Compteur_Arrosage = millis();
      Compteur_Arrosage = 0; // On remet à zéro pour refaire le cycle de la fonction (OK)
      }
  1. tu voulais peut-être mettre else if ?
  2. à quoi sert Compteur_Vanne++, sachant que derrière il est remis à millis ?
  3. Compteur_Arrosage déjà mis à jour précédemment, et remis à jour ici avec une affecation à millis inutile

Et aussi :

  1. une fonction Arrosage() qui prend en paramètre un float taux dont elle ne fait rien
  2. un bouton dont l'état est lu mais jamais utilisé pour déclencher telle ou telle action

Bref, je t'invite à commence par exprimer en français tout simple mais de manière précise, ce que le système est censé faire.
Une fois ceci clarifié, la programmation suivra

A la lecture du code, je pense avoir compris ta principale erreur d'approche.

Le code s'exécute beaucoup beaucoup plus vite que ton processus.
Tu dois appréhender le fait que la fonction loop() est une boucle infinie, qui s'exécute plusieurs centaines de milliers de fois par seconde.

Dans ton approche, on a l'impression d'une seule loop() descend en séquence la totalité du processus qui dure peut-être une minute. Et du coup, tu impriques tes if comme des enchaînements d'états logiques.
Cette approche est erronée. Il faut penser que la fonction loop() est exécutée un très grand nombre de fois pour un seul cycle de ton processus.

Ainsi par exemble :

void loop(){
  if (condition1) {
    traitement1();
  }
  if (condition2) {
    traitement2();
  }
}

Une telle fonction loop() ne fait rien dans 99,99% des itérations
Mais une fois de temps en temps, elle déclenche le traitement1 ou le traitement2, et rarement les deux traitements à la suite dans la même itération.
D'ailleurs on peut tout aussi bien coder

void loop(){
  if (condition2) {
    traitement2();
  }
  if (condition1) {
    traitement1();
  }
}

et cela produira le même résultat.

Oui mon code est incomplet car j’avais supprimé des données pour me concentrer uniquement sur les différents tempos avec millis

Oui, je me mélange les pinceaux, avec certaines fonctions, et je prends des bouts de codes que je trouve pour tester. D’où le Compteur_Vanne++, je vais supprimer merci pour l’info

Mon montage doit faire :

Dès le démarrage

  • Led Rouge + Vanne OFF (Pour l’instant (Pas de Led + vanne ON), il n’est pris en compte qu’après 5 secs, 1er affichage moniteur série, Led Rouge + Vanne OFF OK)

  • Interdiction de démarrer l’arrosage temps que (Interval_Arrossage) n’est pas écoulé

  • Si taux < 10

  • Ou Si bouton presser
    – Arrosage ON –

  • Si temps (Ouverture_Vanne) dépasser

  • Ou si taux > 90
    – Arrosage OFF –

Phase d’arrosage : Lorsque temps (Ouverture_Vanne) 15 secs est dépassé on passe à arrosage OFF, une fois (Interval_Arrossage) dépassé on passe à arrosage ON, on passe entre c’est 2 états jusqu’à atteindre taux > 90.

Phase assèchement : Temps que taux n’est pas < 10 pas d’arrosage possible. Sauf si bouton presser, on passe sur Phase Arrosage ON

Mon montage pièce jointe : Arduino Mini Pro Shema.jpg

Mon code de base, complet sans millis

// -------------------- Arrosages Plante N°1 -------------------- 

//////////////////////////////////////////////////////////////////////////// Declaration des variables ////////////////////////////////////////////////////////////////////////////
// Variables Constantes : Ne change pas.
// Utilisé le numéro de la broche sur laquelle est connectée le capteur pour le définir :
//
const int pinA1 = A7;                  // Pin Analogique du capteur (A3 Ardiono Mini/Pro, A7 Arduino Nano)
const int Ralay = 2;                   // Pin Relay (électrovanne)
const int Sensor = 3;                  // Pin d'alimentation du Capteur Moisture 
const int Bouton = 4;                  // Broche où on lira la valeur renvoyée par le capteur
const int LedVert = 5;                 // Led Verte (Arrosages ON)
const int LedRouge = 6;                // Led Rouge (Arrosages OFF)

// Variables : Qui change
//
boolean EtatBouton;                    // Variable où on stockera l'état du bouton 
boolean EtatVanne;                     // Variable où on stockera l'état Vanne 

// En général, vous devez utiliser "unsigned long" pour les variables qui maintiennent le temps
// La valeur deviendra rapidement trop grand pour un int pour stocker
// Variables Constantes Longue : Ne change pas.
//
unsigned long Interval_Arrosage = 30000;    // Temps d'attente entre les arrosages 60000
unsigned long Ouverture_Vanne = 15000;      // Temps d’ouverture Vanne en millisecondes

// Variables Longue : Qui change 
//
unsigned long Compteur_Arrosage = 0 ;    // Compteur de Temps en millisecondes
unsigned long Compteur_Vanne = 0 ;       // Compteur de Temps en millisecondes
///////////////////////////////////////////////////////////////////////////////// Initialisation //////////////////////////////////////////////////////////////////////////////////
//

void setup() 
{
 Serial.begin(9600);
 pinMode(pinA1,INPUT);
 pinMode(Ralay,OUTPUT);
 pinMode(Sensor,OUTPUT);
 pinMode(Bouton,INPUT);          //On créé une entrée : on reçoit l'état du bouton
 pinMode(LedVert,OUTPUT); 
 pinMode(LedRouge,OUTPUT);  
}


/////////////////////////////////////////////////////////////////////////////// Boucle Principale /////////////////////////////////////////////////////////////////////////////////
//
void loop() {  
//Action     
boolean EtatBouton = digitalRead(Bouton);           // Déclartation variable boolean état du bouton 
digitalWrite(Sensor,HIGH);
float h=analogRead(pinA1);
float taux = (1023.0-h)/6.00;                      // 6.65; (My valeur 6.45 capeur Non isoler;) (Tester avec 9.10) 3.50 New sonde
delay(5000);                                       // Donner suffisamment de temps pour ouvrir le moniteur série après le téléchargement
Serial.println("Starting...");
Serial.print(h);
Serial.print("     ");
Serial.print(taux);
Serial.println("%");
Serial.print("Arrosage ON(0)/OFF(1)");
Serial.print(" ");
Serial.println(EtatVanne); 
Serial.print("Bouton   ON(0)/OFF(1)");
Serial.print(" ");
Serial.println(EtatBouton); 
Arrosage(taux);
digitalWrite(Sensor,LOW);     
// End of Action
}
///////////////////////////////////////////////////////////////////////////// Fonction Personnalisée //////////////////////////////////////////////////////////////////////////////
//
//------------------------------- Programme Principale ------------------------------- 
//
void Arrosage(float taux)                                 // Définir Fonction
{

  
   EtatBouton = digitalRead(Bouton);                      // On lit l'état du bouton
   boolean EtatVanne = digitalRead(EtatVanne);            // Control Vanne ON/OFF
  
      if (EtatBouton==0 || taux < 10) {                   // Si fouchette taux arrosage ON  
      Arrosage_ON(taux);                                  // Exécute Sous Programme
      }
      if (taux > 70) {                                    // Si taux haut atteint
      Arrosage_OFF(taux);                                 // Exécute Sous Programme
      }
}
//--------------------------- Sous Programme Arrosage ON --------------------------- 
//
void Arrosage_ON(float taux)                                  // Définir Fonction
{

           
          digitalWrite(Ralay,LOW);
          digitalWrite(LedVert,HIGH);                         // Allumage Led Vert
          digitalWrite(LedRouge,LOW);  

          if (taux > 70) {                               // Si taux haut atteint 
          Arrosage_OFF(taux);                                 // Exécute Sous Programme
          }
}
   

//-------------------------- Sous Programme Arrosage OFF -------------------------- 
//
void Arrosage_OFF(float taux)                                // Définir Fonction
{

     
 
          digitalWrite(Ralay,HIGH);
          digitalWrite(LedVert,LOW);
          digitalWrite(LedRouge,HIGH);                      // Allumage Led Rouge  

          if (taux < 10) {                             // Si taux bas atteint
          Arrosage_ON(taux);                                // Exécute Sous Programme
          }
}
/////////////////////////////////////////////////////////////////////////////////////// FIN ///////////////////////////////////////////////////////////////////////////////////////

Je vais reprendre mon code de base, si j’ai bien compris Ouverture_vanne se met en conflit, j’ai voulu faire trop simplifier

Merci pour ton aide :wink:

Rapidement, voilà un bout de code qui pourrait correspondre, éventuellement à ajuster (même pas compilé)

La fonction loop() est particulièrement compréhensible. L’important, au travers de cet exemple, c’est de comprendre l’approche générale de structuration des lignes de code, qui doit être le plus proche possible de la logique du système telle qu’exprimée en langage naturel.

J’y a ai juste laissé les manipulations liées à la fonction millis(), pour bien illustrer son utilisation.

const int pinA1 = A7;                  // Pin Analogique du capteur (A3 Ardiono Mini/Pro, A7 Arduino Nano)
const int Relay = 2;                   // Pin Relay (électrovanne)
const int Sensor = 3;                  // Pin d'alimentation du Capteur Moisture
const int Bouton = 4;                  // Broche où on lira la valeur renvoyée par le capteur
const int LedVert = 5;                 // Led Verte (Arrosages ON)
const int LedRouge = 6;                // Led Rouge (Arrosages OFF)

unsigned long millis_display = 0;
unsigned long millis_taux = 0;
unsigned long millis_arrosage = 0;
float taux = 50.0;//valeur d'init sans importance
bool arrosage_en_cours = false;

void setup()
{
  Serial.begin(9600);
  pinMode(pinA1,INPUT);
  pinMode(Relay,OUTPUT);
  pinMode(Sensor,OUTPUT);
  pinMode(Bouton,INPUT);//cablage?
  pinMode(LedVert,OUTPUT);
  pinMode(LedRouge,OUTPUT); 
}

void loop()
{
  //Toutes les 5 secondes, afficher les infos
  if (millis() - millis_display > 5000)
  {
      afficherInfos();
      millis_display = millis();
  }
  
  //Chaque seconde, lire le taux d'humidité
  if (millis() - millis_taux > 1000)
  {
      lireTaux();
      millis_taux = millis();
  }
  
  //Et maintenant les actions
  if (arrosage_en_cours)
  {
    bool trop_humide = (taux > 90.0);
    unsigned long duree_arrosage = millis() - millis_arrosage;  
    bool duree_max_arrosage_atteinte = (duree_arrosage > 15000);    
    if (trop_humide || duree_max_arrosage_atteinte)
    {
      arreterArrosage();
      millis_arrosage = millis();
    }
  }
  else
  {
    bool trop_sec = (taux < 10.0);
    bool bouton_enfonce = (digitalRead(Bouton) == LOW);//ou HIGH, selon cablage
    unsigned long duree_arret = millis() - millis_arrosage;  
    bool duree_minimum_arret_respectee = (duree_arret > 30000);     
    
    if (duree_minimum_arret_respectee && (bouton_enfonce || trop_sec))
    {
      demarrerArrosage();
      millis_arrosage = millis();
    }
  }
}

void afficherInfos()
{
    //uniquement des Serial.print
}

void lireTaux()
{
  float h = analogRead(pinA1);
  taux = (1023.0-h)/6.45;   
}

void demarrerArrosage()
{
  digitalWrite(Relay,LOW);
  digitalWrite(LedVert,HIGH);
  digitalWrite(LedRouge,LOW);
  arrosage_en_cours = true;  
}

void arreterArrosage()
{
  digitalWrite(Relay,HIGH);
  digitalWrite(LedVert,LOW);
  digitalWrite(LedRouge,HIGH);
  arrosage_en_cours = false;  
}

Whoaw, un très grand merci pour t'as réponse.

J'avais pas compris qu'il fallait faire des sous groupe comme cela, j’essayais de condenser tous a la même place pour faire le moins de code possible, pas bonne idée finalement.

Encore merci, je teste ça