Arduino - остановка l oop с помощью кнопки - PullRequest
2 голосов
/ 23 апреля 2020

Итак, я экспериментировал с TinkerCad, ожидая прибытия моего Arduino. В настоящее время у меня есть все светодиодные фонари oop, и я хочу запустить и остановить l oop нажатием кнопки.

В настоящее время я могу запустить свой l oop с помощью кнопки, но не могу чтобы остановить l oop той же кнопкой, нажмите. Имеет ли это какое-то отношение к устранению помех?

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

Моя схема установки:

Hello world project

РЕДАКТИРОВАТЬ:

Я изменил свой код, заменил задержку на миллис и ищу изменение состояния кнопки. Все еще ищите способ отрегулировать interval_led1 в конце l oop для создания последовательностей больного светодиодного освещения.

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

Ответы [ 2 ]

1 голос
/ 23 апреля 2020

Ваша схема правильная. Если вы продолжаете нажимать кнопку немного дольше, условие будет продолжать оставаться в хорошем состоянии, а состояние снова сбрасывается ложно.

Чтобы смоделировать эффект переключения, используйте переменную 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;
     }     
 }
1 голос
/ 23 апреля 2020

Здесь ваши два случая очень разные с точки зрения задержки: 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) - это поиск изменений состояния кнопки. Таким образом, вы должны сравнить его с предыдущим значением. Вы можете объявить другое логическое значение 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;

Надеюсь, это поможет!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...