boucle while bloquante

Bonjour à tous, je viens de me rendre compte que mon code ne fonctionne plus, et se bloque quand je rentre dans la boucle while

// si la cloture1 est éteinte depuis plus de 20 s, on prévient tout le monde en envoyant un push

 while ( cloture1Allume == false  && tempsdepasse == false){
      
     if (millis()-tempscloturearret >= 20000)  {
   
  
          sendToPushingBox(DEVID5);
             
          tempsdepasse = true;
 }}

Quand la condition se trouvant dans le while est rempli, je ne parviens plus à rallumer la clôture
C'est uniquement quand la condition du if devient vrai que je sors de la boucle while et enfin je peux rallumer. Pourtant, je dois pouvoir allumer immédiatement après avoir éteint, sans etre obligé d'attendre le délai des 20 s

voici mon code : Comment puis je faire pour eviter ça , merci d'avance !

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

  //------------------------------ GESTION DE L'APPUI SUR LE BOUTON DE LA CLOTURE 1--------------------------------

  if (val == HIGH && precedetat == LOW) {
    etatbouton = !etatbouton;
    delay(10);
  }
  precedetat = val;


  if (etatbouton == 0 && cloture1Allume == true) { // si bouton n'a pas encore été appuyé et cloture allumée

    lcd.setCursor(0, 0);
    lcd.print("Clot1. ON.Bouton ");
  }



  if (etatbouton == 1 && cloture1Allume == true) { // si bouton appuyé et cloture allumée
    cloture1Allume = false;
    lcd.setCursor(0, 0);
    lcd.print("Clot1.OFF.Bouton ");
  }                      // alors on éteint

  if (etatbouton == 0 && cloture1Allume == false) {   //  si  bouton pas appuyé et cloture éteinte
    cloture1Allume = true;
    lcd.setCursor(0, 0);
    lcd.print("Clot1. ON.Bouton ");      // alors on allume

  }

  if (etatbouton == 0 && cloture1Allume == true && clotureOFFiphone == true) {  // si bouton pas appuyé, cloture allumé et iphone Off
    cloture1Allume = false;
    lcd.setCursor(0, 0);
    lcd.print("Clot1.OFF.Iphone ");
  }                 // alors on éteint


 if(cloture1Allume == false && clotureOFFiphone == true && etatbouton == 1){ // si bouton appuyé, alors que l'iphone a éteint, on peut rien faire
   
   lcd.setCursor(0, 0);
    lcd.print("Manip.impossible");
    delay(1000);
    etatbouton = 0;
 }
  //---------------------------------CONNEXION AU SERVEUR-------------------------




  EthernetClient client = server.available();
  if (client)  {

    boolean currentLineIsBlank = true;
    stringInput = "";

    if (client.connected())  {
      while (client.available())  {

        char c = client.read();

        if (stringInput.length() < sizeString)  {
          stringInput.concat(c);

        }

        if (c == '\n' && currentLineIsBlank)  {

          digitalRead(Cloture1);


          client.println("<?xml version=\"1.0\" encoding=\"utf-8\"?>");

          client.println("<agridomotique>");

          // Pin 30 Cloture1

          client.print("<Pin>");
         
          client.print("<namePin>CLOTURE 1</namePin>");
          
          client.print("<Etat>");
          if (cloture1Allume == 1) {
            
            client.print ("  ALLUMEE");
          }
          if (cloture1Allume == 0) {
            client.print (" ETEINTE");
            }
          client.print("</Etat>");
           
          client.print("</Pin>");





          client.println("</agridomotique>");
          break;
        }

        if (c == '\n')  {

          Serial.print(stringInput);
          Serial.println();

          if (stringInput.indexOf("GET") != -1)  {



            // si iphone ON
            if (stringInput.indexOf("Cloture1=ON") != -1) {
              cloture1Allume = true;
              clotureOFFiphone = false;
              lcd.setCursor(0, 0);
              lcd.print("Clot1. ON.Iphone ");




            }
            // si off iphone
            if ((stringInput.indexOf("Cloture1=OFF") != -1) && (cloture1Allume == true)) {
              cloture1Allume = false;
              clotureOFFiphone = true;
              lcd.setCursor(0, 0);
              lcd.print("Clot1.OFF.Iphone ");



            }



          }
          currentLineIsBlank = true;
          stringInput = "";
        }
        else if (c != '\r')  {

          currentLineIsBlank = false;
        }
      }
    }
    delay(1);
    client.stop();

  }


