Go Down

Topic: [RESOLU]Arduino activer une pompe avec des capteurs de pression et niveau d'eau (Read 1 time) previous topic - next topic

gwest77

Bonjour,je souhaiterais automatiser une pompe a l'aide d'un arduino UNO. L'arduino active un relais qui démarrera la pompe sous certaines conditions :

Etape1 : Si on donne une implusion sur un bouton poussoir (sur une des broches)

       Alors on peut exécuter la suite :

Si le niveau d'eau est OK alors on démarre la pompe sinon on ne fait rien et (on reviens a l'étape 1).

Si la pompe est allumé alors on attend 5 secondes que la pression arrive dans les tuyaux

Ensuite si la pression dans les tuyaux est trop basse ou si la pression est trop élevé Alors on éteint la pompe (et on revient au début: étape 1)

Si la pression est bonne et le niveau d'eau OK (le loop va vérifier constamment)on laisse allumé la pompe pendant 2h et a la fin de la durée des 2heures on éteint la pompe et on revient a l'étape 1

Voici le début de mon code :
Code: [Select]
// CODE //
 
 
 
 
 
 
const int led_verte = 2;//Led verte sur pin 2
const int led_rouge = 5;//Led rouge sur pin 1
int in1 = 4;//relay to arduino pin 4
void setup() {
  pinMode(in1, OUTPUT);//sortie relais broche7
  pinMode(led_verte, OUTPUT);//broche2 étant une sortie (led verte)
  pinMode(led_rouge, OUTPUT);//broche5 étant une sortie (led rouge)
  digitalWrite(in1, HIGH);
  Serial.begin(9600);
 
 
  }
   
  void loop(){
 
 
     
    int sensorVal=analogRead(A1);
    Serial.print("Sensor Value: ");
    Serial.print(sensorVal);
     
    float voltage = (sensorVal*5.0)/1024.0;
    Serial.print("Milivolts: ");
    Serial.print(voltage);
     
    float pressure_pascal = (3.0*((float)voltage-0.47))*1000000.0;
    float pressure_bar = pressure_pascal/10e5;
    Serial.print("Pressure = ");
    Serial.print(pressure_bar);
    Serial.println(" bars");
    Serial.print("Pressure = ");
     
 
    if (pressure_bar<0.05)
 
    {
 
        //ce code n'est exécuté que si la condition est vérifiée
        Serial.println("Pression trop basse");
        digitalWrite(in1, LOW);
        digitalWrite(led_verte, LOW);// led verte d'un état Bas
        digitalWrite(led_rouge, HIGH);// led rouge d'un état Haut
    }
     
    if (pressure_bar>0.05)
 
    {
 
        //ce code n'est exécuté que si la condition est vérifiée
 
        Serial.println("Pression Bonne");
        digitalWrite(in1, HIGH);
        digitalWrite(led_verte, HIGH);// led verte d'un état Haut
        digitalWrite(led_rouge, LOW);// led rouge d'un état Bas
         
    }
     
    delay(3000);
     
    }
     
     
    // END OF CODE //




Actuellement le bout de code détecte juste si la pression est  trop basse et coupe le relais  (in1) Si la pression est bonne il laisse allumé le relais.

Il me semble qui faut faire un boucle avec while.


Pouriez vous me guider ?

Merci

biggil

Code: [Select]

  int sensorVal=analogRead(A1);
  float voltage = (sensorVal*5.0)/1024.0;
  Serial.print("Milivolts: ");
  Serial.print(voltage);
 
vu la formule, voltage est une valeur en Volts. Or tu affiches "Millivolts:", ça peut t'embrouiller.


Quote
Code: [Select]

    float pressure_pascal = (3.0*((float)voltage-0.47))*1000000.0;
    float pressure_bar = pressure_pascal/10e5;
    Serial.print("Pressure = ");
 

Pour convertir des Pascals en bars, on divise par 10 puissance 5. Or toi tu divises pas 10e+5, c-à-d 1.e+6. Ta pression est fausse d'un facteur 10.

