Подключение кнопки. Подключение кнопки к Arduino Виды тактовых кнопок
Подключение датчика кнопки к ардуино требует определенных знаний и навыков. В этой статье мы поговорим о том, что такое тактовая кнопка, что такое дребезг кнопки, как правильно подключать кнопку с подтягивающим и стягивающим резистором, как можно управлять с помощью кнопки светодиодами и другими устройствами.
Кнопка (или кнопочный переключатель) – самый простой и доступный из всех видов датчиков. Нажав на нее, вы подаете контроллеру сигнал, который затем приводит к каким-то действиям: включаются светодиоды, издаются звуки, запускаются моторы. В своей жизни мы часто встречаемся с разными выключателями и хорошо знакомы с этим устройством.
Тактовые кнопки и кнопки-переключатели
Как обычно, начинаем раздел с простых вещей, интересных только начинающим. Если вы владеете азами и хотите узнать о различных вариантах подключения кнопки к ардуино – можете пропустить этот параграф.
Что такое кнопка? По сути, это достаточно простое устройство, замыкающее и размыкающее электрическую сеть. Выполнять это замыкание/размыкание можно в разных режимах, при этому фиксировать или не фиксировать свое положение. Соответственно, все кнопки можно поделить на две большие группы:
- Кнопки переключатели с фиксацией. Они возвращаются в исходное состояние после того, как их отпустили. При в зависимости от начального состояния разделяют на нормально-замкнутые и нормально-разомкнутые кнопки.
- Кнопки без фиксации (тактовые кнопки). Они фиксируются и остаются в том положении, в котором их оставили.
Вариантов различных кнопок великое множество, это действительно один из самых распространенных видов электронных компонентов.








Кнопки ардуино для простых проектов
В наших проектах мы будем работать с очень простыми тактовыми кнопками с 4 ножками, которые идут практически в любом наборе ардуино. Кнопка представляет собой переключатель с двумя парами контактов. Контакты в одной паре соединены между собой, поэтому больше одного выключателя в схеме реализовать не удастся, но вы можете одновременно управлять двумя параллельными сегментами, это бывает полезно.
В зависимости от ситуации, вы можете создавать как схемы с нормально замкнутыми, так и с нормально разомкнутыми контактами – для этого нужно будет только соответствующим образом выполнить соединение в схеме.
Для удобства работы в комплекте с тактовой кнопкой обычно идет пластмассовый колпачок какого-то цвета, он достаточно очевидно надевается на кнопку и придает проекту менее хакерский вид.
Подключение кнопки Ардуино
Включение и выключение светодиода с помощью кнопки
Давайте начнем с самого простого способа подключения тактовой кнопки. Рассмотрим схему с Arduino в качестве источника питания, светодиода, ограничительного резистора номиналом 220 Ом и кнопки, которая будет замыкать и размыкать цепь.
При подключении кнопки с двумя парами ножек важно правильно выбрать размыкающие контакты. Посмотрите на изображение внимательно: пары ножек расположены по бокам кнопки. Сама кнопка квадратная, но расстояния между парами контактов визуально заметны: можно сразу выделить два на одной стороне и два а другой. Так вот, именно между одной «парой» на стороне и будет реализован выключатель. Для включения в схему мы соединяемся с одним и с другим контактом, между которыми минимальное расстояние. Вторая пара контактов просто дублирует первую.


