В статье про кнопку был рассмотрен программный метод подавления дребезга. Для обработки факта нажатия/отпускания кнопки так же можно использовать прерывания. Преимущества такого способа — в отсутствии необходимости в программе постоянно контролировать уровень сигнала на входе, к которому подключена кнопка.
Для отработки состояния кнопки в прерывании нужно определить процедуру обработки и подключить ее в качестве обработчика аппаратного прерывания по какому-нибудь входу (для Arduino UNO — это pin2 (Int0) или pin3 (Int1).
#define p_Sw 2 //вход для кнопки (Int0) pin2 #define t_Dreb 50 //интервал для устраниения дребезга (мс) unsigned int n_Key = 0; //считаем число нажатий на кнопку int t_Tek = 0; //текущий отсчет времени при определении нажатия int t_Pred = 0; //предыдущий отсчет int t_T1 = 0; //длительность отсутствия реакции на кнопку int pin_Tek = 1; //состояние кнопки (0 - замкнута) void setup() { Serial.begin(9600); pinMode(p_Sw, INPUT_PULLUP); //вход с внутр.резистором на VCC attachInterrupt(0, pressK, CHANGE); //кнопка на Int0 (pin2) } void loop() { Serial.println(n_Key); delay(2000); } void pressK() //обработка прерывания от кнопки (Int0) { pin_Tek = digitalRead(p_Sw); //читаем текущее состояние pin2 (Int0) t_Tek = millis(); //текущий отсчет времени if (t_Tek > t_T1) {//если время подавления дребезга не прошло - игнорируем if (pin_Tek == 0) { //замкнуто n_Key ++; //подсчет числа нажатий t_Pred = t_Tek; //начало для определения след.периода } } t_T1 = t_Tek + t_Dreb; //определяем время отсутствия реакции }
Приведенный пример выводит в последовательный канал состояние переменной n_Key, которая наращивается при каждом нажатии и отпускании кнопки. Кнопка подключена одним контактом к входу прерываний Int0 (pin2 Arduino), а другим — к общему проводу. Функция
attachInterrupt(0, pressK, CHANGE);
назначает процедуру pressK как обработчик прерывания по этому входу (нолик в первом аргументе). CHANGE — означает, что вызов процедуры будет по любому изменению на входе (иные варианты: LOW — по нулю; RISING — по переходу из 0 в 1; FALLING — по спаду из 1 в 0).
Процедура обработки «нечувствительна» к измениям на входе в течение времени t_Dreb (задано 50мс) после первого срабатывания, тем самым «как-бы подавляя дребезг контактов кнопки»).
Надо сказать, что подключение кнопки к входу прерываний — «дурной тон». Слишком уж непредсказуем дребезг контактов: процедура может быть вызвана слишком большое число раз :(. Но в не слишком ответственных системах можно поступить и так. Этот метод использован в конструкции велоспидометра…
Когда Вы вызываете прерывание , у Вас другие прерывание запрещены! и мы не можем получить адекватность данных от фун. millis () таким способом от дребезга не избавиться. тем паче Вы вызываете прерывание 0 которое как раз отвечает за таймер 0 , если я правильно думаю.
Вызываемое прерывание никак не связано с таймером 0. Millis() просто считывает значение наращиваемой в прерывании от таймера переменной — так что значение времени будет актуальным («щелочка» для прерывания от таймера всегда найдется).
Упоминаемая статья в Радио описывает велоспидометр, где использован такой подход — устройство рабочее и показывает адекватные результаты (а статья даже получила поощрительный приз среди лучших в 2015 году 🙂