gwest77

Oui en effet il y a erreur sur les Minivolts. IL faut mettre volts.

POur la pression, En effet
Code: [Select]


   float pressure_pascal = (3.0*((float)voltage-0.47))*100000.0;
   float pressure_bar = pressure_pascal/10e5;



biggil


gwest77

Alors, j'ai bossé un peu sur le code :

Code: [Select]

   const int buttonPin = 3; // Interrupteur sur pin 3
   const int contactniv = 5; // Contact niveau d'eau sur pin 5
   int in1 = 4;//relais pompe sur pin 4

   void setup() {

   

   pinMode(in1, OUTPUT);//relais pompe étant une sortie
   pinMode(buttonPin, INPUT); //Interrupteur sur pin3 étant une entrée
   pinMode(contactniv, INPUT); //Contact niveau d'eau étant une entrée
   digitalWrite(in1, HIGH);
   Serial.begin(9600);
}

void loop() {


// Si l'interrupteur sur pin 3 est fermé, exécuter ce qu'il y a entre les acolades
while (digitalRead(buttonPin) == HIGH) {

   // Si le niveau d'eau est Trop Bas
if (contactniv == LOW)  {
        Serial.println("Niveau d'eau Trop Bas");
        digitalWrite(in1, LOW); // Le relais pompe ne s'active pas

}
else
{

if (contactniv == HIGH)  {
        Serial.println("Niveau d'eau Bon");
        digitalWrite(in1, HIGH); // Alors on active le relais pompe




}
}
}
delay(5000); // On attend 5 secondes que la pression arrive


    int sensorVal=analogRead(A1);
    Serial.print("Sensor Value: ");
    Serial.print(sensorVal);
   
    float voltage = (sensorVal*5.0)/1024.0;
    Serial.print("Volts: ");
    Serial.print(voltage);
   
    float pressure_pascal = (3.0*((float)voltage-0.47))*100000.0;
    float pressure_bar = pressure_pascal/10e5;
    Serial.print("Pressure = ");
    Serial.print(pressure_bar);
    Serial.println(" bars");
    Serial.print("Pressure = ");


    if (pressure_bar<2.2)
{
     Serial.println("Pression trop basse");
    digitalWrite(in1, LOW);
   
}
else if (pressure_bar>3.2)
{
     Serial.println("Pression trop haute");
    digitalWrite(in1, LOW);
    }
   
else
{
  delay(7200000);  // La pompe fonctionne durant 2h
}


}




Maintenant le déroulement se fait comme suit :

- Si l'interrupteur sur pin3 est fermé et si le niveau d'eau est trop bas, le relais reste éteint.
- Par contre si le niveau d'eau est Bon alors la pompe se met a tourner .
- On attend 5 secondes que la pression arrive dans le tuyau de refoulement.
- On mesure la pression, si elle se trouve entre 2,1 et 3,2 la pompe tourne pendant 2h.

Le problème avec ce code, c'est que même si la pompe n'est pas mise en route on vas attendre 2h a boire le café en attendant que Mémé revienne. Du coup dois je mettre "break" pour revenir au début de la boucle  si le relais pompe est sur LOW ?

Ensuite il faudrait que l'arduino puisse vérifier pendant la durée des deux heures l'état des capteur de niveau d'eau et de pression toutes les 3 secondes  et si un des deux capteurs sont sur LOW, alors couper la pompe.

Est ce que quelqu'un aurait une idée pour pouvoir arréter la pompe durant son fonctionnement des 2h en ouvrant l'intérupteur pin3 ?

gwest77

J'ai oublié d'éteindre la pompe a la fin :

Code: [Select]
digitalWrite(in1, LOW); // Alors on éteint le relais pompe

biggil

d'abord, STP, présente correctement to code, il est indenté n'importe comment. Fais Control-T dans l'IDE Arduino

Quote
Code: [Select]
float pressure_bar = pressure_pascal/10e5;
Ensuite tu n'as pas corrigé le calcul de la pression en bars. Il est toujours faux d'un facteur 10 ! Voir mon post précédent.


