Как остановить цикл 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.
}

Есть, конечно, другие способы "остановить" эту досадную бесконечную основную петлю но эти три, а также те, которые уже упомянуты, должны начать вас.