Если у вас переключатель другого типа, то можете смело выбрать контакты с противоположных углов (на некоторых кнопка делается специальный знак в виде выемки, по которому можно определить, с какой стороны расположены спаренные контакты). Самый надежный способ определить правильные ножки – это прозвонить контакты тестером.
Сама схема с кнопкой, светодиодом и контроллером Arduino не нуждается в особых пояснениях. Кнопка разрывает цепь, светодиод не горит. При нажатии цепь замыкается, светодиод включается. Если вы перепутаете контакты (включите через замкнутые спаренные контакты кнопки), то кнопка работать не будет, потому что цепь никогда не разомкнется. Просто поменяйте контакты местами.
Подключение кнопки с подтягивающим резистором
Давайте теперь подключим кнопку к ардуино так, чтобы можно было считывать в скетче ее состояние. Для этого воспользуемся следующей схемой.
Мигание светодиода после нажатия на кнопку
В предыдущем примере со светодиодами мы подключили кнопку к плате ардуино и поняли, как она работает. Светодиод включался и выключался, но делал это в совершенно пассивном режиме – сам контроллер здесь был абсолютно лишним, его можно было бы заменить батарейками. Поэтому давайте сделаем наш новый проект более «интеллектуальным»: при нажатии на кнопку заставим светодиод непрерывно мигать. Обычной схемой с лампочкой и выключателем этого уже не сделаешь – мы будем использовать мощь нашего микроконтроллера для решения этой пусть и простой, но не тривиальной задачи.
Фрагмент схемы со светодиодом уже хорошо нам знаком. Мы собрали обычный маячок со светодиодом и ограничительным резистором. А вот во второй части мы видим знакомую нам кнопку и еще один резистор. Пока не будем вдаваться в подробности, просто соберем схему и закачаем в ардуино простой скетч. Все элементы схемы идут в самых простых стартовых наборах ардуино.
/* Скетч для схемы с использованием тактовой кнопки и светодиода Светодиод мигает, пока нажата кнопка. Кнопка подтянута к земле, нажатию соответствует HIGH на входе */ const int PIN_BUTTON = 2; const int PIN_LED = 13; void setup() { Serial.begin(9600); pinMode(PIN_LED, OUTPUT); } void loop() { // Получаем состояние кнопки int buttonState = digitalRead(PIN_BUTTON); Serial.println(buttonState); // Если кнопка не нажата, то ничего не делаем if (!buttonState) { delay(50); return; } // Этот блок кода будет выполняться, если кнопка нажата // Мигаем светодиодом digitalWrite(PIN_LED, HIGH); delay(1000); digitalWrite(PIN_LED, LOW); delay(1000); }
Нажимаем и держим – светодиод мигает. Отпускаем – он гаснет. Именно то, что хотели. Хлопаем от радости в ладоши и приступаем к анализу того, что сделали.
Давайте посмотрим на скетч. В нем мы видим довольно простую логику.
- Определяем, нажата ли кнопка.
- Если кнопка не нажата, то просто выходим из метода loop, ничего не включая и не меняя.
- Если кнопка нажата, то выполняем мигание, используя фрагмент стандартного скетча:
- Включаем светодиод, подавая напряжение на нужный порт
- Делаем нужную паузу при включенном светодиоде
- Выключаем светодиод
- Делаем нужную паузу при выключенном светодиоде
Логика поведения кнопки в скетче может зависеть от способа подключения с подтягивающим резистором. Об этом мы поговорим в следующей статье.
Дребезг кнопки ардуино
В процессе работы с кнопками мы можем столкнуться с очень неприятным явлением, называемым дребезгом кнопки. Как следует из самого названия, явление это обуславливается дребезгом контактов внутри кнопочного переключателя. Металлические пластины соприкасаются друг с другом не мгновенно (хоть и очень быстро для наших глаз), поэтому на короткое время в зоне контакта возникают скачки и провалы напряжения. Если мы не предусмотрим появление таких “мусорных” сигналов, то будем реагировать на них каждый раз и можем привести наш проект к хаусу.
Для устранения дребезга используют программные и аппаратные решения. В двух словах лишь упомянем основные методы подавления дребезга:
- Добавляем в скетче паузу 10-50 миллисекунд между полкучением значений с пина ардуино.
- Если мы используем прерывания, то программный метд использоваться не может и мы формируем аппаратную защиту. Простейшая из них – RC фильтр с конденсатором и сопротивлением.
- Для более точного подавления дребезга используется аппаратный фильтр с использованием триггера шмидта. Этот вариант позволит получить на входе в ардуино сигнал практически идеальной формы.
Более подробную информацию о способах борьбы с дребезгом вы можете найти в этой .
Переключение режимов с помощью кнопки
Для того, чтобы определить, была ли нажата кнопка, надо просто зафиксировать факт ее нажатия и сохранить признак в специальной переменной.
Факт нажатия мы определяем с помощью функции digitalRead(). В результате мы получим HIGH (1, TRUE) или LOW(0, FALSE), в зависимости от того, как подключили кнопку. Если мы подключаем кнопку с помощью внутреннего подтягивающего резистора, то нажатие кнопки приведет к появлению на входе уровня 0 (FALSE).
Для хранения информации о нажатии на кнопку можно использовать переменную типа boolean:
boolean keyPressed = digitalRead(PIN_BUTTON)==LOW;
Почему мы используем такую конструкцию, а не сделали так:
boolean keyPressed = digitalRead(PIN_BUTTON);
Все дело в том, что digitalRead() может вернуть HIGH, но оно не будет означать нажатие кнопки. В случае использования схемы с подтягивающим резистором HIGH будет означать, что кнопка, наоборот, не нажата. В первом варианте (digitalRead(PIN_BUTTON)==LOW) мы сразу сравнили вход с нужным нам значением и определили, что кнопка нажата, хотя и на входе сейчас низкий уровень сигнала. И сохранили в переменную статус кнопки. Старайтесь явно указывать все выполняемые вами логические операции, чтобы делать свой код более прозрачным и избежать лишних глупых ошибок.
Как переключать режимы работы после нажатия кнопки?
Часто возникает ситуация, когда мы с помощью кнопок должны учитывать факт не только нажатия, но и отпускания кнопки. Например, нажав и отпустив кнопку, мы можем включить свет или переключить режим работы схемы. Другими словами, нам нужно как-то зафиксировать в коде факт нажатия на кнопку и использовать информацию в дальнейшем, даже если кнопка уже не нажата. Давайте посмотрим, как это можно сделать.
Логика работы программы очень проста:
- Запоминаем факт нажатия в служебной переменной.
- Ожидаем, пока не пройдут явления, связанные с дребезгом.
- Ожидаем факта отпускания кнопки.
- Запоминаем факт отпускания и устанавливаем в отдельной переменной признак того, что кнопка была полноценно нажата.
- Очищаем служебную переменную.
Как определить нажатие нескольких кнопок?
Нужно просто запомнить состояние каждой из кнопок в соответствующей переменной или в массиве ардуино. Здесь главное понимать, что каждая новая кнопка – это занятый пин. Поэтому если количество кнопок у вас будет большим, то возможно возникновение дефицита свободных контактов. Альтернативным вариантом является использование подключения кнопок на один аналоговый пин по схеме с резистивным делителем. Об этом мы поговорим в следующих статьях.
Кнопка — всем известное механическое устройство, которое может замыкать и размыкать электрическую цепь по желанию человека. Есть множество видов кнопок, работающих по разным правилам. Например, тактовая кнопка (push button), используемая в этом уроке, замыкает цепь только пока палец давит на неё. Кнопка на размыкание, напротив, разрывает цепь при нажатии.
Есть кнопки с группой контактов, одни из которых рвут цепь при нажатии, а другие в это время замыкают. Маленькие версии таких кнопок часто называют микропереключателями.
Тактовые кнопки, можно найти практически в каждом электронном приборе: в клавиатуре компьютера, в телефоне, в пульте от телевизора, и т.д.

Есть кнопки с фиксацией, работающие как кнопка на шариковой ручке: один раз нажали — цепь замкнулась, второй раз — разорвалась. На фото ниже как раз одна из таких. Кнопки с фиксацией удобно использовать для переключения режима работы устройства. Например, можно переключать источник питания: батарея, или блок питания.

Или другой вариант — большие кнопки для экстренной остановки оборудования. Они окрашены в яркие цвета, чтобы привлекать внимание человека. По сути — обычные тактовые кнопки на размыкание, или кнопки с фиксацией.

Это лишь некоторые варианты. Кроме кнопок, в мире электричества есть и другие механизмы, например, тумблеры и рубильники. Все они призваны механически управлять течением тока в цепи.
Подключение кнопки
Итак, мы будем работать с самой простой тактовой кнопкой, которую попробуем подключить к Ардуино Уно . Обычно, при работе с беспаечными макетными платами используется кнопка с выводами под пайку. На фото в начале урока видно, что у такой кнопки есть четыре немного загнутых вывода. Есть кнопки и с двумя прямыми выводами, они тоже подходят для наших занятий.
На электрических схемах кнопка изображается так:
![]()
Если посмотреть внутрь четырехтактной кнопки, то можно увидеть вот такую схему:

Как правило, выводы тактовой кнопки размещаются на противоположных сторонах корпуса парами. То есть мы можем использовать либо пару контактов на одной стороне, либо пару на другой.
А вот так выглядит схема двухконтактной кнопки.

С этой кнопкой сложно запутаться: два контакта, которые соединяются при нажатии кнопки.
На макетной плате оба типа тактовых кнопок обычно ставятся следующим образом:

Теперь попробуем собрать на беспаечной макетной плате самую простую цепь, которая продемонстрирует работу кнопки. Будем зажигать светодиод.

Полученная схема выполняет нехитрую функцию: нажимаем на кнопку — светодиод зажигается, отпускаем — гаснет.
Подключение к Ардуино Уно
Теперь, когда функция тактовой кнопки предельно ясна, соберем схему с кнопкой и светодиодом, и подключим их к контроллеру. Поставим перед собой простую задачу: пусть при однократном нажатии кнопки Ардуино Уно мигнет три раза светодиодом.
Принципиальная схема

Внешний вид макета

На этой схеме мы видим уже привычную цепь для . Также видим кнопку, соединенную с выводом Ардуино №3. Здесь может вполне резонно возникнуть вопрос: зачем мы соединили кнопку ещё и с землей, через резистор 10кОм? Чтобы разобраться с этим вопросом, представим что мы подключили кнопку по «наивной» схеме без всяких дополнительных резисторов.

Здесь между выводом №3 и землей изображен небольшой конденсатор, который способен накапливать заряд. Такая особенность есть у многих микроконтроллеров.
Теперь представим, что мы замыкаем кнопку. Ток начинает бежать от +5В, прямиком в контакт №3, попутно заряжая ёмкость. Ардуино успешно регистрирует нажатие кнопки. Но после того, как мы убираем палец с тактовой кнопки, вопреки нашим ожиданиями, микроконтроллер продолжает считать что кнопка нажата! Еще бы, ведь заряженный конденсатор постепенно отдает накопленный заряд в ногу №3. Это будет продолжаться до тех пор, пока ёмкость не разрядится ниже уровня логической единицы.
Подключение модуля тактовых кнопок ROC к Ардуино
Специально для ваших проектов мы в RobotClass сделали модуль из двух тактовых кнопок. На модуле уже есть необходимые резисторы и даже два светодиода для индикации нажатия кнопок.

Разберемся с подключением этого модуля к Ардуино Уно.
Принципиальная схема

Внешний вид макета

Как можно было заметить, независимо от того, какие всё-таки кнопки мы будем использовать — схема подключения не сильно меняется. Не будет менять и программа для работы с ними.
Программа для работы с кнопкой на Ардуино
Наконец, мы разобрались с нюансами нашей схемы, и готовы к написанию программы. В уроке по мы познакомились с функциями настройки выводов pinMode и функцией вывода в цифровой порт digitalWrite . На этот раз нам понадобится ещё одна важная функция, которая обеспечивает ввод информации в микроконтроллер:
DigitalRead(номер_контакта);
Эта функция возвращает логическое значение, которое Ардуино считала с заданного контакта. Это означает, что если на контакт подать напряжение +5В, то функция вернет истину* . Если контакт соединить с землей, то получим значение ложь . В языке C++, истина и ложь эквивалентны числам 1 и 0 соответственно.
Для того, чтобы интересующий нас контакт заработал в режиме ввода информации, нам нужно будет установить его в определенный режим:
PinMode(номер_контакта, INPUT);
Наконец, соберем всё вместе, и напишем программу.
Const int led = 2;
const int button = 3;
int val = 0;
void setup(){
pinMode(led, OUTPUT);
pinMode(button, INPUT);
}
void loop(){
val = digitalRead(button);
if(val == HIGH){
// цикл от 0 до 2, с шагом 1
for(int i=0; i<3; i++){
digitalWrite(led, HIGH);
delay(500);
digitalWrite(led, LOW);
delay(500);
}
}
}
Загружаем программу на Ардуино Уно, и проверяем работу программы. Если всё сделано правильно, должно получиться как на картинке:
Ну вот и всё. Теперь мы можем управлять нашими устройствами при помощи кнопок. Если вы уже прошли урок по , то мы вполне сможем сделать часы с будильником!
Программа для кнопки-триггера
Еще один пример, заслуживающий внимания — кнопка-триггер. Работает она так: один раз нажали кнопку — светодиод загорелся, второй раз нажали — потух.
Чтобы реализовать такое поведение кнопки, нам потребуется дополнительная переменная, которую часто называют «переменной состояния» или «флагом».
Const int led = 2;
const int button = 3;
int val = 0;
byte state = 0; // переменная состояния
void setup(){
pinMode(led, OUTPUT);
pinMode(button, INPUT);
}
void loop(){
// записываем в переменную val состояние кнопки
val = digitalRead(button);
// если состояние кнопки - истина, выполняем действие
if(val == HIGH){
// меняем состояние на противоположное
state = !state;
if(state == HIGH){
// если текущее состояние - истина, зажигаем светодиод
digitalWrite(led, HIGH);
} else {
// если текущее состояние - ложь, гасим светодиод
digitalWrite(led, LOW);
}
delay(300);
}
}
Загружаем программу на Ардуино и проверяем работу схемы. Быстро нажмем кнопку — светодиод зажжется. Снова нажмем — погаснет. А вот если нажать кнопку и не отпускать, то светодиод начнет мигать с периодом 600мс! Почему так? Попробуйте разобраться.
Задания
В качестве тренировки попробуем решить несколько простых задачек с кнопкой и светодиодом.
- В схеме присутствует две кнопки и один светодиод. Пусть при нажатии на первую кнопку светодиод зажигается, а при нажатии на вторую — гаснет.
- Пианино. В схеме присутствует семь кнопок кнопка и один динамик. При нажатии на каждую из семи кнопок динамик должен воспроизводить соответствующую ноту. Потребуется изучить .
- Игра «Ковбои». В схеме присутствуют две кнопки, один зуммер и два светодиода. После запуска программы зуммер должен издать короткий звук. Сразу после этого, каждый из игроков должен как можно быстрее нажать свою кнопку. У того игрока, который сделает это первым, загорится светодиод. Потребуется изучить урок про прерывания.
Мы говорили об азах программирования Arduino. Сегодня мы будем говорить о GPIO у Arduino и PWM сигналах. Мы будем использовать кнопки и управлять яркостью светодиода с помощью PWM сигнала. Также мы будем использовать функции в среде программирования Arduino.
Для начала давайте попробуем управлять светодиодом с помощью кнопки.
Нам понадобятся :
- Резистор номиналом около 100-400 ом. Для ограничения тока, который идет через светодиод, чтобы не сжечь его.
- Резистор номиналом около 10 ком. Для подтягивания логических уровней на входе Arduino. Если его не ставить то наша кнопка будет работать очень нестабильно, т.к. на входе Arduino вместо полезного сигнала будут помехи.
- Светодиод АЛ307 или любой который вам понравиться. Собственно его мы и будем зажигать.
- Тактовая кнопка IT-1102 или любая другая. Будет использоваться для управления светодиодом.
Теперь настало время собрать простую схему, можно это сделать используя отладочную плату BreadBoard или при помощи паяльника и проводов.
Светодиод подключен через токоограничительный резистор 200 ом к 10 выходу Arduino, номинал резистора можно поставить 200 ом — 500 ом, от этого будет меняться ток, идущий через светодиод и соответственно его яркость. Если вы подключите светодиод напрямую то это закончится плохо, через светодиод пойдет большой ток, в результате чего либо сам светодиод либо выход Arduino выйдет из строя. Необходимо также учесть что светодиод, это как никак диод, у него есть полярность!
Если вы подключите светодиод неправильно, он не загорится, потому что ток через него не пойдет (он просто будет закрыт). Определить полярность светодиода легко, короткая нога светодиода это минус (т.е. ноль или GND), а длинная это +.
Кнопка подключена таким образом, что в момент нажатия она скоммутирует на вход №10 Arduino +5 вольт что соответствует логической единице цифрового входа Arduino. В момент когда кнопка не нажата наш резистор номиналом 10 ком, притянет вход Arduino к GND (т.е. к нулю) и на входе Arduino стабильно будет логический ноль. Если вы не будете использовать этот подтягивающий резистор, то вполне возможна ситуация, когда будут происходить ложные срабатывания, это связанно с тем что на входе Arduino будет отсутствовать подтягивающий резистор и соответственно напряжение не будет равно нулю, оно будет хаотично меняться, что влечет за собой появление ложной логической единицы на входе Arduino.
Итак, настало время написать программу для Arduino. Для начала давайте будем держать включенным светодиод до тех пор, пока нажата кнопка. Конечно решить такую задачу очень легко без микроконтроллера, но ведь нам нужно с чего-то начать. Открываем среду программирования Arduino (как программировать Arduino подробно изложено в №1) и начинаем писать код:
/*
Мигаем светодиодом.
Будем держать включенным светодиод до тех пор, пока нажата кнопка.
*/
{
}
{
if (digitalRead(switchPin) == HIGH) // Если кнопка нажата, наша переменная switchPin будет иметь значение HIGH (логическую 1) и выполниться код на след. строке
{
digitalWrite(ledPin, HIGH); // Зажигаем светодиод, выставив логическую 1 (уровень HIGH) на выходе 13
}
else // Если кнопка не нажата выполниться код идущий ниже.
{
digitalWrite(ledPin, LOW); // Выключаем светодиод
}
}
Ну что работает?! :)
А теперь давайте усложним задачу, сделаем так, чтобы при нажатии кнопки светодиод загорался и горел до тех пор пока не нажмем еще раз и так по кругу.
Наш код для этих целей будет выглядеть так:
/*
Урок 2. GPIO, Кнопки и PWM у Arduino
Будем включать светодиод после нажатия кнопки и выключать после второго нажатия.
Этот демонстрационный код был скачан с сайта www.сайт
*/
int switchPin = 10; // Для удобства задаем имя «switchPin» для 10 вывода
int ledPin = 13; // Для удобства задаем имя «ledPin» для 13 вывода
void setup() // Блок «Setup» запускается только 1 раз при запуске Arduino, он нужен для инициализации.
{
pinMode(switchPin, INPUT); // Конфигурируем 10 вывод Arduino на вход. Т.к. мы будем считывать состояние кнопки.
pinMode(ledPin, OUTPUT); // Конфигурируем 13 вывод Arduino на выход. С помощью него мы будем включать светодиод.
}
void loop() // Блок «loop» это цикл, т.е. код который работает раз за разом бесконечно
{
if (digitalRead(switchPin) == HIGH && lastButton == LOW) // Если кнопка нажата, и последнее состояние кнопки было «не нажата», тогда выполняем следующий код
{
lastButton = HIGH; // Меняем значение lastButton на логическую единицу
}
else
{
lastButton = digitalRead(switchPin); // Устанавливаем в переменную lastButton такое же значение как в переменной switchPin
}
}
Ну как работает?! Хмм… Странно.. Иногда у нас все срабатывает как ожидается, а иногда нет… Почему так могло произойти? Всё дело в эффекте «дребезга контактов»:

Как вы видите на этой осциллограмме на самом деле наша кнопка срабатывает не идеально… И если мы с большой частотой опрашиваем кнопку, то в переходный момент мы можем считать как единицу так и ноль. Лучше было бы использовать аппаратные решения проблемы, но речь сейчас идет о нашем коде. Чтобы избежать этого дребезга нам придется доработать программу и просто ввести задержку по времени :
/*
Урок 2. GPIO, Кнопки и PWM у Arduino
Включаем/выключаем светодиод.
Будем включать светодиод после нажатия кнопки и выключать после второго нажатия и устраняем дребезг кнопок.
Этот демонстрационный код был скачан с сайта www.сайт
int switchPin = 10; // Для удобства задаем имя «switchPin» для 10 вывода
int ledPin = 13; // Для удобства задаем имя «ledPin» для 13 вывода
boolean lastButton = LOW; // В этой переменной мы будем хранить состояние кнопки во время предыдущей обработки нашего цикла, а также установим его в ноль.
boolean ledOn = false; // В этой переменной мы будем хранить состояние светодиода, чтобы мы могли переключать его
void setup() // Блок «Setup» запускается только 1 раз при запуске Arduino, он нужен для инициализации.
{
pinMode(switchPin, INPUT); // Конфигурируем 10 вывод Arduino на вход. Т.к. мы будем считывать состояние кнопки.
pinMode(ledPin, OUTPUT); // Конфигурируем 13 вывод Arduino на выход. С помощью него мы будем включать светодиод.
}
{
{
}
}
void loop() // Блок «loop» это цикл, т.е. код который работает раз за разом бесконечно
{
{
ledOn = !ledOn; // Меняем значение ledOn на противоположное
}
digitalWrite(ledPin, ledOn); // Собственно эта строчка будет зажигать и гасить светодиод
}
Я думаю теперь у всех все заработало так, как и задумывалось;)
Теперь настало время изменить нашу программу таким образом, чтобы после каждого нажатия кнопки менялась яркость светодиода, для этого мы будем использовать ШИМ сигнал или как его еще называют PWM. Если вы хотите узнать подробнее про ШИМ, можете почитать об этом в ВИКИ . А для нас на текущий момент достаточно знать лишь то, что меняя логические значения 0 и 1 в определенной последовательности можно заставить светодиод светиться по разному, но сути он просто будет по разному мигать, но так как частота миганий высокая, глазу будет казаться что он просто меняет яркость.
Но к сожалению не все выходы Arduino поддерживают PWM, поддержка PWM обозначена значком ~ рядом с номером контакта на шелкографии Arduino. Одним из таких контактов является контакт №11, а текущий наш контакт №13 не поддерживает PWM, следовательно нам нужно изменить схему подключения следующим образом:

А также внести изменения в программный код, а именно нужно изменить номер контакта и добавить использование ШИМ :
/*
Урок 2. GPIO, Кнопки и PWM у Arduino
Меняем яркость светодиода.
Будем менять яркость свечения светодиода после каждого нажатия кнопки.
Этот демонстрационный код был скачан с сайта www.сайт
*/
int switchPin = 10; // Для удобства задаем имя «switchPin» для 10 вывода
int ledPin = 11; // Для удобства задаем имя «ledPin» для 11 вывода
boolean lastButton = LOW; // В этой переменной мы будем хранить состояние кнопки во время предыдущей обработки нашего цикла, а также установим его в ноль.
int ledLevel = 0; // В этой переменной мы будем хранить яркость свечения светодиода, яркость может иметь значение от 0 до 255, в момент инициализации установим его в 0, чтобы светодиод не светился
boolean currentButton = LOW; // Переменная для нашей функции debounce
void setup() // Блок «Setup» запускается только 1 раз при запуске Arduino, он нужен для инициализации.
{
pinMode(switchPin, INPUT); // Конфигурируем 10 вывод Arduino на вход. Т.к. мы будем считывать состояние кнопки.
pinMode(ledPin, OUTPUT); // Конфигурируем 13 вывод Arduino на выход. С помощью него мы будем включать светодиод.
}
boolean debounce(boolean last) //функция для устранения дребезга контактов кнопки, будет возвращать предыдущее её состояние
{
boolean current = digitalRead(switchPin); // Пишем в current текущее состояние кнопки
if (last != current) // Проверяем изменилось ли состояние кнопки
{
delay(5); // Если да, делаем задержку 5 миллисекунд, для того чтобы кнопка перестала «дребезжать»
current = digitalRead(switchPin); // Считываем значение кнопки после паузы, сейчас дребезг уже должен пройти
}
return current; // возвращаем стабильное значение кнопки
}
void loop() // Блок «loop» это цикл, т.е. код который работает раз за разом бесконечно
{
currentButton = debounce(lastButton); // передаем в currentButton результат работы функции debounce с переданным в него состоянием кнопки
if (lastButton == LOW && currentButton == HIGH) // Проверяем была ли нажата кнопка
{
ledLevel = ledLevel + 51; // Меняем значение яркости на 51
}
lastButton = currentButton; // Устанавливаем в переменную lastButton такое же значение как в переменной currentButton
if (ledLevel > 255) ledLevel = 0; // Ограничиваем макс. значение в 255
analogWrite(ledPin, ledLevel); // Собственно эта строчка будет зажигать светодиод с нужной яркостью
}
Надеюсь у вас все заработало. Это конец урока.
Вы можете задать вопросы и спросить совета в комментариях.
Инструкция
Кнопки бывают разные, но все они выполняют одну функцию - физически соединяют (или, наоборот, разрывают) между собой проводники для обеспечения электрического контакта. В простейшем случае - это соединение двух проводников, есть кнопки, которые соединяют большее количество проводников.
Некоторые кнопки после нажатия оставляют проводники соединёнными (фиксирующиеся кнопки), другие - сразу же после отпускания размыкают цепь (нефиксирующиеся).
Также кнопки делят на нормально разомкнутые и нормально замкнутые. Первые при нажатии замыкают цепь, вторые - размыкают.
Сейчас нашёл широкое применение тип кнопок, которые называют "тактовые кнопки". Тактовые - не от слова "такт", а скорее от слова "тактильный", т.к. нажатие хорошо чувствуется пальцами. Это кнопки, которые при нажатии замыкают электрическую цепь, а при отпускании - размыкают.
Кнопка - очень простое и полезное изобретение, служащее для лучшего взаимодействия человека и техники. Но, как и всё в природе, она не идеальна. Проявляется это в том, что при нажатии на кнопку и при её отпускании возникает т.н. " " ("bounce" по-). Это многократное переключение состояния кнопки за короткий промежуток времени (порядка нескольких миллисекунд), прежде чем она примет установившееся состояние. Это нежелательное явление возникает в момент переключения кнопки из-за упругости материалов кнопки или из-за возникающих при электрическом микроискр.
Увидеть своими глазами можно с помощью Arduino, что мы и сделаем чуть позже.

Чтобы подключить нормально разомкнутую тактовую кнопку к Arduino, можно поступить самым простым способом: один свободный проводник кнопки соединить с питанием или землёй, другой - с цифровым выводом Arduino. Но, вообще говоря, это неправильно. Дело в том, что в моменты, когда кнопка не замкнута, на цифровом выводе Ардуино будут появляться электромагнитные наводки, и из-за этого возможны ложные срабатывания.
Чтобы избежать наводок, цифровой вывод обычно подключают через достаточно большой резистор (10 кОм) либо к земле, либо к питанию. В первом случае это называется " с подтягивающим резистором", во втором - "схема со стягивающим резистором". Давайте рассмотрим каждую из них.

Сначала подключим к Arduino кнопку по схеме с подтягивающим резистором. Для этого один контакт кнопки соединим с землёй, второй - с цифровым выходом 2. Цифровой выход 2 также подключим через резистор номиналом 10 кОм к питанию +5 В.

Напишем вот такой скетч для обработки нажатий кнопки и загрузим в Arduino.
Теперь встроенный светодиод на выводе 13 постоянно горит, пока не нажата кнопка. Когда нажимаем кнопку, она принимает состояние LOW, и светодиод гаснет.

Теперь соберём схему со стягивающим резистором. Один контакт кнопки соединим с питанием +5 В, второй - с цифровым выходом 2. Цифровой выход 2 подключим через резистор номиналом 10 кОм к земле.
Скетч менять не будем.

