Рис. 9.12. Дребезг при нажатии кнопки
Кнопка физически нажата в течении 25 мс. Вы могли бы предполагать, что можете сразу узнать о состоянии кнопки, считав значение с входа контакта, как показано на левом графике. Однако кнопка фактически возвращается вверх-вниз, пока значение не установится, как показано на правом графике. Теперь, зная как ведет себя кнопка, Вы можете написать программное обеспечение кнопки с дребезгом, которое ищет изменение состояния кнопки, ожидает возврата, чтобы закончиться, и затем читает состояние переключателя снова. Эта логика программы может быть выражена следующим образом:
1) сохраняем предыдущее состояние кнопки и текущее состояние кнопки (при инициализации LOW);
2) считываем текущее состояние кнопки;
3) если текущее состояние кнопки отличается от предыдущего состояния кнопки, ждем 5 мс, потому что кнопка, возможно, изменила состояние;
4) После 5 мс, считываем состояние кнопки и используем его в качестве текущего состояния кнопки;
5) если предыдущее состояние кнопки было LOW, а текущее состояние кнопки HIGH, переключаем состояние светодиода;
6) установливаем предыдущее состояние кнопки для текущего состояния кнопки;
7) возврат к шагу 2.
Составляем скетч по вышеприведенному алгоритму (см. листинг 1.8), загружаем на плату Arduino и проверяем. Однократное нажатие кнопки приводит к однократному изменению состояния светодиода.
Листинг 9.2.
// Контакт 13 для подключения светодиода
int LED=13;
// Контакт 2 для подключения кнопки
int BUTTON=2;
// Переменная для сохранения предыдущего состояния кнопки
boolean lastButton = LOW;
// Переменная для сохранения текущего состояния кнопки
boolean currentButton = LOW;
// Текущее состояние светодиода (включен/выключен)
boolean ledOn = false;
void setup() {
// Сконфигурировать контакт светодиода как выход
pinMode (LED, OUTPUT);
// Сконфигурировать контакт кнопки как вход
pinMode (BUTTON, INPUT);
}
void loop() {
currentButton = debounce(lastButton);
// если нажатие...
if (lastButton == LOW && currentButton == HIGH)
{
// инвертировать значение состояния светодиода
ledOn = !ledOn;
Serial.println(ledOn);
}
lastButton = currentButton;
// изменить статус состояния светодиода
digitalWrite(LED, ledOn);
}
// Функция сглаживания дребезга
// Принимает в качестве аргумента предыдущее состояние кнопки,
// выдает фактическое.
boolean debounce(boolean last) {
// Считать состояние кнопки
boolean current = digitalRead(BUTTON);
if (last != current) // если изменилось...
{
// ждем 5мс
delay(5);
// считываем состояние кнопки
current = digitalRead(BUTTON);
// возвращаем состояние кнопки
return current;
}
}
Загрузим данный скетч на плату Arduino и проверяем правильность работы.
Скачать данный скетч 09_02.ino можно по ссылке https://amegakit.ru/libraries/lib_Lab_Om-Robot.zip