Quote
Code: [Select]
while (digitalRead(buttonPin) == HIGH) { ... }
tant que ton inter est sur HIGH, tu tournes en boucle dans ce bloc, sans jamais en sortir.


Quote
Code: [Select]
if (contactniv == LOW)
Là tu pars en pointe, contactniv vaut 5 et ne change jamais. C'est un numéro de broche.
Je suppose que ce que tu veux, c'est
Code: [Select]
if ( digitalRead(contactniv) ) == LOW)


Quote
J'ai oublié d'éteindre la pompe a la fin
Il me semble que tu as aussi oublié de l'allumer  :)


gwest77

Quote
d'abord, STP, présente correctement to code, il est indenté n'importe comment. Fais Control-T dans l'IDE Arduino. 
Merci pour l'astuce.

Quote
float pressure_pascal = (3.0*((float)voltage-0.47))*1000000.0;
    float pressure_bar = pressure_pascal/10e5;
J'ai pas bien compris le facteur 10, 1 bar = 100000 Pascals.
Doit-on écrire 10e5 autrement?

Quote
if ( digitalRead(contactniv) ) == LOW)
IL y a une parenthèse en trop, c'est plutot
Code: [Select]
if ( digitalRead(contactniv)  == LOW) non?


tant que ton inter est sur HIGH, tu tournes en boucle dans ce bloc, sans jamais en sortir.
C'est mieux comme ça ?

Code: [Select]
const int buttonPin = 3; // Interrupteur sur pin 3
const int contactniv = 5; // Contact niveau d'eau sur pin 5
int in1 = 4;//relais pompe sur pin 4

void setup() {



  pinMode(in1, OUTPUT);//relais pompe étant une sortie
  pinMode(buttonPin, INPUT); //Interrupteur sur pin3 étant une entrée
  pinMode(contactniv, INPUT); //Contact niveau d'eau étant une entrée
  digitalWrite(in1, HIGH);
  Serial.begin(9600);
}

void loop() {


  // Si l'interrupteur sur pin 3 est fermé, exécuter ce qu'il y a entre les acolades
  while (digitalRead(buttonPin) == HIGH) {

    // Si le niveau d'eau est Trop Bas
    if ( digitalRead(contactniv)  == LOW)  {
      Serial.println("Niveau d'eau Trop Bas");
      digitalWrite(in1, LOW); // Le relais pompe ne s'active pas
    }


    if (contactniv == HIGH)  {
      Serial.println("Niveau d'eau Bon");
      digitalWrite(in1, HIGH); // Alors on active le relais pompe
    }




delay(5000); // On attend 5 secondes que la pression arrive


int sensorVal = analogRead(A1);
Serial.print("Sensor Value: ");
Serial.print(sensorVal);

float voltage = (sensorVal * 5.0) / 1024.0;
Serial.print("Volts: ");
Serial.print(voltage);

float pressure_pascal = (3.0 * ((float)voltage - 0.47)) * 1000000.0;
float pressure_bar = pressure_pascal / 10e5;
Serial.print("Pressure = ");
Serial.print(pressure_bar);
Serial.println(" bars");
Serial.print("Pressure = ");


if (pressure_bar < 2.2)
{
  Serial.println("Pression trop basse");
  digitalWrite(in1, LOW);

}
else if (pressure_bar > 3.2)
{
  Serial.println("Pression trop haute");
  digitalWrite(in1, LOW);
}

else
{
  delay(7200000);  // La pompe fonctionne durant 2h
}
digitalWrite(in1, LOW); // Alors on éteint le relais pompe

}
}



Il me semble que tu as aussi oublié de l'allumer, il me semble l'avoir allumé..  :

Code: [Select]
if (contactniv == HIGH)  {
      Serial.println("Niveau d'eau Bon");
      digitalWrite(in1, HIGH); // Alors on active le relais pompe
    }




biggil

