web-dev-qa-db-fra.com

comment arrêter une boucle arduino

J'ai cette boucle, comment pourrais-je terminer la boucle? 

 void loop() {
      // read the pushbutton input pin:

       a ++;
      Serial.println(a);
        analogWrite(speakerOut, NULL);

      if(a > 50 && a < 300){
      analogWrite(speakerOut, 200);
      }

      if(a <= 49){
        analogWrite(speakerOut, NULL);
      }

      if(a >= 300 && a <= 2499){
          analogWrite(speakerOut, NULL);
      }
11
Beep

Arduino ne fournit spécifiquement aucun moyen de quitter leur fonction loop, comme le montre le code qui l’exécute:

setup();

for (;;) {
    loop();
    if (serialEventRun) serialEventRun();
}

En outre, sur un microcontrôleur, il n’ya rien d’autre que l’on puisse sortir.

Le mieux que vous puissiez faire est simplement d'arrêter le processeur. Cela arrêtera le traitement jusqu'à ce qu'il soit réinitialisé.

8
Matti Virkkunen

Ce n'est pas publié sur Arduino.cc mais vous pouvez en fait sortir de la routine de boucle avec une simple sortie (0); 

Cela compilera à peu près n'importe quel tableau de votre liste. J'utilise IDE 1.0.6. Je l'ai testé avec Uno, Mega, Micro Pro et même le bibelot Adafruit

void loop() {
// All of your code here

/* Note you should clean up any of your I/O here as on exit, 
all 'ON'outputs remain HIGH */

// Exit the loop 
exit(0);  //The 0 is required to prevent compile error.
}

J'utilise ceci dans les projets où je câble un bouton à la broche de réinitialisation. En gros, votre boucle court jusqu’à la sortie (0); et puis persiste dans le dernier état. J'ai fabriqué des robots pour mes enfants et chaque fois que vous appuyez sur un bouton (réinitialisation), le code commence au début de la fonction loop ().

36
Zoul007

Matti Virkkunen dit bien, il n'y a pas de moyen "décent" pour arrêter la boucle. Néanmoins, en examinant votre code et en émettant plusieurs hypothèses, j'imagine que vous essayez d'émettre un signal avec une fréquence donnée, mais que vous voulez pouvoir l'arrêter.

Si tel est le cas, il existe plusieurs solutions:

  1. Si vous voulez générer le signal avec l’entrée d’un bouton, vous pouvez faire ce qui suit:

    int speakerOut = A0;
    int buttonPin = 13;
    
    void setup() {
        pinMode(speakerOut, OUTPUT);
        pinMode(buttonPin, INPUT_PULLUP);
    }
    
    int a = 0;
    
    void loop() {
        if(digitalRead(buttonPin) == LOW) {
            a ++;
            Serial.println(a);
            analogWrite(speakerOut, NULL);
    
            if(a > 50 && a < 300) {
                analogWrite(speakerOut, 200);
            }
    
            if(a <= 49) {
                analogWrite(speakerOut, NULL);
            }
    
            if(a >= 300 && a <= 2499) {
                analogWrite(speakerOut, NULL);
            }
        }
    }
    

    Dans ce cas, nous utilisons une broche de bouton en tant que INPUT_PULLUP. Vous pouvez lire la référence Arduino pour plus d’informations sur ce sujet, mais en un mot cette configuration définit une résistance de rappel interne. Ainsi, vous pouvez simplement relier votre bouton à la terre, sans nécessiter de résistances externes .Note: Ceci inversera les niveaux du bouton, LOW sera appuyé et HIGH sera relâché.

  2. L'autre option consisterait à utiliser l'un des timers matériels intégrés pour obtenir une fonction appelée périodiquement avec des interruptions. Je n'entrerai pas dans les détails car ici est une excellente description de ce que c'est et de la façon de l'utiliser.

8
Maximo Dominguez

Les trois options qui me viennent à l’esprit:

1er) Terminez void loop() par while(1)... ou tout aussi bien ... while(true)

void loop(){
    //the code you want to run once here, 
    //e.g., If (blah == blah)...etc.

    while(1)        //last line of main loop
}

Cette option exécute votre code une fois, puis envoie à Ard une boucle "invisible" sans fin Ce n’est peut-être pas la meilleure façon d’aller , Mais en ce qui concerne les apparences extérieures, le travail est fait.
L’Ard continue à tirer du courant pendant qu’il tourne lui-même en un cercle sans fin ... peut-être pourrait-on installer une sorte de minuterie fonction qui met l'Ard en veille après tant de secondes, minutes, etc. de bouclage ... juste une pensée ... il y a certainement diverses bibliothèques de sommeil là-bas ... voir par exemple , Monk, Programming Arduino: Next Steps, p. 85-100 Pour en savoir plus.

2e) Créer une fonction "arrêter la boucle principale" avec une structure de contrôle conditionnel Qui fait échouer son test initial une seconde fois.
Cela nécessite souvent de déclarer une variable globale et d’avoir le La fonction "stop main loop" bascule la valeur de la variable à la fin. Par exemple.,

boolean stop_it = false;         //global variable

void setup(){
    Serial.begin(9600); 
    //blah...
}

boolean stop_main_loop(){        //fancy stop main loop function

    if(stop_it == false){   //which it will be the first time through

        Serial.println("This should print once.");

       //then do some more blah....you can locate all the
       // code you want to run once here....eventually end by 
       //toggling the "stop_it" variable ... 
    }
    stop_it = true; //...like this
    return stop_it;   //then send this newly updated "stop_it" value
                     // outside the function
}

void loop{ 

    stop_it = stop_main_loop();     //and finally catch that updated 
                                    //value and store it in the global stop_it 
                                    //variable, effectively 
                                    //halting the loop  ...
}

Certes, cela n’est peut-être pas très joli, mais ça marche aussi.
Il lance l'Ard dans une autre boucle sans fin "invisible", mais cette fois C'est un cas de vérification répétée de la condition if(stop_it == false) dans stop_main_loop() qui, bien sûr, ne passe pas à chaque fois après la première fois. 

3ème) On pourrait encore une fois utiliser une variable globale mais utiliser une structure simple if (test == blah){} au lieu d'une fonction sophistiquée "stop main loop".

boolean start = true;                  //global variable

void setup(){

      Serial.begin(9600);
}

void loop(){

      if(start == true){           //which it will be the first time through



           Serial.println("This should print once.");       

           //the code you want to run once here, 
           //e.g., more If (blah == blah)...etc.

     }

start = false;                //toggle value of global "start" variable
                              //Next time around, the if test is sure to fail.
}

Il existe certainement d’autres moyens de "stopper" cette boucle principale sans fin embêtante Mais ces trois-là, ainsi que ceux déjà mentionnés, devraient vous aider à démarrer.

3
philomech

Cela éteindra les interruptions et mettra la CPU en veille (permanente jusqu'à ce que la réinitialisation soit effectuée/basculée):

cli();
sleep_enable();
sleep_cpu();

Voir aussi http://arduino.land/FAQ/content/7/47/en/how-to-stop-an-arduino-sketch.html , pour plus de détails.

2
Sigivald
> #include <SPI.h>
> #include <MFRC522.h>
> #include <Ethernet.h>
> 
> #define RST_PIN 4
> #define SS_PIN 2
> 
> String content="";
> 
> byte mac[]={0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED}; IPAddress
> ip(192,168,3,15);
> 
> MFRC522 mfrc522(SS_PIN, RST_PIN); EthernetClient client;
> 
> void setup() {   Serial.begin(9600);                                  
> SPI.begin();   while(!Serial){;}   Ethernet.begin(mac, ip);           
> mfrc522.PCD_Init();             
>                                     //Serial.println(F("Silahkan Scan Kartu RFID Anda:")); }
> 
> void loop() {   rfid();   database(); }
> 
> void rfid(){   //membaca kartu RFID   if ( !
> mfrc522.PICC_IsNewCardPresent())    {
>     return;   }   // memilih salah satu card yang terdeteksi   if ( ! mfrc522.PICC_ReadCardSerial())    {
>     return;   }
>      //Serial.print("Kartu Anda Adalah :");   //String content= "";   //byte letter;   //for (byte i = 0; i < mfrc522.uid.size; i++) {
>      //Serial.print(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " ");
>      //Serial.print(mfrc522.uid.uidByte[i], HEX);
>      //content.concat(String(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " "));
>      //content.concat(String(mfrc522.uid.uidByte[i], HEX));   //}   //Serial.println();   //delay(1000); //change value if you want to
> read cards faster
> 
>   //mfrc522.PICC_HaltA();   //mfrc522.PCD_StopCrypto1(); }
> 
> void database(){   EthernetClient client;   rfid();   if
> (client.connect("192.168.3.12", 80)){
>     Serial.print("Kartu Anda Adalah :"); 
>     String content="";
>     byte letter;
>     for (byte i = 0; i < mfrc522.uid.size; i++) {
>      Serial.print(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " ");
>      Serial.print(mfrc522.uid.uidByte[i], HEX);
>      content.concat(String(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " "));
>      content.concat(String(mfrc522.uid.uidByte[i], HEX));   }   Serial.println();   delay(1000); //change value if you want to read
> cards faster   mfrc522.PICC_HaltA();   mfrc522.PCD_StopCrypto1();
>     
>     //Serial.println("connected");
>     Serial.print(content);
>     client.println("POST /gerbang2/insert.php HTTP/1.1");
>     client.println("Host: 192,168,3,12"); 
>     client.println("Connection: close");
>     client.print("Content-Type: application/x-www-form-urlencoded\n");
>     client.print("Content-Length: "); 
>     client.print(content.length());
>     client.print("\n\n");
>     client.print(content);
>     Serial.println(content);
>     delay (1000);
>     client.stop();     }   else{
>     Serial.println("Connection Failed.");  
>     Serial.println();
>     delay (1000);   } }

comment arrêter la boucle dans le moniteur série?

0
한룻디