Comment sortir d'une boucle

Bonjour à tous,

J'ai creer un automate capable de gérer une serre extérieure, il relève l'hygro, la température et fais fonctionner des relais, tous çà grâce à arduino.

Aujourd'hui j'ai fini mon code et il fonctionne seul problème si je veux sortir d'une boucle for je suis obliger de faire un reset de la carte.

Ma question est la suivante, une fois que j'ai appuyé sur une touche et que la boucle for se lance, comment faire pour sortir de cette boucle sur simple appuie d'une touche ?

Je vous mets mon code à la suite, merci d'avance.

void loop()
{
char touche = clavier.getKey();
  if(touche == NO_KEY)
  {
    menu();
  }
  else
  {
     if(touche == '1')
    {
       croissance();
    }
     if(touche == '2')
    {
       floraison();
    }
     if(touche == '3')
    {
       sechage();
    }
  }
}

void menu()
{
      lcd.clear();
      lcd.setCursor(1,0);
      lcd.print(" Choisir un mode ");
      lcd.setCursor(0,1);
      lcd.print("1 - MODE CROISSANCE ");
      lcd.setCursor(0,2);
      lcd.print("2 - MODE FLORAISON  ");
      lcd.setCursor(0,3);
      lcd.print("3 - FIN DE FLORAISON");
      delay(2000);
     
}

void croissance() 
{
  for(;;)
  {
  dht.begin();
  lcd.begin(20,4);
  heure = RTC.get(DS1307_HR,true);                              // Récupération de l'heure
              minut = RTC.get(DS1307_MIN,false);
              seconde = RTC.get(DS1307_SEC,false);
              date = RTC.get(DS1307_DATE,false);
              mois = RTC.get(DS1307_MTH,false);
              annee = RTC.get(DS1307_YR,false);
              temps_perso = (heure * 100) + minut;  //creation temps_perso
              float h = dht.readHumidity();
              float t = dht.readTemperature();

                if(t > extracteur_on)                                       // Mise en route des Relais en mode croissance
                {
                  digitalWrite(extracteur, HIGH);
                }
                if(t < extracteur_off)
                {
                  digitalWrite(extracteur, LOW);
                }
                if(t > intracteur_on){
                  digitalWrite(intracteur, HIGH);
                }
                if(t < intracteur_off){
                  digitalWrite(intracteur, LOW);
                }
                if(temps_perso > lampe_on && temps_perso < lampe_off)
                {
                  digitalWrite(lampe,HIGH);
                }
                else
                {
                  digitalWrite(lampe, LOW);
                }
                if(minut > 15 && minut < 30 || minut > 45 && minut < 59)
                {
                  digitalWrite(brasseur,HIGH);
                }
                else
                {
                  digitalWrite(brasseur,LOW);
                }

                 lcd.setCursor(0,0);                                                       // Début affichage page 1 LCD
            lcd.print("  MODE  CROISSANCE  ");
            lcd.setCursor(0,1);
            lcd.print("TEMPERATURE ");
            lcd.print(t); 
            lcd.print(" C");
            lcd.setCursor(0,2);
            lcd.print("HYGROMETRIE ");
            lcd.print(h); 
            lcd.print(" %");
            lcd.setCursor(7,3);
                if(digitalRead(lampe) == HIGH)
                {
                    lcd.print("LAMPE ALLUMEE");
                }
                else
                {
                    lcd.print("LAMPE ETEINTE");
                }

            lcd.setCursor(0,3);
                if (heure < 10)
                {
                   lcd.print("0");
                } 
            lcd.print(RTC.get(DS1307_HR,true)); 
            lcd.print("H");
                 if (minut < 10)
                {
                  lcd.print("0");
                }
            lcd.print(RTC.get(DS1307_MIN,false));
            lcd.print(" ");
            delay(5000);            
            lcd.clear();
            lcd.setCursor(0,0);                                                // début page 2 de l'écran LCD
            lcd.print("EXTRA  ");
            lcd.setCursor(7,0);
              if(digitalRead(extracteur) == HIGH)
              {
            lcd.print("ON ");
              }
              else
              {
            lcd.print("OFF");
              }
            lcd.setCursor(0,1);
            lcd.print("INTRA  ");
            lcd.setCursor(7,1);
              if(digitalRead(intracteur) == HIGH)
              {
            lcd.print("ON ");
              }
               else
              {
            lcd.print("OFF");
              }    
            lcd.setCursor(0,2);
            lcd.print("BRASS ");
            lcd.setCursor(7,2);
              if(digitalRead(brasseur) == HIGH)
              {
            lcd.print("ON ");
              }
              else
              {
            lcd.print("OFF");
              }
              lcd.setCursor(0,3);
                if (heure < 10)
                {
                   lcd.print("0");
                } 
            lcd.print(RTC.get(DS1307_HR,true)); 
            lcd.print("H");
                 if (minut < 10)
                {
                  lcd.print("0");
                }
            lcd.print(RTC.get(DS1307_MIN,false));
            lcd.print(" ");
            delay(5000); 
  }
}

Je n'ai pas mis la totalité du code juste la loop et 1 programme, je travail avec un keypad 4*4.

break

ben, elle est où ta boucle for ?

pour sortir d'un boucle for, l'instruction qui va bien est break

La boucle for se trouve au niveau de void croissance.

Comment placer ce break ?

Voici ce que j'ai essayer mais cela ne fonctionne pas...

