Arrosage auto avec esp8266 "PROTECTION"

Bonjour à tous.

Donc j'avais comme projet automatique le plus simple possible donc je me suis inspiré de plusieurs codes et on m'a aidé à faire une partie.

Pour le moment tout fonctionne sauf que j'aimerais ajouter une partie "protection".

Je m'explique :
-On branche à un pot de fleur
-0n paramètre à quel moment on trouve que la Terre est sèche
-Donc la pompe s'actionne

j'ai mis comme temporisation "3sec" d'activation,"10sec" pour laisser l'eau pénétrer dans la terre et en cas de besoin réactiver la pompe "3sec" et ainsi de suite et le tous répété 10 fois

le code réamorce un temps programmer avant une autre vérification.

Donc pour le moment tout est très bien sauf que le problème c'est que si le tuyau pour X raison se situe plus dans le pot ça va créer un souci et du coup ça va continuer jusqu'à vider complètement le réservoir où se situe la pompe.

Il faudrait ajouté une commande " protection"

J'aimerais ajouter une sécurité , du genre :

  • Apres X cycle si le taux n"as pas ou très peu changer ( signe de problème ), le systeme se coupe automatiquement et'il ne relance pas la temporisation.

Limite un affichage "ALERTE PROBLÈME"sur le lcd.

Donc ma question est-ce que c'est possible à faire et est-ce que c'est compliqué.

Je suis débutant et un simple code comme celui m'a pris plusieurs semaines mais je me rends compte qu'on veut toujours plus une fois toucher au codage 8)

///////////////////////LCD NE PAS TOUCHER ////////////////////////////
#include <Wire.h>
#include <hd44780.h>                       
#include <hd44780ioClass/hd44780_I2Cexp.h> 
const int LCD_COLS = 20;
const int LCD_ROWS = 4;
hd44780_I2Cexp lcd; 
int status;
///////////////////////LCD NE PAS TOUCHER ////////////////////////////



  int ValeurPourcentageA0 = A0;                 //Sonde1 pin A0

///////////////////////SONDE 1////////////////////////
  const int ValeursecheA0 = 673;              //CHANGER de valeur haute humide apres test
  const int ValeurhumideA0 = 308;             //CHANGER Valeur base seche apres test
  int RelaydigitalPinD5 = D5;                 // PIN D4 pour le relais
  int SondeanalogPinA0 = A0;                  // PIN A0 pour le capteur de l’humidité du sol
  int SondedigitalValA0;                      // Lecture de la sonde
  int RelayanalogValD5;                       // lecture du relay
  int EtathumiditeS1 = 0;
/////////////////////////////////////SONDE 1////////////

/////////////////////////////////////Valeur parametrable////////////////
  int seuil_alerte = 550;                     //CHANGER VALEUR (450) // Comprit entre 500(SEC) et 250(TREMPER)
  long delayattentesec = 10;                  //CHANGER VALEUR (ex 30sec) N°de seconde entre chaque verifications du taux humidité (Parametre reglabe en seconde)
  int nbcontrol = 10;                         //CHANGER VALEUR (10sec) N° de control effectué pendant humidification
  int delayattenteentrearrosagesec = 10;      //CHANGER VALEUR (10sec) Delai attente entre arrosages
  int tempsactivepompesec = 3;                //CHANGER VALEUR (3sec) Temps activation de la pompe en seconde
/////////////////////////////////////Valeur parametrable////////////////

/////////////////////////////////////Convertion/////////////////////////
  int delayattenteentrearrosagemills = delayattenteentrearrosagesec*1000;
  int tempsactivepompemills = tempsactivepompesec*1000;
  long compteurtemps = 0 ;
  int nbcontrolcompteur = 0;
/////////////////////////////////////Convertion /////////////////////////

