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