J'ai pas bien compris le facteur 10, 1 bar = 100000 Pascals.
Doit-on écrire 10e5 autrement?
10e5 = 1 million. C'est 10 multiplié par 10 puissance 5 (e5 =100000)

donc tu dois diviser par 1.e5 ( un point e cinq, à la place de 10e5)

gwest77

Je viens de me rendre compte que mon code ça ne vas pas du tout.. comme le delay qui n'as pas la bonne fonction. Je re-posterai bientot une nouvelle version.



Par contre, j'ai une valeur 0.5 bar a la mesure (a pression atmosphérique), alors que je devrais avoir une valeur proche de 0 c'est normal ?


Code: [Select]
    float pressure_pascal = (3.0 * ((float)voltage - 0.47)) * 1000000.0;
    float pressure_bar = pressure_pascal / 1.e5;



biggil

D'ou vient ta formule d'étalonnage (le calcul qui transforme les Volts en Pascals) ?
Pourquoi tu multiplies par 1 million pour divisiser par cent mille juste derrière ?

gwest77

Elle vient d'ici : https://www.youtube.com/watch?v=AB7zgnfkEi4

Je pense que la formule de début était bonne.

biggil

ce dont je suis sûr et certain, c'est que pour transformer des Pascals en bar, on divise par cent mille, et pas par 1 milllion.
Je suis sûr aussi que 10e5, ça vaut un million.
C'est tout ce que je sais.
J'ai vu que tu as récupéré ces 2 lignes sur le Net, ça ne prouve pas qu'il n'y a pas d'erreur  :)

Normalement avec ton capteur il devrait y avoir une notice - question très bête : est-ce bien le même que dans le tutoriel ?
Dans cette notice il devait y avoir la formule de conversion des Volts en Pression.

Sinon, si tu n'as rien (à part ces formules suspectes), tu peux étalonner toi-même ton capteur.
Tu notes la tension à P atmosphérique.
Puis tu lui mets 10 cm d'eau (froide), c-à-d une pression de 10 millibars, tu notes la tension
Pareil avec 20 cm; 30 cm, etc, jusqu'au max que tu peux. (1 cm = 1 millibar).
Tu portes tous ces points sur un graphe, tu traces la droite qui les joint au mieux, et tu calcules les coefficients A et B tels que Pression = AxVolts + B.
Ou tu fais directement une régression par les moindres carrés sur les points.

Tu peux aussi utiliser une pompe à vélo munie d'un manomètre.

Un étalonnage c'est moins facile qu'un copier coller, mais c'est solide.

gwest77

Bonjour, voici un nouveau code (voir description a la fin du code)

Par contre je voudrais insérer une temporisation après le démarrage de la pompe et vérifier la pression, savez vous comment faire cela ?

Code: [Select]
// CODE //


// variables
int moistureSensorValue;    // stores the moisture sensor values
int soggyLEDPin = 3;
int moistsoilLEDPin = 4;
int drysoilLEDPin = 5;
int pumpLEDPin = 6;
int pumpPin = 7; // Numéro de la broche à laquelle est connecté le relais pompe
const int niveau = 11;     // Numéro de la broche à laquelle est connecté le contact niveau d'eau
int etatBouton = 0;         // variable qui sera utilisée pour stocker l'état du bouton
// Déclaration des variables :
int etatniveau = 0;         // variable qui sera utilisée pour stocker l'état du niveau d'eau
const int bouton = 10;     // Numéro de la broche à laquelle est connecté l'interrupteur
const int led_verte = 2;//Led verte sur pin 2
const int led_rouge = 8;//Led rouge sur pin 8
int relais = 9;//relais de pompe sur pin 9
int moistureSensorPin = 1;//détecteur d'humidité sur pin 1





void setup() {
  pinMode(relais, OUTPUT);//sortie relais broche7
  pinMode(led_verte, OUTPUT);//broche2 étant une sortie (led verte)
  pinMode(led_rouge, OUTPUT);//broche5 étant une sortie (led rouge)
  digitalWrite(relais, HIGH);
  Serial.begin(9600);

  // indique que la broche bouton est une entrée :
  pinMode(bouton, INPUT);
  pinMode(niveau, INPUT);



  pinMode(soggyLEDPin, OUTPUT);
  pinMode(moistsoilLEDPin, OUTPUT);
  pinMode(drysoilLEDPin, OUTPUT);
  pinMode(pumpLEDPin, OUTPUT);
  pinMode(pumpPin, OUTPUT);







}

void loop() {

  // reads the sensors
  moistureSensorValue = analogRead(moistureSensorPin);
  // lit l'état du bouton et stocke le résultat dans etatBouton
  etatBouton = digitalRead(bouton);
  // lit l'état du niveau et stocke le résultat dans etatniveau
  etatniveau = digitalRead(niveau);

  // check the moisture range
  if (moistureSensorValue >= 700) {
    // in case of dry soil:


    // lights up the correct LED
    digitalWrite(drysoilLEDPin, HIGH);
    digitalWrite(moistsoilLEDPin, LOW);
    digitalWrite(soggyLEDPin, LOW);

  }
  if ((moistureSensorValue < 700) && (moistureSensorValue >= 300)) {


    // lights up the correct LED
    digitalWrite(drysoilLEDPin, LOW);
    digitalWrite(moistsoilLEDPin, HIGH);
    digitalWrite(soggyLEDPin, LOW);
    delay(250);
  }
  if (moistureSensorValue < 300) {
    // in case of soggy soil:

    // lights up the correct LED
    digitalWrite(drysoilLEDPin, LOW);
    digitalWrite(moistsoilLEDPin, LOW);
    digitalWrite(soggyLEDPin, HIGH);
    delay(100);
  }

  // if the soil is dry and if the button is on, and if the watter level is OK : turn on the pump for 1 minute
  if ((etatBouton == HIGH) && (etatniveau == HIGH)) {
    while (moistureSensorValue >= 700) {

      // turn the pump on
      digitalWrite(pumpPin, HIGH);
      digitalWrite(pumpLEDPin, HIGH);
      delay(10000);
      // if the soil is not moist so far
      // reads the moisture sensor once more
      moistureSensorValue = analogRead(moistureSensorPin);
    }
    // turn the pump off
    digitalWrite(pumpPin, LOW);
    digitalWrite(pumpLEDPin, LOW);
  }


}



// END OF CODE //

// Résumé :
//Si le programateur est allumé, si le niveau d'eau est bon, si le sol est sec(non humide) Alors on allume la pompe.
//Si la pompe est allumé on temporise 7 secondes et on mesure la pression au refoulement: si la pression est bonne,
//on laisse tourné jusqu'a ce que le programmateur s'éteint. Si la pression n'est pas bonne on éteint la pompe.

gwest77

Bonjour,

j'ai rajouté une temporisation, pouvez vous me dire si mon code tient la route?

Enfait, il y a un contact qui déclenchera la pompe seulement si le niveau d'eau est bon et si l'humidité du sol est "sec".

Si la pompe démarre, alors il y a temporisation de 5 secondes puis il y a la mesure de la pression qui s'éffectue, si la pression n'a pas les conditions requises, alors la pompe s'éteint.

Code: [Select]





// État d'activation de la tempo
int tempoActive = 0;

// Temps à l'activation de la tempo
unsigned long tempoDepart = 0;



// pins definition
int bouton = 0;
int moistureSensorPin = 1;
int soggyLEDPin = 3;
int moistsoilLEDPin = 4;
int drysoilLEDPin = 5;
int pumpLEDPin = 6;
int pumpPin = 7;
const int led_verte = 2;//Led verte sur pin 2
const int led_rouge = 8;//Led rouge sur pin 1

// variables
int boutonValue;       // stores the level sensor values
int moistureSensorValue;    // stores the moisture sensor values
int etatBouton;             // variable qui enregistre l'état du bouton




void setup() {
  // serial initialization
  Serial.begin(9600);






  // Arduino pins initalization

  pinMode(soggyLEDPin, OUTPUT);
  pinMode(moistsoilLEDPin, OUTPUT);
  pinMode(drysoilLEDPin, OUTPUT);
  pinMode(pumpLEDPin, OUTPUT);
  pinMode(pumpPin, OUTPUT);
  pinMode(bouton, INPUT); // le bouton est une entrée




  etatBouton = HIGH; // on initialise l'état du bouton comme "relaché"






}


void loop() {


  etatBouton = digitalRead(bouton); // Rappel : bouton = 2

  // reads the sensors
  boutonValue = analogRead(bouton);
  moistureSensorValue = analogRead(moistureSensorPin);




  // check the moisture range
  if (moistureSensorValue >= 700) {
    // in case of dry soil:

    // lights up the correct LED
    digitalWrite(drysoilLEDPin, HIGH);
    digitalWrite(moistsoilLEDPin, LOW);
    digitalWrite(soggyLEDPin, LOW);

  }
  if ((moistureSensorValue < 700) && (moistureSensorValue >= 300)) {
    // in case of moist soil:

    // lights up the correct LED
    digitalWrite(drysoilLEDPin, LOW);
    digitalWrite(moistsoilLEDPin, HIGH);
    digitalWrite(soggyLEDPin, LOW);
    delay(250);
  }
  if (moistureSensorValue < 300) {
    // in case of soggy soil:

    // lights up the correct LED
    digitalWrite(drysoilLEDPin, LOW);
    digitalWrite(moistsoilLEDPin, LOW);
    digitalWrite(soggyLEDPin, HIGH);
    delay(100);
  }

  // if the soil is dry and if it is the right time: turn on the pump for 1 minute
  if ((etatBouton == LOW)) {

    while (moistureSensorValue >= 700) {

      // turn the pump on
      digitalWrite(pumpPin, HIGH);
      digitalWrite(pumpLEDPin, HIGH);

      delay(10000);
      // if the soil is not moist so far
      // reads the moisture sensor once more
      moistureSensorValue = analogRead(moistureSensorPin);
    }
    // turn the pump off
    digitalWrite(pumpPin, LOW);
    digitalWrite(pumpLEDPin, LOW);
  }



  // Si le bouton est enfoncé,
  if ( digitalRead(bouton) == LOW ) {

    // Alors on active la temporisation
    tempoActive = 1;
    tempoDepart = millis();

  }

  // Si la temporisation est active,
  if ( tempoActive ) {

    // Et si il s'est écoulé 5 secondes,
    if ( ( millis() - tempoDepart ) >= 5000 ) {


      // Et on désactive la temporisation
      tempoActive = 0;

      // Puis on vérifie la pression,

      int sensorVal = analogRead(A1);
      Serial.print("Sensor Value: ");
      Serial.print(sensorVal);

      float voltage = (sensorVal * 5.0) / 1024.0;
      Serial.print("volts: ");
      Serial.print(voltage);

      float pressure_pascal = (3.0 * ((float)voltage - 0.47)) * 1000000.0;
      float pressure_bar = pressure_pascal / 10e5;
      Serial.print("Pressure = ");
      Serial.print(pressure_bar);
      Serial.println(" bars");
      Serial.print("Pressure = ");


      if (pressure_bar < 0.05)

      {

        //ce code n'est exécuté que si la condition est vérifiée
        Serial.println("Pression trop basse");
        digitalWrite(pumpPin, LOW);
        digitalWrite(led_verte, LOW);// led verte d'un état Bas
        digitalWrite(led_rouge, HIGH);// led rouge d'un état Bas
      }

      if (pressure_bar > 0.05)

      {

        //ce code n'est exécuté que si la condition est vérifiée

        Serial.println("Pression Bonne");
        digitalWrite(pumpPin, HIGH);
        digitalWrite(led_verte, HIGH);// led verte d'un état Haut
        digitalWrite(led_rouge, LOW);// led rouge d'un état Bas

      }



    }

  }





}




Go Up