void setup()  
{

///////////////////////LCD NE PAS TOUCHER ////////////////////////////
  Serial.begin(9600); 
   lcd.begin(20,4); 

///////////////////////LCD ////////////////////////////

///////////////////////////////////////RELAY1///////////////////
  pinMode(RelaydigitalPinD5, OUTPUT);
  digitalWrite(RelaydigitalPinD5, HIGH);
////////////////////////////////////////RELAY1//////////////////
}
void loop()   {

  
///////////////////////Olivier////////////////////////////
////////////Convertion en %/////////////// 
  int ValeurPourcentageA0 = A0;
  ValeurPourcentageA0 = map (analogRead(SondeanalogPinA0), ValeursecheA0, ValeurhumideA0, 0, 100); //map(valeur, deValeurbasse, deValeurHaute, versValeurBasse, vers ValeurHaute);
  Serial.print("Sonde 1 : ");  Serial.println(analogRead(A0)); 
  delay(200); //delai entre deux mesure
  
  lcd.setCursor(10,0);
  lcd.print(ValeurPourcentageA0);
  /*Serial.print("Valeur analogique :");
  Serial.println(RelayanalogValD4);
  Serial.print("Valeur % :");
  Serial.println(ValeurPourcentageA0);
  */
///////////////////////Olivier ////////////////////////////

///////////////////////LCD ////////////////////////////
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("Olivier");
  lcd.setCursor(7,0);
  lcd.print(ValeurPourcentageA0);
  lcd.setCursor(9,0);
  lcd.print("%");
  

  delay(800); //delai entre deux mesure
  
///////////////////////LCD  ////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////Bloc timer+pome a ne pas séparer
///////////////////////Timer POMPE 1////////////////////////////
  if(delayattentesec > compteurtemps){
    compteurtemps++;
    Serial.print("Secondes écoulées avant le prochain test : ");
    Serial.println(compteurtemps);
    
  }
  
  if((delayattentesec <= compteurtemps)&&(nbcontrolcompteur<=nbcontrol)){
     Serial.println("----------CONTROLE D'HUMIDITE----------");
     nbcontrolcompteur++; 
     lcd.clear();
     lcd.setCursor(0,0);
     lcd.print("CONTROLE D'HUMIDITE");
     lcd.setCursor(6,1);

     Serial.print("Cycle : ");
     Serial.println(nbcontrolcompteur);
     pompe1(); 
 
     if (EtathumiditeS1==0){
     delay(delayattenteentrearrosagemills); 
     }  
  }
  
  if (EtathumiditeS1==1){
   nbcontrolcompteur = 10; 
  }
  
  if((delayattentesec <= compteurtemps)&&(nbcontrolcompteur>=nbcontrol)){
     nbcontrolcompteur = 0;
     compteurtemps = 0;
     EtathumiditeS1 = 0;                  //Ajout sonde (EX : EtathumiditeS3 = 0 )

  }
}


///////////////////////Timer POMPE 1////////////////////////////
void pompe1(){
///////////////////////POMPE 1////////////////////////////
 RelayanalogValD5 = analogRead(SondeanalogPinA0);       //lire la valeur retournée par le capteur de l’humidité


 if (RelayanalogValD5>seuil_alerte){                    
  Serial.println("HUMIDITE   BASSE");
  Serial.println("Pompe ON");
  
 
  lcd.setCursor(2, 2);
  lcd.print("ARROSAGE EN COUR");
  lcd.setCursor(5, 3);
  lcd.print("Cycle :");
  lcd.setCursor(13, 3);
  lcd.print(nbcontrolcompteur);
  
  digitalWrite(RelaydigitalPinD5, LOW);                
  delay(tempsactivepompemills);                        
  digitalWrite(RelaydigitalPinD5, HIGH);               
  delay(1000);
  
  }  
  else {
  Serial.println("HUMIDITE BONNE");  
  EtathumiditeS1 = 1;
  lcd.setCursor(3,2);
  lcd.print("HUMIDITE BONNE");
  
   
  delay(1000);
  }
///////////////////////POMPE 1////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////Bloc timer+pome a ne pas séparer
}

c'est typiquement une définition de programme qui se prête bien à la programmation par machine à états cf mon tuto éventuellement

Si vous avez suivi le tuto et en supposant que vous utilisez un capteur capacitif de ce genre:

à la louche je dirais que la machine à état ressemblerait à un truc comme cela:

et donc si on met cela sous forme de code ça donnerait cela (absolument non testé, tapé ici)

// --------------------------------------------
// -------- LES ELEMENTS A DEFINIR ------------
// --------------------------------------------
const byte pinCapteur = A0; // la sonde est branchée sur A0

const int valeurSolSec    = 673;    // A DEFINIR: VALEUR DANS L'AIR
const int valeurSolHumide = 308;    // A DEFINIR: VALEUR DANS L'EAU
const int seuilSolSec     = valeurSolHumide + (valeurSolSec - valeurSolHumide) * 3.0 / 5.0; // A DEFINIR: formule arbitraire on est sec au dessus de 3/5ème

const unsigned long dureeArrosage = 1000ul * 3ul;         // arrose pendant 3 secondes
const unsigned long dureePause    = 1000ul * 10ul;        // petite pause pendant 10 secondes
const unsigned long dureeAttente  = 1000ul * 60ul * 30ul; // longue pause pendant 30 minutes

const byte maxArrosages = 10; // on n'arrosera pas plus que ça même si l'humidité n'est pas assez bonne avant de faire un attente longue

const byte minArrosage = 3; // A DEFINIR: après 3 arrosages on testera si l'hulidité a assez progressé pour détecter une situation anormale
const int deltaHumiditeMin = (valeurSolSec - valeurSolHumide) / 10; // A DEFINIR: formule aritraire après minArrosage on doit avoir gagné au moins 10% de variation

// --------------------------------------------

enum : byte {REPOS, ARROSE, PAUSE, MESURE, ATTENTE, ALERTE} etatCourant = REPOS;
unsigned long topChrono;
int humiditeInitiale;
byte nbArrosages;

int mesure() {
  return constrain(analogRead(pinCapteur), valeurSolHumide, valeurSolSec);
}

bool solSec() {
  return mesure() >=  seuilSolSec;
}

bool situationAnormale() {
  return (nbArrosages >= minArrosage) && (abs(mesure() - humiditeInitiale) < deltaHumiditeMin);
}

void alerte() {
  etatCourant = ALERTE;
  Serial.println(F("ALERTE"));
  Serial.println(F("VERIFIER LE SYSTEME"));
  Serial.flush();
  pompeOff(); // juste au cas où
  // autre chose ? (beep, LED rouge, sleep)
}

void pompeOn() {
  Serial.println(F("Arrosage en cours"));
  // A FAIRE
}

void pompeOff() {
  Serial.println(F("Fin arrosage"));
  // A FAIRE
}

void evaluation() {
  switch (etatCourant) {
    case REPOS:
      if (solSec()) {
        topChrono = millis();
        humiditeInitiale = mesure();
        nbArrosages = 0;
        pompeOn();
        etatCourant = ARROSE;
      }
      break;

    case ARROSE:
      if (millis() - topChrono >= dureeArrosage) {
        pompeOff();
        topChrono = millis();
        nbArrosages++;
        etatCourant = PAUSE;
      }
      break;

    case PAUSE:
      if (millis() - topChrono >= dureePause) {
        etatCourant = MESURE;
      }
      break;

    case MESURE:
      if (situationAnormale()) alerte();
      else if ((nbArrosages < maxArrosages) && solSec()) {
        topChrono = millis();
        pompeOn();
        etatCourant = ARROSE;
      } else {
        etatCourant = ATTENTE;
      }
      break;

    case ATTENTE:
      if (millis() - topChrono >= dureeAttente) etatCourant = REPOS;
      break;

    case ALERTE:
      break; // on n'en sort pas, il faudra rebooter une fois le problème corrigé
  }
}

void setup() {
  Serial.begin(115200);
}

void loop() {
  evaluation();
}

si ça fonctionne dans la console série (à 115200 bauds) il ne vous reste plus qu'à rajouter l'écran LCD pour les affichages au lieu de les faire sur la console et bien sûr les commandes du relai des pompes dans les 2 fonctions associées.

L'avantage de structurer le code en machine à états c'est qu'il est non bloquant, relativement simple à lire et à faire évoluer: Il suffit de regarder pour chaque état quelles sont les flèches qui en partent (les transitions possibles en fonction des évènements attendus) et juste coder cela dans le switch/case.

à vous de jouer :slight_smile:

bonjour et merci de votre réponse

Effectivement ce sont bien ces sondes :slight_smile:

J'ai tester votre code je n'arrive pas à le faire fonctionner et pour être honnête la complexité du code et nettement au dessus de mes capacité :frowning:

Avez vous lu le tuto ? Il explique le principe.

moi j'ai pourtant fait vérifier le programme et il marche bien

Si je passe sur un NANO je fait juste un copier/coller???

J'ai vue que l ESP8266 à seulement une sortie analogique donc je doit utilisé un multiplexer ( 74hc4051 que j 'ai déjà reçu ) mais je pense que je pars trop loin pour mon niveau actuel.

Là j ai juste fait avec un NANO un code pour avoir le taux d’humidement sur 4pots :),par contre si j'ajoute des pompes (soit 1 pompe pour 1 sonde) mon code était vraiment pas concluant car il fesai des pauses des arrosages non prevu et tous .Il vivait sa vie de son coté :sweat_smile:

Pour récapitulé j'aimerai un système d'arrosage avec X sonde et pompe qui puisse arroser en cas de besoins et avec une protection en cas de problème.

Sur un Nano c'est inintéressant mais sur un ESP8266 avec visu consultable en ligne serai le TOP mais est-il possible de visualiser les donnée en ligne ?

Ex : Je suis en voyage et j'aimerai consulter sur les données ??

Avec un ESP8266 est que c'est possible ou c'est juste en WIFI?

///////////////////////LCD NE PAS TOUCHER ////////////////////////////
#include <Wire.h>
#include <hd44780.h>                       
#include <hd44780ioClass/hd44780_I2Cexp.h> 
const int LCD_COLS = 20;
const int LCD_ROWS = 4;
hd44780_I2Cexp lcd; 
int status;
///////////////////////LCD NE PAS TOUCHER ////////////////////////////


//////////////////////Convertion en %//////////////////////
  int ValeurPourcentageA0 = A0;                 //Sonde1 pin A0
  int ValeurPourcentageA1 = A1;                 //Sonde1 pin A1
  int ValeurPourcentageA2 = A2;                 //Sonde1 pin A2
  int ValeurPourcentageA3 = A3;                 //Sonde1 pin A3
//////////////////////Convertion en %//////////////////////


///////////////////////SONDE 1////////////////////////
  const int ValeursecheA0 = 471;              //CHANGER de valeur haute humide apres test
  const int ValeurhumideA0 = 297;             //CHANGER Valeur base seche apres test

  int SondeanalogPinA0 = A0;                  // PIN A0 pour le capteur de l’humidité du sol
  int SondedigitalValA0;                      // Lecture de la sonde
/////////////////////////////////////SONDE 1////////////


///////////////////////SONDE 2////////////////////////
  const int ValeursecheA1 = 490;              //CHANGER de valeur haute humide apres test
  const int ValeurhumideA1 = 220;             //CHANGER Valeur base seche apres test

  int SondeanalogPinA1 = A1;                  // PIN A1 pour le capteur de l’humidité du sol
  int SondedigitalValA1;                      // Lecture de la sonde
/////////////////////////////////////SONDE 2////////////


///////////////////////SONDE 3////////////////////////
  const int ValeursecheA2 = 516;              //CHANGER de valeur haute humide apres test
  const int ValeurhumideA2 = 225;             //CHANGER Valeur base seche apres test
  
  int SondeanalogPinA2 = A2;                  // PIN A2 pour le capteur de l’humidité du sol
  int SondedigitalValA2;                      // Lecture de la sonde
/////////////////////////////////////SONDE 3////////////


