简体   繁体   English

Arduino - 通过按钮停止循环

[英]Arduino - stopping loop via button

So i have been experimenting with TinkerCad, waiting for my arduino to arrive.所以我一直在试验 TinkerCad,等待我的 arduino 到货。 Currently I have a loop of ledlights and i want to start and stop the loop by pressing a button.目前我有一个 LED 灯循环,我想通过按下按钮来启动和停止循环。

Currently i am able to start my loop via the button, but not able to stop the loop with the same button press.目前我可以通过按钮启动我的循环,但不能通过按下相同的按钮来停止循环。 Does this have something to do with the debouncing?这和去抖有关系吗?

const int button = 10;
const int led1 = 8;
const int led2 = 4;
const int led3 = 3;
const int timedelay = 250;

boolean buttonstate = false;  

void setup()
  {

  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(led3, OUTPUT);
  pinMode(button, INPUT);
}

void loop() {

if(digitalRead(button)==HIGH)  // check if button is pushed
   buttonstate = !buttonstate;    //reverse buttonstate value

   if(buttonstate==true)
  {  
    digitalWrite(led1, HIGH);
    delay(timedelay); 
    digitalWrite(led1, LOW);
    delay(timedelay); 
    digitalWrite(led2, HIGH);
    delay(timedelay);
    digitalWrite(led2, LOW);
    delay(timedelay);
    digitalWrite(led3, HIGH);
    delay(timedelay);
    digitalWrite(led2, HIGH);
    delay(timedelay);
    digitalWrite(led1, HIGH); 
    delay(timedelay);
    digitalWrite(led3, LOW);
    delay(timedelay);
    digitalWrite(led2, LOW);
    delay(timedelay);
    digitalWrite(led1, LOW); 
    delay(timedelay);
    digitalWrite(led1, HIGH); }
   else {
        digitalWrite(led1, HIGH);
  }     
}

My circuit setup:我的电路设置:

你好世界项目

EDIT:编辑:

I have adjusted my code, replaced the delay with millis and looking for a change in button state.我已经调整了我的代码,用毫秒替换了延迟,并寻找按钮 state 的变化。 Still looking for a way to adjust interval_led1 at the end of the loop to make sick ledlight sequences.仍在寻找一种方法来在循环结束时调整 interval_led1 以制作生病的 LED 灯序列。

const int led1 = 13;
const int led2 = 8;
const int led3 = 5;
const int button = 10;
int ledState_led1 = LOW;             // ledState used to set the LED
int ledState_led2 = LOW;
int ledState_led3 = LOW;


// Generally, you should use "unsigned long" for variables that hold time
// The value will quickly become too large for an int to store
unsigned long previousMillis_led1 = 0;        // will store last time LED was updated
unsigned long previousMillis_led2 = 0;
unsigned long previousMillis_led3 = 0;

long interval_led1 = 500;           // interval at which to blink (milliseconds)
long interval_led2 = 600;
long interval_led3 = 700;

boolean buttonstate = false;


void setup() {

pinMode(led1, OUTPUT);
pinMode(led2, OUTPUT);
pinMode(led3, OUTPUT);
pinMode(button, INPUT);

}





void loop() {
   // check to see if it's time to blink the LED; that is, if the difference
  // between the current time and last time you blinked the LED is bigger than
  // the interval at which you want to blink the LED.
  unsigned long currentMillis_led1 = millis();
  unsigned long currentMillis_led2 = millis();
  unsigned long currentMillis_led3 = millis();

  bool current_state = digitalRead(button);
  bool prev_buttonstate= false;

if(current_state==HIGH && current_state != prev_buttonstate)
{  
   buttonstate = !buttonstate;    //reverse buttonstate value
}
prev_buttonstate = current_state;



if(buttonstate==true)
    if (currentMillis_led1 - previousMillis_led1 >= interval_led1) {
    previousMillis_led1 = currentMillis_led1;
    if (ledState_led1 == LOW) {
      ledState_led1 = HIGH;
    } else {
      ledState_led1 = LOW;
    }
    digitalWrite(led1, ledState_led1);
    }

if(buttonstate==true)    
    if (currentMillis_led2 - previousMillis_led2 >= interval_led2) {
    previousMillis_led2 = currentMillis_led2;
    if (ledState_led2 == LOW) {
      ledState_led2 = HIGH;
    } else {
      ledState_led2 = LOW;
    }
    digitalWrite(led2, ledState_led2);
    }

if(buttonstate==true)
    if (currentMillis_led3 - previousMillis_led3 >= interval_led3) {
    previousMillis_led3 = currentMillis_led3;
    if (ledState_led3 == LOW) {
      ledState_led3 = HIGH;
    } else {
      ledState_led3 = LOW;
    }
    digitalWrite(led3, ledState_led3);
    }
}

