Подсчёт нажатий с помощью прерывания
Часть раздела Отсчёт времени без 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 мс.
Задание
СреднеЭтот счётчик считает каждый щелчок несколько раз. Устраните дребезг внутри 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);
}
}
В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Отсчёт времени без delay
1millis()
Часы на millis()Время в unsigned longМигание без задержкиДва светодиода, две скоростиМигание и переключение кнопкойСвет по таймеру4Точное измерение времени
Измерение с помощью micros()Когда millis() переполняетсяСекундомер с кнопкой3Прерывания
Нажатие, которое пропускает циклFALLING, RISING и CHANGEОбщий доступ с volatileПодсчёт нажатий с помощью прерыванияПотренируйтесь самостоятельно: Песочница Arduino