Теперь светодиод не горит, пока кнопку не нажали.

Видео по теме
Совет 2: Как избавиться от дребезга контактов при подключении кнопки к Arduino
Мы уже рассматривали подключение кнопки к Arduino и затрагивали вопрос "дребезга" контактов. Это весьма неприятное явление, которое вызывает повторные нажатия кнопки и усложняет программную обработку нажатий кнопки. Давайте же поговорим о том, как избавиться от дребезга контактов.

Вам понадобится
- - Arduino;
- - тактовая кнопка;
- - резистор номиналом 10 кОм;
- - светодиод;
- - соединительные провода.
Инструкция
"Дребезг" контактов - это явление, свойственное механическим переключателям, кнопкам, тумблерам и реле. Из-за того, что контакты обычно из металлов и сплавов, которые обладают упругостью, при физическом замыкании они не сразу устанавливают надёжное соединение. В течение короткого промежутка времени контакты несколько раз смыкаются и отталкиваются друг от друга. В результате этого электрический ток принимает установившееся значение не моментально, а после череды нарастаний и спадов. Длительность этого переходного эффекта зависит от материала контактов, от их размера и конструкции. На иллюстрации показана типичная осциллограмма при замыкании контактов тактовой кнопки. Видно, что время от момента переключения до установившегося состояния составляет несколько миллисекунд. Это и "дребезгом".
Этот эффект не заметен в электрических управления освещением, или другими инерционными датчиками и приборами. Но в цепях, где идёт быстрое считывание и обработка информации (где частоты того же порядка, что и импульсы "дребезга", или выше), это является проблемой. В частности, Arduino UNO, который работает на частоте 16 МГц, отлично "дребезг" контактов, принимая последовательность единиц и нулей вместо единичного переключения от 0 к 1.

