В этом эксперименте мы делаем из тактовой кнопки триггер, борясь с «дребезгом». 
 
СПИСОК ДЕТАЛЕЙ ДЛЯ ЭКСПЕРИМЕНТА
  
-   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   |