Как я могу прервать задержку() при нажатии кнопки?

Я создал устройство, которое позволяет моему сыну отслеживать время, потраченное на занятия, и обменивать это время на время, которое он может использовать со своей электроникой (eTime).

Полный код в GITHUB

У меня возникли проблемы с кодированием части кода, которая обрабатывает обратный отсчет от его заработанного eTime. Как и сейчас, он может вести обратный отсчет и предупреждать его, когда его eTime истекает, но процесс нельзя прервать.

Я хотел бы, чтобы он мог остановить свое время eTime и использовать остаток позже. Я попытался поместить функцию в цикл while.

while(digitalRead(button_9)==LOW){
    delay(60000);
    avail_time -= 1;
    if(avail_time<0){
      playAlarm();
      return;
}

Это регистрирует нажатие клавиши, но игнорирует задержку.

Я также пытался использовать цикл for для обратного отсчета и цикл для проверки каждую секунду нажатия клавиши.

void useTime() {
  for(int i=avail_time+1; i>0; i--){
    displayTime(i);
    for(int minute=60; minute>0; minute--){
      if(digitalRead(button_9)==HIGH){
        avail_time = i;
        return;
      }
      delay(1000);
    }
  }
  while(digitalRead(button_9)==LOW){
    tone(buzzer, 2000);
    }
  noTone(buzzer);
  avail_time=0;
  displayOptions();
  return;
 }

Этот не регистрирует нажатие клавиши.

, 👍0

Обсуждение

посмотрите пример скетча «мигать без промедления», @jsotola

Используйте метку времени вместо задержки(), см. пример [Мигание без задержки](https://arduinogetstarted.com/tutorials/arduino-led-blink-without-delay)., @Rozona Zoro

Я посмотрел на ваш код в Github. Я думаю, вам также нужно [отменить дребезг для кнопки](https://arduinogetstarted.com/tutorials/arduino-button-debounce), @Rozona Zoro

Вы спросили: «Как я могу прервать задержку () при нажатии кнопки?» Короткий ответ: вы не можете. delay() — это блокирующая функция. Это не может быть прервано. Вам нужно реорганизовать свой код, как предложили другие., @Duncan C

Вы можете, если обработаете нажатие кнопки в обработчике прерывания смены контакта. Но все же использовать delay() — плохая практика. Единственное законное использование — это синхронизированная последовательность, когда вы больше ничего не делаете., @Kwasmich


1 ответ


Лучший ответ:

1

Вы можете использовать функцию millis, чтобы проверить текущее "время". Если вы сохраните это, а затем снова вызовете эту функцию, вычитая, вы можете увидеть, сколько времени прошло. поэтому вместо delay(500) вы используете if (millis() - timeStamp >= 500) { ... для продолжения кода.

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

Изменить: устранение дребезга

Библиотеки для устранения дребезга нет (по крайней мере, на сайте Arduino), но вы можете легко скопировать нужный код из следующего скетча:

Отказ Arduino

,

Я смог использовать это решение. Я еще не реализовал debounce, но я изучаю это. Есть ли библиотека debounce или мне нужно реализовать ее самостоятельно?, @Gabe Ruiz

Я обновил свой ответ в соответствии с вашим вопросом в комментарии., @Michel Keijzers