Нажать одну кнопку, потом другую?

Допустим, у нас есть две кнопки - кнопка 1 и кнопка 2. Что мне нужно сделать, так это что-то сделать (например, включить светодиод), когда кнопка 1 нажата, а затем нажата кнопка 2. Я могу сделать это очень просто, просто используя две логические переменные, но как мы можем определить, что кнопка 1 была нажата первой?

, 👍1

Обсуждение

Посмотрите, что такое «конечный автомат». Используйте прерывания или digitalRead для проверки состояния кнопок., @MichaelT


1 ответ


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

2

Хорошим решением является использование переменной состояния. В C/C++ (таким образом, Arduino) вы можете использовать для этого переменную enum.

enum EState
{
  // Кнопки 1 и 2 не нажаты
  NoButtonsPressed,

  // Кнопка 1 нажата, кнопка 2 не нажата
  FirstButtonPressed,

  // Обе кнопки нажаты
  BothButtonsPressed
};

EState _state;


void setup() {
  // поместите сюда код установки для однократного запуска:
  _state = NoButtonsPressed;
}

void loop() {
  // поместите сюда ваш основной код для многократного запуска:
  switch (_state)
  {
  case NoButtonsPressed:
    if (digitalRead(1) == HIGH)
    {
      _state = FirstButtonPressed;
    }
    break;

  case FirstButtonPressed:
    if (digitalRead(1) == HIGH)
    {
      // Кнопка 1 все еще нажата, вторую кнопку игнорируем.
    } 
    else if (digitalRead(2) == HIGH)
    {
      // Кнопка 1 не нажата, кнопка 2 нажата.
      _state = BothButtonsPressed;
    }
    break;

 case BothButtonsPressed:
   // Включаем светодиод
   digitalWrite(2, HIGH);

   // Сбросить состояние.
   _state = NoButtonsPressed;
   break;

 default:
   // Другое состояние, незаконное.
   break;
  }
}

В каждом состоянии вы можете точно определить, что нужно сделать. Поскольку функция цикла выполняется непрерывно, вам нужно обрабатывать только одно состояние (изменение) за раз.

Дополнительные примечания:

  • Ваши требования не полностью выполнены (например, когда выключать светодиод), возможно, когда кнопка 2 будет отпущена (что я не проверяю), вы можете добавить для этого новое состояние.
  • Я не учитывал дребезг кнопок; вам может понадобиться сделать это, особенно если вы проверяете отпускание кнопок. На официальном сайте Arduino есть хорошая статья об этом.
  • Я не тестировал скетч.
,

Спасибо! Это решение великолепно! :), @Svetoslav Nedelchev

Хороший чистый ответ. (проголосовало), @Duncan C

Похоже, что в этом коде не должно быть проблем с подпрыгиванием кнопок, поскольку он игнорирует нажатия кнопок, если только он не находится в состоянии ожидания нажатия этой кнопки, а затем переходит в новое состояние, в котором он будет игнорировать это нажатие кнопки и ждать следующего. Как вы говорите, если вы углубитесь в детали, например, будете реагировать на отпускание кнопок, потребуется устранение дребезга., @Duncan C

@DuncanC Спасибо за голосование и комментарий. В приведенном выше примере устранение дребезга не является строго необходимым, хотя я могу предположить, что пользователь хочет, чтобы светодиод выключался после отпускания второй кнопки, без устранения дребезга светодиод будет гореть в течение мс или меньше после нажатия второй кнопки, потому что вторая кнопка будет нажата (светодиод загорится) и отскочит назад (светодиод погаснет). Если требования заключаются в том, что светодиод должен гореть до тех пор, пока не будет нажата первая кнопка, то устранение дребезга не является строго необходимым., @Michel Keijzers