Как остановить цикл arduino
У меня есть этот цикл, как бы закончить цикл?
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 специально не предоставляет абсолютно никакого способа выйти из своей функции loop
, как показано в коде, который фактически запускает его:
setup();
for (;;) {
loop();
if (serialEventRun) serialEventRun();
}
Кроме того, на микроконтроллере в первую очередь нечего делать.
Ближе всего вы можете просто остановить процессор. Это прекратит обработку, пока не будет reset.
Ответ 2
Это не опубликовано на Arduino.cc, но вы можете фактически выйти из цикла с простым выходом (0);
Это будет скомпилировано практически на любой плате, имеющейся в вашем списке. Я использую IDE 1.0.6. Я тестировал его с помощью Uno, Mega, Micro Pro и даже брелка 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.
}
Я использую это в проектах, где я подключаюсь к кнопке reset. В основном ваша петля работает до выхода (0); а затем просто сохраняется в последнем состоянии. Я сделал несколько роботов для своих детей, и каждый раз, когда нажимают кнопку (reset), код начинается с начала функции loop().
Ответ 3
Матти Вирккунен сказал, что это правильно, нет "приличного" способа остановить цикл. Тем не менее, просматривая ваш код и делая несколько предположений, я думаю, вы пытаетесь вывести сигнал с заданной частотой, но вы хотите остановить его.
Если в этом случае имеется несколько решений:
-
Если вы хотите сгенерировать сигнал с помощью кнопки, вы можете сделать следующее
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);
}
}
}
В этом случае мы используем кнопочный штифт как INPUT_PULLUP
. Вы можете прочитать ссылку Arduino для получения дополнительной информации об этой теме, но в двух словах эта конфигурация устанавливает внутренний нагрузочный резистор, таким образом вы можете просто подключите вашу кнопку к земле, без необходимости использования внешних резисторов.
Примечание. Это приведет к инвертированию уровней кнопки, LOW
будет нажата, и HIGH
будет отпущена.
-
Другим вариантом будет использование одного из встроенных аппаратных таймеров для периодического вызова функции с прерываниями. Я не буду углубляться в здесь отличное описание того, что это такое и как его использовать.
Ответ 4
Три варианта, которые приходят на ум:
1-й) Конец void loop()
с while(1)
... или одинаково хороший... 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
}
Эта опция запускает ваш код один раз, а затем ударяет Ard в
бесконечный "невидимый" цикл. Возможно, это не самый лучший способ
но, по внешнему виду, он выполняет свою работу.
Ард продолжит рисовать ток, пока он вращается в
бесконечный круг... возможно, можно было создать своего рода таймер
функция, которая заставляет Ard спать после стольких секунд,
минут и т.д., зацикливания... просто мысль... есть, конечно,
различные библиотеки сна там... см.
например, Monk, Programming Arduino: Следующие шаги, стр. 85-100
для дальнейшего обсуждения таких вопросов.
2nd) Создайте функцию "stop main loop" с условным управлением
структура, которая делает его первоначальный тест терпеть неудачу на втором проходе.
Это часто требует объявления глобальной переменной и наличия
Функция "остановить основной цикл" переключает значение переменной
после прекращения. Например.
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 ...
}
Конечно, это может быть не особенно красиво, но оно также работает.
Он ударяет Арда в другой бесконечный "невидимый" цикл, но это
время это случай многократной проверки условия if(stop_it == false)
в stop_main_loop()
который, конечно же, не проходит каждый раз после первого раза.
3rd). Можно снова использовать глобальную переменную, но использовать простую структуру if (test == blah){}
вместо фэнтезийной функции "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.
}
Есть, конечно, другие способы "остановить" эту досадную бесконечную основную петлю
но эти три, а также те, которые уже упомянуты, должны начать вас.
Ответ 5
Это отключит прерывания и переведет CPU (постоянный до reset/power toggled):
cli();
sleep_enable();
sleep_cpu();
Подробнее см. http://arduino.land/FAQ/content/7/47/en/how-to-stop-an-arduino-sketch.html.