Давайте посмотрим, как дребезг контактов влияет на правильную работу схемы. Подключим к Arduino тактовую кнопку по схеме со стягивающим резистором. Будем по нажатию кнопки зажигать светодиод и оставлять включённым до повторного нажатия кнопки. Для наглядности подключим к цифровому выводу 13 внешний светодиод, хотя можно обойтись и встроенным.

Чтобы реализовать данную задачу, первое, что приходит в голову:
- запоминать предыдущее состояние кнопки;
- сравнивать с текущим состоянием;
- если состояние изменилось, то меняем состояние светодиода.
Напишем такой скетч и загрузим в память Arduino.
При включении схемы в работу, сразу виден эффект от влияния дребезга контактов. Он проявляется в том, что светодиод загорается не сразу после нажатия кнопки, или загорается и тут же гаснет, или не выключается сразу после нажатия кнопки, а продолжает гореть. В общем, схема работает не стабильно. И если для задачи с включением светодиода это не столь критично, то для других, более серьёзных задач, это просто неприемлемо.

Постараемся исправить ситуацию. Мы знаем, что дребезг контактов проявляет себя в течение нескольких миллисекунд после замыкания контактов. Давайте после изменения состояния кнопки выжидать, скажем, 5 мсек. Это время для человека является практически мгновением, и нажатие кнопки человеком обычно происходит значительно дольше - несколько десятков миллисекунд. А Arduino прекрасно работает с такими короткими промежутками времени, и эти 5 мсек позволят ему отсечь дребезг контактов от нажатия кнопки.
В данном скетче мы объявим процедуру debounce() ("bounce" по-английски - это как раз "дребезг", приставка "de" означает обратный процесс), на вход которой мы подаём предыдущее состояние кнопки. Если нажатие кнопки длится более 5 мсек, значит это действительно нажатие.
Определив нажатие, мы меняем состояние светодиода.
Загрузим скетч в плату Arduino. Теперь всё гораздо лучше! Кнопка срабатывает без сбоев, при нажатии светодиод меняет состояние, как мы и хотели.

