簡體   English   中英

Arduino - 通過按鈕停止循環

[英]Arduino - stopping loop via button

所以我一直在試驗 TinkerCad,等待我的 arduino 到貨。 目前我有一個 LED 燈循環,我想通過按下按鈕來啟動和停止循環。

目前我可以通過按鈕啟動我的循環,但不能通過按下相同的按鈕來停止循環。 這和去抖有關系嗎?

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

我的電路設置:

你好世界項目

編輯:

我已經調整了我的代碼,用毫秒替換了延遲,並尋找按鈕 state 的變化。 仍在尋找一種方法來在循環結束時調整 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);
    }
}

在這里,您的兩種情況在延遲方面非常不同: if(buttonstate==true)由於其中包含多個delay指令,因此執行時間很長, else非常快,因為其中沒有delay

buttonstate==True並且您按下按鈕時(正如 Delta_G 所說, delay()在大多數情況下會阻止測試發生,您應該使用millis()例如進行計時,但是假設您很幸運並且您傳遞您的第一個if語句),因此buttonstate將翻轉為false

由於您的else指令沒有延遲,因此電路板將立即返回到您的初始if ,不幸的是,由於您的速度不足以僅按下此按鈕幾微秒,這仍然是true的。 所以buttonstate將再次翻轉,您的代碼將落在您的if(buttonstate==true)中,它很長,允許您在重新評估if(digitalRead(button)==HIGH)之前及時釋放按鈕。

解決方案(除了@Delta_G 提出的計時問題和@TomServo 提出的硬件問題)是尋求按鈕state 的更改 因此,您必須與之前的值進行比較。 您可以聲明另一個 boolean boolean prev_buttonstate = false; 並且可以執行以下操作:

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

希望能幫助到你!

你的電路是正確的。 如果您按住按鈕的時間稍長,則狀態將繼續保持良好,並且 state 會再次錯誤地重置。

要模擬切換效果,請使用 bool 變量,如下所示: 當信號變低時,您重置變量。

  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