//----------------------------------------- COMMMANDE , PUSH ET BUZZER de la Cloture 1 --------------------------------------------

  if (cloture1Allume == true ) {                       // ON ALLUME LA CLOTURE1
    digitalWrite (Cloture1, HIGH);
    digitalWrite (led, HIGH);
    tempsdepasse = false;
  }

  if (cloture1Allume == false ) {                  // ON ETEINT LA CLOTURE1
    digitalWrite (Cloture1, LOW);
    digitalWrite (led, LOW);
    tempscloturearret = millis();
  }

  if ( cloture1Allume == true && pushenvoi == true ) {   // si la cloture1 est allumé on envoi un push
    // On envoi un push allumé
    sendToPushingBox(DEVID1);
    pushenvoi = false;
  }

  if ( cloture1Allume == false && pushenvoi == false ) {  // si la cloture1 est éteinte en onvoi un push
    // On envoi un push éteint
    sendToPushingBox(DEVID2);
    pushenvoi = true;

  }
// si la cloture1 est éteinte depuis plus de 30 mn, on prévient tout le monde en envoyant un push

 while ( cloture1Allume == false  && tempsdepasse == false){
      
     if (millis()-tempscloturearret >= 20000)  {
   
  
          sendToPushingBox(DEVID5);
             
          tempsdepasse = true;
 }}
 
 // si la cloture1 est éteinte depuis plus de 30 mn, on prévient tout le monde en actionnant le buzzer
 
 if (tempsdepasse == true)
     {         digitalWrite (buzzer, HIGH);  // buzzer en route
                delay (300);
               digitalWrite (buzzer, LOW);
               delay (300);
             
               
               }
              

}
//---------------------------------Fonction permettant d'envoyer un push PushingBox---------------------

void sendToPushingBox(char devid[]) {

  //demarre connexion ethernet
  ;

  Serial.println("connecting...");
  if (client2.connect(serverName, 80)) {

    Serial.println("connected");

    Serial.println("sendind request");

    client2.print("GET /pushingbox?devid=");
    client2.print(devid);
    client2.println(" HTTP/1.1");

    client2.print("Host: ");
    client2.println(serverName);
    client2.println("User-Agent: Arduino");
    client2.println("Connection: close");
    client2.println();

    while (client2.connected ())
      if (client2.available ())
        Serial.write(client2.read());

    client2.stop ();

    Serial.println("succes");


  }


  else {
    Serial.println("connection failed");
  }

  client2.stop();
}
/code]

Bonjour

Toutes les boucles sont bloquantes. Pourquoi ne pas utiliser un if ? Je ne vois rien qui justifie d'avoir une boucle :slight_smile:

J'ai déjà essayé remplacer while par if, mais ça ne fonctionne pas, le push est uniquement envoyé avec le while

Bonjour,
pour garder la boucle while, il faut que la valeur de cloture1Allume soit mis à jour à l’intérieur de la boucle...

Oui mais si clôture1allume ne change pas, je ne peux pas

essaye ça

 while ( cloture1Allume == false  && tempsdepasse == false)
     {
      if (BP_réarmement = HIGH)
        { cloture1Allume = true                        // ON ALLUME LA CLOTURE1
        digitalWrite (Cloture1, HIGH);
        digitalWrite (led, HIGH);
        tempsdepasse = false;
        }
     if (millis()-tempscloturearret >= 20000)  
       {
          sendToPushingBox(DEVID5)
          tempsdepasse = true;
       }
   }

Merci, je crois avoir compris le problème ! Je test ce soir en rentrant
Merci encore pour tous vos conseils

Bon alors jai testé tout ça et ça ne règle pas mon problème . Mon code resté bloqué ( dans le moniteur) jusqu'à ce que le temps soit dépassé , la il reprend

      if (BP_réarmement == HIGH)

== et non =