Аналогичная функциональность обеспечивается специальными библиотеками, например, библиотекой Bounce2. Скачать её можно по ссылке в разделе "Источники" или на сайте https://github.com/thomasfredericks/Bounce2. Для установки библиотеки помещаем её в директорию libraries среды разработки Arduino и перезапускаем IDE.
Библиотека "Bounce2" содержит следующие методы:
Bounce() - инициализация объекта "Bounce";
void interval(мсек)
- устанавливает время задержки в миллисекундах;
void attach (номерПина)
- задаёт вывод, к которому подключена кнопка;
int update()
- обновляет объект и возвращает true, если состояние пина изменилось, и false в противном случае;
int read()
- считывает новое состояние пина.
Перепишем наш скетч с использованием библиотеки. Можно также запоминать и сравнивать прошлое состояние кнопки с текущим, но давайте упростим алгоритм. При нажатии кнопки будем считать нажатия, и каждое нечётное нажатие будем включать светодиод, каждое чётное - выключать. Такой скетч смотрится лаконично, его легко прочитать и легко применить.

Источники:
- Убираем дребезг контактов кнопки, подключённой к Arduino
- Библиотека Bounce2
И Arduino здесь не является исключением, после того, как помигает светодиодом пробует подключать кнопку и управлять с ее помощью миганием этого самого светодиода. Особенно сложного здесь ничего нет, но есть один нюанс, называемый «дребезг контактов». О том как правильно подключать кнопку к Arduino , что такое «дребезг контактов», как этот эффект проявляется и методах борьбы с ним и пойдет сегодня речь.
Простейшая схема подключения кнопки к микроконтроллеру выглядит следующим образом:
Если ключ S 1 разомкнут (кнопка отпущена), то на цифровом входе D in микроконтроллера мы будем иметь напряжение 5В, соответствующее логической единице. При нажатой кнопке вход D in подключается к земле, что соответствует уровню логического нуля и все напряжение у нас упадет на резисторе R 1 , величину которого выбирают исходя из того, чтобы при нажатой кнопке через него протекал не слишком большой ток (обычно порядка 10÷100 кОм).
Если же просто подключить кнопку между цифровым входом и землей (без резистора R 1 , подключенного к +5В) или между входом и +5В, то в положении, когда кнопка не нажата на цифровом входе микроконтроллера будет присутствовать неопределенное напряжение (может соответствовать уровню 0, а может и 1) и мы бы считывали случайные состояния. Поэтому используется резистор R 1 , который, как говорят, «подтягивает» вход к +5В при отпущенной кнопке.
Считывая состояние цифрового входа микроконтроллера, мы сможем определить нажата кнопка (состояние логического 0) или же нет (будем получать на входе логическую единицу).
Подключение кнопки к Arduino
Микроконтроллеры Atmel AVR ATmega (на базе которых и строится Arduino ) имеют встроенные программно подключаемые нагрузочные резисторы R н величиной 20 кОм и мы можем воспользоваться ими, упростив схему подключения.

