В этом эксперименте мы делаем из тактовой кнопки триггер, борясь с «дребезгом».
СПИСОК ДЕТАЛЕЙ ДЛЯ ЭКСПЕРИМЕНТА
- 1 плата Arduino Uno;
- 1 беспаечная макетная плата;
- 1 тактовая кнопка;
- 1 резистор номиналом 220 Ом;
- 1 светодиод;
- 5 проводов «папа-папа».
ДЕТАЛИ ДЛЯ ДОПОЛНИТЕЛЬНОГО ЗАДАНИЯ
- еще 1 кнопка;
- еще 2 провода.
ПРИНЦИПИАЛЬНАЯ СХЕМА
СХЕМА НА МАКЕТНОЙ ПЛАТЕ
ОБРАТИТЕ ВНИМАНИЕ
- Мы могли бы один из контактов кнопки соединить проводом напрямую с одним из входов GND, но мы сначала «раздали» «землю» на длинную рельсу макетки. Если мы работаем с макетной платой, так поступать удобнее, т.к. в схеме могут появляться новые участки, которые тоже нужно будет соединить с «землей»
- Также полезно руководствоваться соображениями аккуратности изделия, поэтому катод светодиода мы соединяем с другим входом GND отдельным проводом, который не мешает нам работать в середине макетки.
СКЕТЧ
скачать скетч для Arduino IDE
#define BUTTON_PIN 3
#define LED_PIN 13
boolean buttonWasUp = true; // была ли кнопка отпущена?
boolean ledEnabled = false; // включен ли свет?
void setup()
{
pinMode(LED_PIN, OUTPUT);
pinMode(BUTTON_PIN, INPUT_PULLUP);
}
void loop()
{
// определить момент «клика» несколько сложнее, чем факт того,
// что кнопка сейчас просто нажата. Для определения клика мы
// сначала понимаем, отпущена ли кнопка прямо сейчас...
boolean buttonIsUp = digitalRead(BUTTON_PIN);
// ...если «кнопка была отпущена и (&&) не отпущена сейчас»...
if (buttonWasUp && !buttonIsUp) {
// ...может это «клик», а может и ложный сигнал (дребезг),
// возникающий в момент замыкания/размыкания пластин кнопки,
// поэтому даём кнопке полностью «успокоиться»...
delay(10);
// ...и считываем сигнал снова
buttonIsUp = digitalRead(BUTTON_PIN);
if (!buttonIsUp) { // если она всё ещё нажата...
// ...это клик! Переворачиваем сигнал светодиода
ledEnabled = !ledEnabled;
digitalWrite(LED_PIN, ledEnabled);
}
}
// запоминаем последнее состояние кнопки для новой итерации
buttonWasUp = buttonIsUp;
}
ПОЯСНЕНИЯ К КОДУ
- Поскольку мы сконфигурировали вход кнопки как
INPUT_PULLUP , при нажатии на кнопку на данном входе мы будем получать 0. Поэтому мы получим значение true («истина») в булевой переменной buttonIsUp («кнопка отпущена»), когда кнопка отпущена.
- Логический оператор
&& («и») возвращает значение «истина» только в случае истинности обоих его операндов. Взглянем на так называемую таблицу истинности для выражения buttonWasUp && !buttonIsUp («кнопка была отпущена и кнопка не отпущена»):
Здесь рассмотрены все возможные сочетания предыдущего и текущего состояний кнопки и мы видим, что наш условный оператор if сработает только в случае, когда кнопка нажата только что: предыдущее состояние 1 («была отпущена»), а текущее 0 («не отпущена»).
- Через 10 миллисекунд мы проверяем еще раз, нажата ли кнопка: этот интервал больше, чем длительность «дребезга», но меньше, чем время, за которое человек успел бы дважды нажать на кнопку. Если кнопка всё еще нажата, значит, это был не дребезг.
- Мы передаем в
digitalWrite не конкретное значение HIGH или LOW , а просто булеву переменную ledEnabled . В зависимости от того, какое значение было для нее вычислено, светодиод будет зажигаться или гаситься.
- Последняя инструкция в
buttonWasUp = buttonIsUp сохраняет текущее состояние кнопки в переменную предыдущего состояния, ведь на следующей итерации loop текущее состояние уже станет историей.
ВОПРОСЫ ДЛЯ ПРОВЕРКИ СЕБЯ
- В каком случае оператор
&& возвращает значение «истина»?
- Что такое «дребезг»?
- Как мы с ним боремся в программе?
- Как можно избежать явного указания значения уровня напряжения при вызове
digitalWrite ?
ЗАДАНИЯ ДЛЯ САМОСТОЯТЕЛЬНОГО РЕШЕНИЯ
- Измените код так, чтобы светодиод переключался только после отпускания кнопки.
- Добавьте в схему еще одну кнопку и доработайте код, чтобы светодиод зажигался только при нажатии обеих кнопок.
С оригиналом статьи вы можете ознакомиться на сайте Amperka.ru
ЭКСПЕРИМЕНТ 9 | ОГЛАВЛЕНИЕ | ЭКСПЕРИМЕНТ 11 |