il faut lire l'état du bouton aussi BP_réarmement ou son équivalent
digitalRead(BP_réarmement);

      if (digitalRead(BP_réarmement) == HIGH)

Oui, j'avais corrigé le = mais ça bloque quand même

il faut lire le BP

 while ( cloture1Allume == false  && tempsdepasse == false)
     { BP_rearmement = digitalRead(son entree);
      if (BP_réarmement = HIGH)
        { cloture1Allume = true                        // ON ALLUME LA CLOTURE1
        digitalWrite (Cloture1, HIGH);
        digitalWrite (led, HIGH);
        tempsdepasse = false;
        }
     if (millis()-tempscloturearret >= 20000)  
       {
          sendToPushingBox(DEVID5)
          tempsdepasse = true;
       }
   }

tu peux pas sortir de la boucle même si le bouton est activé tel qu'écrit, vu que si bouton high tempsdepasse = false.
et le while indique aussi tempsdepasse = false
avec ca, tu devrais sortir

 while ( cloture1Allume == false  && tempsdepasse == false)
     { BP_rearmement = digitalRead(son entree);
      if (BP_réarmement == HIGH) // manque un =
        { cloture1Allume = true  ;                      // manque le point virgule
        digitalWrite (Cloture1, HIGH);
        digitalWrite (led, HIGH);
        tempsdepasse = true;
        }
     if (millis()-tempscloturearret >= 20000)  
       {
          sendToPushingBox(DEVID5)
          tempsdepasse = true;
       }
   }

oui, mais "cloture allumée" est devenue vraie :slight_smile:

Infobarquee je ne pense pas que ton code réglera mon problème : si la clôture est eteinte et tempsdepasse est faux, et si on appuie sur le bouton, elle va s'allumer, mais temps dépassé va devenir vrai aussi .ensuite si on eteind a nouveau , tempsdepassé sera tj vrai et on entrera jamais dans le while !

Moi je pense que le problème n'est pas le code.
Le problème est dans la logique de l'ensemble.
Il se résoudra sur le papier en décrivant clairement le comportement du système avec ses différents états et les conditions de passage d'un état à un autre.

En l'état le code est difficile à lire avec les if qui s'empilent. S'acharner sur le code c'est le rendre encore plus obscure et instable.
La logique du fonctionnement est préalable au codage.

Fredericzim:
Infobarquee je ne pense pas que ton code réglera mon problème : si la clôture est eteinte et tempsdepasse est faux, et si on appuie sur le bouton, elle va s'allumer, mais temps dépassé va devenir vrai aussi .ensuite si on eteind a nouveau , tempsdepassé sera tj vrai et on entrera jamais dans le while !

sans le code entier on tergiverse sur un bout de code.
on ne sais as à quoi correspondent tes variables et ce quelles engendrent.
tu peux utiliser un break pour sortir de la boucle à condition qu'une des variables change quelque part pour ne pas retourner dans le while.

http://www.mon-club-elec.fr/pmwiki_reference_arduino/pmwiki.php?n=Main.Break

while (condition) { // debut boucle while

      if (condition1) { // condition dans la boucle while

        if (condition 11 ) { // 1 ère sous-condition dans la condition 1

        break; // sort de la boucle while et pas seulement de la condition 11

        } // fin condition 11

        if (condition 12) { // 2 ème sous-condition dans la condition 1

        } // fin condition 12

        else if (condition 13) {// 3ème sous condition dans la condition 1

        } // fin condition 13

      } // --- fin condition 1

    } // --- fin while

Je voulais poster le code entier, mais le forum l'affiche qu'il est trop long

fais le en deux parties :wink:

voici mon code entier :

partie 1 :

// ---------------------------------------------------------------------------------------------------------
// zimmermann frédéric
// Arduino + ethernet shield control by iOS
// Mai 2015
// ----------------------------------------------------------------------------------------------------------
#include <dht.h>
#include <LiquidCrystal.h>
#include <Ethernet.h>
#include <SPI.h>

  
unsigned long tempscloturearret = 0;


