управление несколькими кнопками в Arduino - PullRequest
0 голосов
/ 23 декабря 2018

Так что мой вопрос больше о поиске элегантного решения.У меня есть несколько кнопок, подключенных к Arduino, которые работают по отдельности.Для простоты просто посмотрите на два.Я хочу разные действия при нажатии кнопок A, B и A + B одновременно (AB).Я могу проверить, какие кнопки были нажаты в данный момент, и выполнить действие, проблема в том, что сначала всегда нажимается одна кнопка, поэтому метод вызывается немедленно, и у меня нет действительно детерминированного поведения.Что я сделал, так это установил задержку и проверил, нажата ли другая кнопка в заданное время:

void loop() {

delay(100);
A = digitalRead(ButtonA);
B = digitalRead(ButtonB);
if (A == 0) {
    delay(150);
    B = digitalRead(ButtonB);
    if (B == 0) {
        doAB();
    }
    else {
        doA();
    }
}

A = digitalRead(ButtonA);
B = digitalRead(ButtonB);
if (B == 0) {
    delay(150);
    A = digitalRead(ButtonA);
    if (A == 0) {
        doAB();
    }
    else {
        doB();
    }
}

}

Проблема в том, что этот код зависит от поведения нажатия кнопки.Я уверен, что смогу найти достаточное решение с большим количеством испытаний и проверкой того, что нажимается когда.Хотя с большим количеством кнопок это, кажется, дает очень много вложений, и я думаю, что многие люди имели эту проблему раньше при разработке прошивки.Поэтому мой вопрос заключается в том, если и как это можно сделать более чистым способом.

misc:

Если кто-то держит кнопки, я хочу, чтобы это действие повторялось снова и снова.

Кодирование выполняется на C ++.

doA, B, действия AB занимают некоторое время (1-2 с).

Ответы [ 3 ]

0 голосов
/ 23 декабря 2018

это должно сделать то же самое (или лучше), что и ваша версия

void loop() {
  delay(100);
  A = digitalRead(ButtonA);
  B = digitalRead(ButtonB);
  if (A == 0 || B == 0) {
      delay(150);
      A = digitalRead(ButtonA);
      B = digitalRead(ButtonB);
      if (A == 0 && B == 0) {
          doAB();
      } else if (A == 0) {
          doA();
      } else {
          doB();
      }
  }
}
0 голосов
/ 23 декабря 2018

Попробуйте объединить все состояния кнопок в одну переменную, например:

int allBtnStates;
unsigned long btnTimeStamp = 0;
void loop() {
  A = digitalRead(ButtonA);
  B = digitalRead(ButtonB);
  allBtnStates = A + 2*B;
  if(allBtnStates < 3){ //Any button pressed
    if(btnTimeStamp == 0) btnTimeStamp = millis(); //Create timestamp
    else if(millis() - btnTimeStamp > 150){
      switch(allBtnStates){
        case 2: doA(); break; //Only A pressed
        case 1: doB(); break; //Only B pressed
        case 0: doAB(); break; //Both A and B pressed
      }
      btnTimeStamp = 0; //Reset timestamp
    }
  }
  //Monitor other input if needed
}

Если у вас есть кнопка C, измените allBtnStates = A + 2*B; на allBtnStates = A + 2*B + 4*C; и выполните все условия соответственно.Надеюсь, это поможет!

0 голосов
/ 23 декабря 2018

Что делать, если у вас есть коллекция объектов Button.Каждая кнопка имеет свойство «нажатие» и открытый метод установки, который позволяет клиентам (вашему циклу) устанавливать только true.В вашем цикле вы перебираете коллекцию Button каждый раз, проверяя «digitalRead» для каждой кнопки.Как только по крайней мере 1 кнопка возвращает 0 (нажата), вы запускаете таймер в цикле, скажем, на 150 мс, которые вы используете.Естественно, вы устанавливаете каждую соответствующую кнопку нажатой.Во время обратного отсчета таймера могут быть установлены и другие кнопки.Единицы, которые были ранее установлены, остаются установленными, даже если их digitalRead становится высоким.По истечении 150 мс задержки вы соберете все нажатия кнопок одновременно.Вызвать метод «doAB» для любой комбинации - doA, doACF, doBEK и т. Д. Очистить таймер и сделать все нажатия кнопок ложными.Эта последняя часть может произойти, когда вы собираете статус прессы.Теперь ваша логика ответа происходит только в одном месте.

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

...