Подключается внутренний нагрузочный резистор путем записи логической единицы в требуемый бит порта.
Пример скетча Arduino , который включает и выключает встроенный светодиод на 13 пине, в зависимости от того, нажата или отпущена кнопка, подключенная ко второму пину, используя внутренний нагрузочный резистор:
void setup() { pinMode(13, OUTPUT); //светодиод на 13 пине pinMode(2, INPUT); //2 пин - в режиме входа. Кнопка подключена к земле. digitalWrite(2, HIGH); //подключаем подтягивающий резистор } void loop() { digitalWrite(13, !digitalRead(2)); // считываем состояние кнопки и переключаем светодиод }
Здесь мы инвертируем значение, считанное с входного порта, путем использование логического НЕ , обозначаемого восклицательным знаком перед функцией digitalRead , так как при нажатой кнопке мы считываем 0, а для включения светодиода в порт нам нужно отправить 1.
Дребезг контактов
Все бы ничего, если бы мы жили в идеальном мире с идеальными кнопками. Реальные механические контакты, которые присутствуют в кнопках никогда не замыкаются и не размыкаются мгновенно. В течении непродолжительного промежутка времени происходит многократное замыкание и размыкание контактов ключа (кнопки) в результате чего на вход микроконтроллера поступает не единичный перепад напряжения, а целая пачка импульсов. Это явление носит название «дребезг контактов».
В примере выше, когда при помощи кнопки мы просто включали и выключали светодиод мы не заметили это, так как включение/выключение светодиода в момент «дребезга» происходило очень быстро и мы просто не увидели это глазом.
Эта библиотека включает следующие методы:
- Bounce () — инициализация объекта Bounce
- void interval (unsigned long interval) — устанавливает время антидребезга в миллисекундах
- void attach (int pin) — устанавливает пин, к которому подключена кнопка и подключает на этом выводе встроенный подтягивающий резистор
- int update () — поскольку Bounce не использует , вы «обновляете» объект до того, как считываете его состояние и это нужно делать постоянно (например, внутри loop ). Метод update обновляет объект и возвращает TRUE (1), если состояние пина изменилось (кнопка была нажата или же, наоборот, отпущена) и FALSE (0) в противном случае. Вызов метода update внутри loop необходимо производить только один раз.
- int read () — возвращает обновленное состояние пина
По умолчанию, библиотека Bounce использует интервал стабилизации (stable interval ) для реализации антидребезга. Это проще для понимания и позволяет не знать длительность дребезга.

Параметр stable interval библиотеки Bounce
Определив
#define BOUNCE_LOCK-OUT
#define BOUNCE_LOCK-OUT |
в файле Bounce.h можно включить альтернативный метод борьбы с дребезгом. Этот метод позволяет быстрее реагировать на изменение состояния кнопки, однако, требует установить продолжительность дребезга, а эта величина, как я отметил выше увеличивается с течением времени, а значит, потребуется вносить изменения в код, либо установить заведомо большее значение.

Приведу пример использования этой библиотеки:
#include
#include Bounce bouncer = Bounce () ; //создаем экземпляр класса Bounce void setup () pinMode (2 , INPUT ) ; // кнопка на пине 2 digitalWrite (2 , HIGH ) ; // подключаем встроенный подтягивающий резистор bouncer . attach (2 ) ; // устанавливаем кнопку bouncer . interval (5 ) ; // устанавливаем параметр stable interval = 5 мс Serial . begin (9600 ) ; //установка Serial-порта на скорость 9600 бит/сек void loop () if (bouncer . update () ) { //если произошло событие if (bouncer . read () == 0 ) { //если кнопка нажата Serial . println ("pressed" ) ; //вывод сообщения о нажатии else Serial . println ("released" ) ; //вывод сообщения об отпускании |
И еще один небольшой практически полезный пример. Пусть у нас есть кнопка, при длительности нажатии которой меньше 2 секунд происходит изменение переменной current_mode , в которой хранится текущий режим работы некоторого устройства. В этом примере режим будет изменяться от 0 до 5. Один раз нажали — режим имеет номер 1. Еще раз нажали — 2. И так до пяти. После пяти при очередном нажатии текущий режим становится первым и опять по кругу. Если же удерживать кнопку в нажатом состоянии более 2 секунд переменной current_mode присваивается значение 0.
#include
#include #define pressed_long 2000 // долговременное нажатие = 2 секунды #define num_modes 5 // максимальный номер режима short int max_mode = num_modes + 1 ; // вспомогательная переменная Bounce bouncer = Bounce () ; //создаем экземпляр класса Bounce unsigned long pressed_moment ; // момент нажатия кнопки int current_mode = 0 ; // текущий режим void setup () pinMode (2 , INPUT ) ; // кнопка на пине 2 digitalWrite (2 , HIGH ) ; // подключаем встроенный подтягивающий резистор bouncer . attach (2 ) ; // устанавливаем кнопку bouncer . interval (5 ) ; // устанавливаем параметр stable interval = 5 мс |