// Ethernet shield settings
// Change the MAC in hex, your IP, Gateway, subnet mask and webport
byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};        // MAC
byte ip[] = {192, 168, 0, 254};                         // Shield IP
byte gateway[] = {192, 168, 0, 1};                      // Gateway
byte subnet[] = {255, 255, 255, 0}; // Subnet mask
byte dnsserver[] = {213, 166, 201, 3};
int port = 85;                                                        // Webport

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

EthernetServer server(port);
LiquidCrystal lcd(9, 8, 5, 4, 3, 2);
EthernetClient client2;


int Cloture1 = 30;
int led = 22;
int bouton = 6;
int etatbouton ;
int buzzer = 24;

int val = 0;
int precedetat = 0;
long previousMillis = 0;
long interval = 250;

boolean pushenvoi = true;
boolean cloture1Allume = true;
boolean clotureOFFiphone;
boolean tempsdepasse = false;

boolean lastConnected = false;

char DEVID1[] = "v1F51D72F4A163BD";  //sénario cloture 1 allumé
char DEVID2[] = "v7F928A69AAD2196";  //sénario cloture 1 éteinte
char DEVID3[] = "v10DB6F8487D22F0";  //sénario cloture 2 allumé
char DEVID4[] = "vDEDA46A8C5E4D79";  //sénario cloture 2 éteinte
char DEVID5[] = "vBD841D59046818A"; // sénario temps dépassé cloture éteinte trop longtemps
char serverName[] = ("api.pushingbox.com");



// Serial speed
int speedSerial = 9600;

// Buffer size
int sizeString = 80;
String stringInput = String(sizeString);

// Setup
void setup()  {

  Serial.begin(speedSerial);

  lcd.begin(16, 2);

  // Digital Pins 10, 11, 12 , 13 utilisé par le shield ethernet
  pinMode(Cloture1, OUTPUT);
  pinMode(led, OUTPUT);
  pinMode(bouton, INPUT);
  pinMode(buzzer, OUTPUT);
  // Start ethernet shield webserver


  Ethernet.begin(mac, ip, dnsserver, gateway, subnet);
  Serial.println (Ethernet.localIP ());



  server.begin();


}


