Menu
CoddyTech

Подсчёт нажатий с помощью прерывания

Часть раздела Отсчёт времени без delay путешествия по Arduino на Coddy. Урок 15 из 18.

Как вы увидели в разделе «Входы», кнопки дребезжат: примерно в течение миллисекунды контакты соприкасаются, размыкаются и снова соприкасаются при нажатии и отпускании. Прерывание видит каждое соприкосновение, поэтому ISR FALLING, который увеличивает счётчик на 1, несколько раз засчитывает один щелчок.

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

unsigned long lastPress = 0;

void onPress() {
  unsigned long now = millis();
  if (now - lastPress >= 200) {
    presses = presses + 1;
    lastPress = now;
  }
}

Считывать millis() в ISR можно: функция возвращает время начала ISR. Выберите интервал длиннее щелчка, чтобы дребезг при отпускании попадал в него, и короче промежутка между двумя быстрыми щелчками. Для людей подходит 200 мс.

challenge icon

Задание

Средне

Этот счётчик считает каждый щелчок несколько раз. Устраните дребезг внутри onPress():

  • добавьте переменную unsigned long lastPress
  • считайте спад только в том случае, если с момента lastPress прошло не менее 200 ms, а затем сохраните время в lastPress

Нажмите Запустить, несколько раз нажмите кнопку и следите за счётчиком, затем нажмите Проверить.

Попробуйте сами

const int buttonPin = 2;

volatile int presses = 0;
int shown = 0;

void onPress() {
  // каждый спад сигнала на выводе учитывается, включая дребезг контактов: подавите его здесь
  presses = presses + 1;
}

void setup() {
  pinMode(buttonPin, INPUT_PULLUP);
  Serial.begin(9600);
  attachInterrupt(digitalPinToInterrupt(buttonPin), onPress, FALLING);
}

void loop() {
  // выводите счётчик при каждом его изменении
  if (presses != shown) {
    shown = presses;
    Serial.println(shown);
  }
}
quiz iconПроверьте себя

В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.

Все уроки раздела Отсчёт времени без delay

Потренируйтесь самостоятельно: Песочница Arduino