void croissance()
{
   for(;;)
{
 /* Mon bout de code */

if(touche =='0')
{
break;
}

}
}

Tu testes la touche et si elle est enfoncée : break !

Justement c'est ce que j'ai fait mais cela ne fonctionne pas...

( J'ai éditer mon message du dessus )

Roms629:

void croissance()

{
  for(;:wink:
{

Cela s'appelle une boucle infinie.

Cordialement,
bidouilleelec

Oui j'avais compris çà :slight_smile:

Mais j'aimerais pouvoir sortir de cette boucle par simple appuie d'une touche ?

Ce n'est pas possible sur une boucle infini ?

break marche très bien sur PC (et sur arduino, mais je n'en ai pas sous ma main)

J'ai repris l'ossature que vous avez donnée (en passant, mettez if ... { sur la même ligne: pour les petits écrans -"smart" "phones", c'est plus confortable:

cat breqk.cpp && g++ breqk.cpp && ./A.exe

#include <stdio.h>
int main() {
  int i = 0;
   for (;;) {
    i++;
    printf( " i: %d ",i); // affiche le compteur sur la même ligne
    if (3 == i) {
       printf("\n break\n"); // saute une ligne; affiche break
       break;
    }
  }
  printf(" fini\n");
  return 0;
}
 i: 1  i: 2  i: 3
 break
 fini

Merci pour votre réponse, mais étant débutant je comprend pas tout :roll_eyes:

Mais je vais essayer d'adapter cette partie à mon code et je reviens vous donnez une réponse

Vous pouvez le mettre sans le setup et remplacer prontf par Serial.print dans les cas simples;
printf( " i: %d ",i); se replace par Serial.print(" i:");Serial.print(i); Serial.print(" ");
En passant, je ne comprendrai jamais pourquoi les débutants ne débutent pas ... avec un PC (est préassemblé; il n'y a rien à brancher) ou un xxPi. (et pour tester des codes compliqués, j'utilise toujours des bouts de programme sur xxPi)

Roms629:

void croissance()

{
  for(;:wink:
 {
/* Mon bout de code */
   if(touche =='0') break;
 }
}

Tu n'aurais pas oublié

char touche = clavier.getKey();

+1 (et il faut le mettre dans la boucle "infinie" -juste avant le test, par exemple)

Au passage, il est possible de coder ça autrement, sans passer par une boucle infinie ni avoir besoin d'en sortir : le while est ton ami...

  char touche= clavier.getKey();
  while (touche == NO_KEY) touche = clavier.getKey();
  if (touche =='0') {
...
  } else if (touche =='1') {
...
  } else ...

A tester.

C'est une boucle d'attente du clavier : elle te permet de faire autre chose en attendant une touche.

un autre ami (peut être un peu moins beau) serait le for incomplet

for (char touche =  clavier.getKey(); NO_KEY != touche;) {
switch touch{
case '0'
.....
}
touche=clavier.getKey();
 }

Edité:
votre boucle est ... à l'interieur d'une autre boucle (loop ) et bloquera toute action ulterieure. Si votre titre est exact (comment sortir d'UNE boucle?), c'est ce que vous voulez; sinon, il vous faudra recoder (pour sortir de DEUX boucles) par machine d'état....

Merci pour vos réponses je ferais les test demain dans la journée et je vous tiens au courant.

Encore merci à tous.

Bonjour à tous,

J'ai modifier mon code, enlever les boucle for et je suis passé par un while.
Voici mon code :

void loop()
{
char touche= clavier.getKey();
  while (touche == NO_KEY) 
  {
  touche = clavier.getKey();
  if (touche == '1') 
  {
    
    
    croissance();
    
    
  } 
  else if (touche == '2') 
  {
    
    
    floraison(); 
    
  } 
  else if (touche == '3')
  {
    sechage();
  }
  
}
}

La fonction se lance sans souci, je peux également naviguer entre les différentes fonction.
Maintenant le souci qui se pose c'est que ma prise de mesure ( température et hygro ) ne se met à jour que lors d'un appuie bouton...

Comment faire pour que cela se mette à jour tout les X temps ?

Comme je disais, tu peux faire d'autres choses dans ta boucle d'attente. Tu peux faire la mise à jour après les tests

Qu'entendez vous par X temps?
la façon la plus simple est de faire un compteur , incrementé à l'entrée de for, et qui met à jour les mesures à chaque fois que compteur modulo X vaut zero
Quelque chose comme ça

#define X 100 
int compteur = 0;
void loop() {
if (0 == compteur) {
    miseAJourMesures();();
}
compteur = (compteur +1) % X; 
// le même code qu'avant
}

Ce n'est certainement pas ce qui se fait de mieux (sera bizarre si la fonction loop a des temps d'execution variables) mais c'est le plus rapide (et vous n'avez pas demandé à ce que la mise à jour soit à intervalles de temps réguliers, d'où ma question).
Edité:
vu le post de lesept: on peut mettre ce bout de code après les tests, bien sûr.
mis un nom de fonction joli (reste à l'écrire..... si ce n'est déjà fait)

Un truc comme ça

unsigned long chrono ;
unsigned long period = 5000ul;  // mise à jour toutes les 5 secondes 

void loop()
{
  char touche= clavier.getKey();
  if (touche == '1') croissance();
  else if (touche == '2') floraison(); 
  else if (touche == '3') sechage();
 
  if (millis () - chrono > period) {
    chrono =millis () ;
// code de mise à jour 
  } 
}