void loop()  {





  val = digitalRead (bouton);
  
  
  Serial.print("CLOTURE");
  Serial.print(" ");
  Serial.println(cloture1Allume);
  delay(500);
  Serial.print("bouton");
  Serial.print(" ");
  Serial.println(etatbouton);
[code]

partie 2 :

[code]//------------------------------ GESTION DE L'APPUI SUR LE BOUTON DE LA CLOTURE 1--------------------------------

  if (val == HIGH && precedetat == LOW) {
    etatbouton = !etatbouton;
    delay(10);
  }
  precedetat = val;


  if (etatbouton == 0 && cloture1Allume == true) { // si bouton n'a pas encore été appuyé et cloture allumée

    lcd.setCursor(0, 0);
    lcd.print("Clot1. ON.Bouton ");
  }



  if (etatbouton == 1 && cloture1Allume == true) { // si bouton appuyé et cloture allumée
    cloture1Allume = false;
    lcd.setCursor(0, 0);
    lcd.print("Clot1.OFF.Bouton ");
  }                      // alors on éteint

  if (etatbouton == 0 && cloture1Allume == false) {   //  si  bouton pas appuyé et cloture éteinte
    cloture1Allume = true;
    lcd.setCursor(0, 0);
    lcd.print("Clot1. ON.Bouton ");      // alors on allume

  }

  if (etatbouton == 0 && cloture1Allume == true && clotureOFFiphone == true) {  // si bouton pas appuyé, cloture allumé et iphone Off
    cloture1Allume = false;
    lcd.setCursor(0, 0);
    lcd.print("Clot1.OFF.Iphone ");
  }                 // alors on éteint


 if(cloture1Allume == false && clotureOFFiphone == true && etatbouton == 1){ // si bouton appuyé, alors que l'iphone a éteint, on peut rien faire
   
   lcd.setCursor(0, 0);
    lcd.print("Manip.impossible");
    delay(1000);
    etatbouton = 0;
 }
  //---------------------------------CONNEXION AU SERVEUR-------------------------




  EthernetClient client = server.available();
  if (client)  {

    boolean currentLineIsBlank = true;
    stringInput = "";

    if (client.connected())  {
      while (client.available())  {

        char c = client.read();

        if (stringInput.length() < sizeString)  {
          stringInput.concat(c);

        }

        if (c == '\n' && currentLineIsBlank)  {

          digitalRead(Cloture1);


          client.println("<?xml version=\"1.0\" encoding=\"utf-8\"?>");

          client.println("<agridomotique>");

          // Pin 30 Cloture1

          client.print("<Pin>");
         
          client.print("<namePin>CLOTURE 1</namePin>");
          
          client.print("<Etat>");
          if (cloture1Allume == 1) {
            
            client.print ("  ALLUMEE");
          }
          if (cloture1Allume == 0) {
            client.print (" ETEINTE");
            }
          client.print("</Etat>");
           
          client.print("</Pin>");





          client.println("</agridomotique>");
          break;
        }

        if (c == '\n')  {

          Serial.print(stringInput);
          Serial.println();

          if (stringInput.indexOf("GET") != -1)  {



            // si iphone ON
            if (stringInput.indexOf("Cloture1=ON") != -1) {
              cloture1Allume = true;
              clotureOFFiphone = false;
              lcd.setCursor(0, 0);
              lcd.print("Clot1. ON.Iphone ");




            }
            // si off iphone
            if ((stringInput.indexOf("Cloture1=OFF") != -1) && (cloture1Allume == true)) {
              cloture1Allume = false;
              clotureOFFiphone = true;
              lcd.setCursor(0, 0);
              lcd.print("Clot1.OFF.Iphone ");



            }



          }
          currentLineIsBlank = true;
          stringInput = "";
        }
        else if (c != '\r')  {

          currentLineIsBlank = false;
        }
      }
    }
    delay(1);
    client.stop();

  }


//----------------------------------------- COMMMANDE , PUSH ET BUZZER de la Cloture 1 --------------------------------------------

  if (cloture1Allume == true ) {                       // ON ALLUME LA CLOTURE1
    digitalWrite (Cloture1, HIGH);
    digitalWrite (led, HIGH);
    tempsdepasse = false;
  }

  if (cloture1Allume == false ) {                  // ON ETEINT LA CLOTURE1
    digitalWrite (Cloture1, LOW);
    digitalWrite (led, LOW);
    tempscloturearret = millis();
  }

  if ( cloture1Allume == true && pushenvoi == true ) {   // si la cloture1 est allumé on envoi un push
    // On envoi un push allumé
    sendToPushingBox(DEVID1);
    pushenvoi = false;
  }

  if ( cloture1Allume == false && pushenvoi == false ) {  // si la cloture1 est éteinte en onvoi un push
    // On envoi un push éteint
    sendToPushingBox(DEVID2);
    pushenvoi = true;

  }
// si la cloture1 est éteinte depuis plus de 30 mn, on prévient tout le monde en envoyant un push

 if ( cloture1Allume == false && tempsdepasse == false && millis()-tempscloturearret >= 20000) {
         
          
           sendToPushingBox(DEVID5);
           tempsdepasse = true;
 }
 
 
 // si la cloture1 est éteinte depuis plus de 30 mn, on prévient tout le monde en actionnant le buzzer
 
 if (tempsdepasse == true)
     {         digitalWrite (buzzer, HIGH);  // buzzer en route
                delay (300);
               digitalWrite (buzzer, LOW);
               delay (300);
             
               
               }
              

}
//---------------------------------Fonction permettant d'envoyer un push PushingBox---------------------

void sendToPushingBox(char devid[]) {

  //demarre connexion ethernet
  ;

  Serial.println("connecting...");
  if (client2.connect(serverName, 80)) {

    Serial.println("connected");

    Serial.println("sendind request");

    client2.print("GET /pushingbox?devid=");
    client2.print(devid);
    client2.println(" HTTP/1.1");

    client2.print("Host: ");
    client2.println(serverName);
    client2.println("User-Agent: Arduino");
    client2.println("Connection: close");
    client2.println();

    while (client2.connected ())
      if (client2.available ())
        Serial.write(client2.read());

    client2.stop ();

    Serial.println("succes");


  }


  else {
    Serial.println("connection failed");
  }

  client2.stop();
}
[code]

bon ben il m'a mis tout le code