Here your two cases are very different in terms of delay: if(buttonstate==true) is very long to execute because of the multiple delay instructions in it, else is very fast because there is no delay in it.在这里,您的两种情况在延迟方面非常不同: if(buttonstate==true)由于其中包含多个delay指令,因此执行时间很长, else非常快,因为其中没有delay

When buttonstate==True and you press the button (as Delta_G said, the delay() prevent the test to happen most of the time and you should use millis() for instance to do the timing, but let say you are lucky and you pass your first if statement), so buttonstate will flip to false .buttonstate==True并且您按下按钮时(正如 Delta_G 所说, delay()在大多数情况下会阻止测试发生,您应该使用millis()例如进行计时,但是假设您很幸运并且您传递您的第一个if语句),因此buttonstate将翻转为false

As there is no delay in your else instruction, the board will come back in no time to your initial if , which, unfortunately will still be true as you are not fast enough to press this button for only a few microseconds.由于您的else指令没有延迟,因此电路板将立即返回到您的初始if ,不幸的是,由于您的速度不足以仅按下此按钮几微秒,这仍然是true的。 So buttonstate will flip again and your code will fall in your if(buttonstate==true) which is very long, allowing you to release the button in time before the if(digitalRead(button)==HIGH) is reevaluated.所以buttonstate将再次翻转,您的代码将落在您的if(buttonstate==true)中,它很长,允许您在重新评估if(digitalRead(button)==HIGH)之前及时释放按钮。

The solution (apart from timing issues raised by @Delta_G, and hardware issues raised by @TomServo) is to seek for changes of the button state.解决方案(除了@Delta_G 提出的计时问题和@TomServo 提出的硬件问题)是寻求按钮state 的更改 You thus have to compare to the previous value it had.因此,您必须与之前的值进行比较。 You can declare another boolean boolean prev_buttonstate = false;您可以声明另一个 boolean boolean prev_buttonstate = false; and could do something like:并且可以执行以下操作:

bool current_state = digitalRead(button);
if(current_state==HIGH && current_state != prev_buttonstate)
{  
   buttonstate = !buttonstate;    //reverse buttonstate value
}
prev_buttonstate = current_state;

Hope it helps!希望能帮助到你!

Your circuit is correct.你的电路是正确的。 If you keep pressing the button little longer, the condition will continue to hold good and the state falsely resets again.如果您按住按钮的时间稍长,则状态将继续保持良好,并且 state 会再次错误地重置。

To simulate the toggling effect, use a bool variable like so:.要模拟切换效果,请使用 bool 变量,如下所示: You reset the variable when the signal goes low.当信号变低时,您重置变量。

  void loop() {
       static bool ready = true;
       if(digitalRead(button)==HIGH && ready)
       {
           ready = false;
            buttonstate = !buttonstate; //reverse buttonstate value
            if(buttonstate){
                  digitalWrite(led1, HIGH);
                  delay(timedelay); 
                  digitalWrite(led1, LOW);
                  delay(timedelay); 
                  /* Etc*/ }
             else {
                  digitalWrite(led1, HIGH);
            }
     }
     else 
     if(digitalRead(button)==LOW && !ready)
     {
         ready = true;
     }     
 }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM