how to stop a loop arduino

2019-01-24 05:25发布

问题:

I have this loop, how would I end the loop?

 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);
      }

回答1:

Arduino specifically provides absolutely no way to exit their loop function, as exhibited by the code that actually runs it:

setup();

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

Besides, on a microcontroller there isn't anything to exit to in the first place.

The closest you can do is to just halt the processor. That will stop processing until it's reset.



回答2:

This isn't published on Arduino.cc but you can in fact exit from the loop routine with a simple exit(0);

This will compile on pretty much any board you have in your board list. I'm using IDE 1.0.6. I've tested it with Uno, Mega, Micro Pro and even the Adafruit Trinket

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.
}

I use this in projects where I wire in a button to the reset pin. Basically your loop runs until exit(0); and then just persists in the last state. I've made some robots for my kids, and each time the press a button (reset) the code starts from the start of the loop() function.



回答3:

Matti Virkkunen said it right, there's no "decent" way of stopping the loop. Nonetheless, by looking at your code and making several assumptions, I imagine you're trying to output a signal with a given frequency, but you want to be able to stop it.

If that's the case, there are several solutions:

  1. If you want to generate the signal with the input of a button you could do the following

    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);
            }
        }
    }
    

    In this case we're using a button pin as an INPUT_PULLUP. You can read the Arduino reference for more information about this topic, but in a nutshell this configuration sets an internal pullup resistor, this way you can just have your button connected to ground, with no need of external resistors. Note: This will invert the levels of the button, LOW will be pressed and HIGH will be released.

  2. The other option would be using one of the built-ins hardware timers to get a function called periodically with interruptions. I won't go in depth be here's a great description of what it is and how to use it.



回答4:

The three options that come to mind:

1st) End void loop() with while(1)... or equally as good... 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
}

This option runs your code once and then kicks the Ard into an endless "invisible" loop. Perhaps not the nicest way to go, but as far as outside appearances, it gets the job done.
The Ard will continue to draw current while it spins itself in an endless circle... perhaps one could set up a sort of timer function that puts the Ard to sleep after so many seconds, minutes, etc., of looping... just a thought... there are certainly various sleep libraries out there... see e.g., Monk, Programming Arduino: Next Steps, pgs., 85-100 for further discussion of such.

2nd) Create a "stop main loop" function with a conditional control structure that makes its initial test fail on a second pass.
This often requires declaring a global variable and having the "stop main loop" function toggle the value of the variable upon termination. E.g.,

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  ...
}

Granted, this might not be especially pretty, but it also works.
It kicks the Ard into another endless "invisible" loop, but this time it's a case of repeatedly checking the if(stop_it == false) condition in stop_main_loop() which of course fails to pass every time after the first time through.

3rd) One could once again use a global variable but use a simple if (test == blah){} structure instead of a fancy "stop main loop" function.

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.
}

There are certainly other ways to "stop" that pesky endless main loop but these three as well as those already mentioned should get you started.



回答5:

This will turn off interrupts and put the CPU into (permanent until reset/power toggled) sleep:

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

See also http://arduino.land/FAQ/content/7/47/en/how-to-stop-an-arduino-sketch.html, for more details.



回答6:

> #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);   } }

how to stop loop in serial monitor?



标签: c loops arduino