【问题标题】:how to stop a loop arduino如何停止循环arduino
【发布时间】:2014-05-30 13:17:54
【问题描述】:

我有这个循环,我将如何结束循环?

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

【问题讨论】:

    标签: c loops arduino


    【解决方案1】:

    这不是在 Arduino.cc 上发布的,但实际上您可以通过简单的 exit(0) 退出循环例程;

    这将在您的板列表中的几乎所有板上编译。我正在使用 IDE 1.0.6。我已经用 Uno、Mega、Micro Pro 甚至 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.
    }
    

    我在将按钮连接到复位引脚的项目中使用它。基本上你的循环一直运行到 exit(0);然后只是坚持在最后一个状态。我为我的孩子们制作了一些机器人,每次按下按钮(重置)时,代码都会从 loop() 函数的开头开始。

    【讨论】:

    • 我也用过这个。为什么这不是更广为人知/使用的?
    • 这将是停止处理器并通过反汇编判断它完全符合我在上面评论中建议的正确 C 库方法,即禁用中断并进入无限循环。如果它支持,将处理器置于睡眠状态也很好,以节省电力。 (请注意,在 C++ 代码中,exit(0) 也可能在关闭之前运行全局析构函数)。 @Beep 这应该是公认的答案。
    • 不适用于 esp8266。编译器错误。 In function 'loop': undefined reference to 'exit'
    • 在 ESP8266 上我使用的是 ESP.deepSleep( seconds * 1000000, WAKE_RF_DISABLED);如果 GPIO16 未绑定到 RST,它甚至不会在 30 秒内唤醒。
    • delay(1000); exit(0); 有助于在退出前完成剩余的串行通信。
    【解决方案2】:

    Arduino 明确规定绝对无法退出其loop 函数,正如实际运行它的代码所示:

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

    此外,在微控制器上,首先没有任何东西可以退出。

    你能做的最接近的就是停止处理器。这将停止处理,直到它被重置。

    【讨论】:

    • 如何停止处理器?
    • @Brent:通过禁用中断并将处理器置于睡眠状态。您可以将其包装在无限循环中,以确保永远不会继续执行。
    • 我认为“回归”会这样做
    • @MohamedElShenawy:这只会从对“循环”函数的调用返回并返回到 main() 中的 for 循环。
    【解决方案3】:

    Matti Virkkunen 说得对,没有“体面”的方法来停止循环。尽管如此,通过查看您的代码并做出几个假设,我想您正在尝试输出具有给定频率的信号,但您希望能够阻止它。

    如果是这样,有几种解决方案:

    1. 如果您想通过输入按钮生成信号,您可以执行以下操作

      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 reference 了解有关此主题的更多信息,但简而言之,此配置设置了一个内部上拉电阻,这样您只需将按钮接地,无需外部电阻。 注意:这将反转按钮的级别,LOW 将被按下,HIGH 将被释放。

    2. 另一种选择是使用其中一个内置硬件计时器来获得一个定期调用的函数,并中断。我不会深入了解here 对它是什么以及如何使用它的详细描述。

    【讨论】:

    • 哇,tganks 的信息。我会通读参考资料并尝试一下。
    【解决方案4】:

    想到的三个选项:

    1st) 以 while(1)... 结束 void loop()... 或同样好... 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 将在其自旋时继续汲取电流 一个无尽的循环......也许可以设置一种计时器 让 Ard 在几秒钟后进入睡眠状态的功能, 分钟等,循环......只是一个想法......当然有 那里有各种睡眠库......见 例如,Monk,Arduino 编程:下一步,第 85-100 页 进一步讨论。

    2nd) 创建一个带有条件控制的“停止主循环”函数 使其初始测试在第二次通过时失败的结构。
    这通常需要声明一个全局变量并具有 “停止主循环”功能切换变量的值 终止时。例如,

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

    当然,这可能不是特别漂亮,但它也有效。
    它将 Ard 踢进了另一个无休止的“隐形”循环,但这 这是在stop_main_loop() 中反复检查if(stop_it == false) 条件的情况 在第一次通过之后,当然每次都无法通过。

    3rd) 可以再次使用全局变量,但使用简单的if (test == blah){} 结构而不是花哨的“停止主循环”函数。

    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 进入(永久直到复位/电源切换)睡眠:

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

      另请参阅http://arduino.land/FAQ/content/7/47/en/how-to-stop-an-arduino-sketch.html,了解更多详情。

      【讨论】:

      • 请查看此URL,它将有助于您提高内容质量
      【解决方案6】:

      只需使用这一行退出函数:

      return;
      

      【讨论】:

      • 问题是专门询问arduino loopreturn 肯定会退出函数,但不会结束/停止循环。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-13
      • 1970-01-01
      • 2018-04-03
      • 2022-01-11
      • 2010-09-26
      相关资源
      最近更新 更多