///////////////////////SONDE 4////////////////////////
  const int ValeursecheA3 = 490;              //CHANGER de valeur haute humide apres test
  const int ValeurhumideA3 = 219;             //CHANGER Valeur base seche apres test

  int SondeanalogPinA3 = A3;                  // PIN A3 pour le capteur de l’humidité du sol
  int SondedigitalValA3;                      // Lecture de la sonde
/////////////////////////////////////SONDE 4////////////


void setup()  
{

///////////////////////LCD NE PAS TOUCHER ////////////////////////////
  Serial.begin(9600); 
   lcd.begin(20,4); 
///////////////////////LCD NE PAS TOUCHER ////////////////////////////

}


void loop()   {

/////////////////////// SONDE 1 //////////////////////////// 
  int ValeurPourcentageA0 = A0;
  ValeurPourcentageA0 = map (analogRead(SondeanalogPinA0), ValeursecheA0, ValeurhumideA0, 0, 100); //map(valeur, deValeurbasse, deValeurHaute, versValeurBasse, vers ValeurHaute);
  Serial.print("Sonde 1 : ");  Serial.println(analogRead(A0)); 

/////////////////////// SONDE 1 ////////////////////////////

  
/////////////////////// SONDE 2 ////////////////////////////
  int ValeurPourcentageA1 = A1;
  ValeurPourcentageA1 = map (analogRead(SondeanalogPinA1), ValeursecheA1, ValeurhumideA1, 0, 100); //map(valeur, deValeurbasse, deValeurHaute, versValeurBasse, vers ValeurHaute);
  Serial.print("Sonde 2 : ");  Serial.println(analogRead(A1)); 
  
/////////////////////// SONDE 2 ////////////////////////////


/////////////////////// SONDE 3 ////////////////////////////
  int ValeurPourcentageA2= A2;
  ValeurPourcentageA2 = map (analogRead(SondeanalogPinA2), ValeursecheA2, ValeurhumideA2, 0, 100); //map(valeur, deValeurbasse, deValeurHaute, versValeurBasse, vers ValeurHaute);
  Serial.print("Sonde 3 : ");  Serial.println(analogRead(A2)); 
  
/////////////////////// SONDE 3 ////////////////////////////


/////////////////////// SONDE 4 ////////////////////////////
  int ValeurPourcentageA3 = A3;
  ValeurPourcentageA3 = map (analogRead(SondeanalogPinA3), ValeursecheA3, ValeurhumideA3, 0, 100); //map(valeur, deValeurbasse, deValeurHaute, versValeurBasse, vers ValeurHaute);
  Serial.print("Sonde 4 : ");  Serial.println(analogRead(A3)); 
 
/////////////////////// SONDE 3 ////////////////////////////


///////////////////////LCD NE PAS TOUCHER ////////////////////////////
  lcd.clear();
  
  lcd.setCursor(0,0); 
  lcd.print("Olivier");
  lcd.setCursor(7,0);
  lcd.print(ValeurPourcentageA0);
  lcd.setCursor(10,0);
  lcd.print("%");

  lcd.setCursor(0,1);
  lcd.print("Yucca");
  lcd.setCursor(7,1);
  lcd.print(ValeurPourcentageA1);
  lcd.setCursor(10,1);
  lcd.print("%");
  
  lcd.setCursor(0,2);
  lcd.print("Bananier");
  lcd.setCursor(7,2);
  lcd.print(ValeurPourcentageA2);
  lcd.setCursor(10,2);
  lcd.print("%");

  lcd.setCursor(0,4);
  lcd.print("Monstera");
  lcd.setCursor(7,3);
  lcd.print(ValeurPourcentageA3);
  lcd.setCursor(10,3);
  lcd.print("%");

  delay(1000); //Rafraichissement
///////////////////////LCD NE PAS TOUCHER ////////////////////////////
}

J'ai vue que l ESP8266 à seulement une sortie analogique donc je doit utilisé un multiplexer ( 74hc4051 que j 'ai déjà reçu ) mais je pense que je pars trop loin pour mon niveau actuel.

Que voulez vous faire avec une sortie analogique ? - vous voulez dire une entrée je suppose (ADC) ?

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.