Неожиданное увеличение/уменьшение кнопки. Я использую attachInterrupt

Я новичок в Arduino и нуждаюсь в помощи знающих людей. У меня проблема с моим кодом, который позволяет пользователю увеличивать или уменьшать число, нажимая кнопки. Время от времени число меняется не на единицу, а на две или три. Это происходит спорадически. Это известно как "подпрыгивание". Я напрасно гуглил "attachInterrupt debounce", но не смог найти подходящего решения. Мой код здесь.

int digit_state = 0;
void increment(void){
  digit_state = digit_state + 1;
  }
void decrement(void){
  digit_state = digit_state - 1;  
  }
String user_input = "";
String password = "3452";
int enterbutton = 11;
int increment_button = 2;
int decrement_button = 3;
int counter = 0;
void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  pinMode(enterbutton,INPUT);
  attachInterrupt(digitalPinToInterrupt(increment_button),increment,FALLING);
  attachInterrupt(digitalPinToInterrupt(decrement_button),decrement,FALLING);
}

void loop() {
  // put your main code here, to run repeatedly:
  lastButtonState = reading;
  while(counter<=3){
    delay(500);
    Serial.println(digit_state);
    if(digitalRead(enterbutton)==LOW){
      user_input = user_input + digit_state;
      Serial.println("Saved input so far is "+user_input);
      if(user_input == password){
        Serial.println("検証できた");
      }
      delay(500);
      digit_state = 0;
      counter++;
  }
}
}

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

, 👍1


1 ответ


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

1

Во-первых: нет необходимости использовать прерывания для кнопок, потому что, когда люди нажимают кнопки, они будут активированы по крайней мере в течение примерно 100 мс, что очень медленно для микроконтроллера. Вам просто нужно будет переписать свой код, чтобы он не блокировался (например, отключив все вызовы delay() и вместо этого используя millis (), как в примере BlinkWithoutDelay, который поставляется с Arduino IDE). Затем вы также можете использовать существующие библиотеки для отмены, такие как Bounce2.


Очень простым подходом было бы установить тайм-аут после каждого нажатия кнопки, при котором не будет регистрироваться новое нажатие кнопки, например, 10 мс (должно быть достаточно для отмены, хотя вы можете проверить свою настройку самостоятельно). Это можно сделать с помощью функции millis (), сохранив отметку времени последнего нажатия кнопки:

#define DEBOUNCE_TIME  10
volatile unsigned long button_press_timestamp = 0;

void increment(void){
  if(millis()-button_press_timestamp > DEBOUNCE_TIME){
      digit_state = digit_state + 1;
      button_press_timestamp = millis();
  }
}

Сначала в глобальной области мы определяем наше время отмены и переменную для удержания метки времени, когда было зарегистрировано последнее нажатие кнопки. В ISR (здесь только инкремент() в качестве примера) мы затем проверяем разницу между этой меткой времени и текущим временем. Если это больше, чем время отмены, мы выполняем действие кнопки (в данном случае увеличивающееся). Затем мы обновляем метку времени до текущего времени.

При нажатии на кнопку первый падающий край вызовет действие кнопки. Любые выпадающие края от отскока появятся во время отмены и, таким образом, будут проигнорированы (ISR вызывается, но код в операторе if не выполняется).

Этот принцип отмены не идеален, но его легко реализовать, и вам этого может быть достаточно.

,

Спасибо вам за решение., @Joshua