Arduino правильное подключение кнопок. Подключение кнопки к Arduino

И 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 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"); //вывод сообщения об отпускании } }

#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 )

Вам понадобится

  • Arduino;
  • тактовая кнопка;
  • резистор 10 кОм;
  • макетная плата;
  • соединительные провода.

1 Виды кнопок

Кнопки бывают разные, но все они выполняют одну функцию - физически соединяют (или, наоборот, разрывают) между собой проводники для обеспечения электрического контакта. В простейшем случае - это соединение двух проводников, есть кнопки, которые соединяют большее количество проводников.

Некоторые кнопки после нажатия оставляют проводники соединёнными (фиксирующиеся кнопки ), другие - сразу же после отпускания размыкают цепь (нефиксирующиеся кнопки ).

Также кнопки делят на:

  • нормально разомкнутые ,
  • нормально замкнутые .
Первые при нажатии замыкают цепь, вторые - размыкают.

Сейчас нашёл широкое применение тип кнопок, которые называют «тактовые кнопки» . Тактовые - не от слова «такт», а от слова «тактильный», т.к. нажатие хорошо чувствуется пальцами. Но этот ошибочный термин устоялся, и теперь эти кнопки у нас повсеместно так называют. Это кнопки, которые при нажатии замыкают электрическую цепь, а при отпускании - размыкают, т.е. это нефиксирующиеся, нормально разомкнутые кнопки.

2 Дребезг контактов

Кнопка - очень простое и полезное изобретение, служащее для лучшего взаимодействия человека и техники. Но, как и всё в природе, она не идеальна. Проявляется это в том, что при нажатии на кнопку и при её отпускании возникает т.н. «дребезг» ("bounce" по-английски). Это многократное переключение состояния кнопки за короткий промежуток времени (порядка нескольких миллисекунд), прежде чем она примет установившееся состояние. Это нежелательное явление возникает в момент переключения кнопки из-за упругости материалов кнопки или из-за возникающих при электрическом контакте микроискр.



В следующей статье мы подробно рассмотрим способы борьбы с «дребезгом» при замыкании и размыкании контактов. А пока что рассмотрим варианты подключения кнопки к Arduino.

3 Некорректное подключение кнопки

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



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

4 Подключение кнопки по схеме с подтягивающим резистором

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



Напишем вот такой скетч для обработки нажатий на кнопку и загрузим в Arduino.

// Задаём номера выводов: const int buttonPin = 2; const int ledPin = 13; void setup() { pinMode(ledPin, OUTPUT); pinMode(buttonPin, INPUT); } void loop() { int buttonState = digitalRead(buttonPin); // считываем состояние кнопки if (buttonState == HIGH) { digitalWrite(ledPin, HIGH); // зажигаем светодиод при нажатии кнопки } else { digitalWrite(ledPin, LOW); // гасим светодиод при отпускании кнопки } }

Встроенный светодиод на выводе "13" постоянно горит, пока не нажата кнопка. Т.е. на порте "2" Arduino всегда присутствует высокий логический уровень HIGH. Когда нажимаем кнопку, напряжение на "2" порте принимает состояние LOW, и светодиод гаснет.

5 Подключение кнопки по схеме со стягивающим резистором

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



При включении схемы на цифровом порте "2" Arduino низкий уровень LOW, и светодиод не горит. При нажатии на кнопку на порт "2" поступает высокий уровень HIGH, и светодиод загорается.

В этом примеры мы рассмотрим подключение кнопки к контроллеру Arduino. При нажатие кнопки мы будем зажигать встроенный светодиод. Большинство плат Arduino имеют встроенный SMT светодиод, подключенный к выходу 13 (pin 13).

Необходимые компоненты

  • контроллер Arduino
  • тактовая кнопка
  • 10кОм резистор
  • контактная макетная плата
  • соединительные провода

Подключение

Подключаем выход питания (5V) и землю (Gnd), красным и черным проводом соответственно к макетной плате. Обычно на макетных платах для питания и земли используют крайние ряды контактов, как показано на рисунке. Третьим синим проводом мы соединяем цифровой пин 2 контроллера Arduino к контакту тактовой кнопки. К этому же контакту, либо к контакту, постоянно соединенному с ней в 4х штырковом исполнении, подключаем подтягивающий резистор 10 кОм, который в свою очередь соединяем с землей. Другой выход кнопки соединяем с питанием 5 В.

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

Замечание: Чаще всего тактовые кнопки имеют по два контакта с каждой стороны так, как это показано на рисунке подключение. При этом по форме кнопка почти квадратная. ВАЖНО не перепутать при подключении какие контакты соединены, а какие замыкаются при нажатие. Лучше всего прозвонить кнопку если не уверены.

Первая программа должна управлять светодиодом с помощью кнопки:

  • при нажатой кнопке светодиод светится;
  • при отжатой кнопке светодиод не светится.

Подключение кнопки и светодиода к плате Ардуино.

Для связи с внешними элементами в контроллере Arduino UNO существуют 14 цифровых выводов. Каждый вывод может быть определен программой как вход или выход.

У цифрового выхода есть только два состояния высокое и низкое. Высокое состояние соответствует напряжению на выходе порядка 5 В, низкое состояние – 0 В. Выход допускает подключение нагрузки с током до 40 мА.

Когда вывод определен как вход, считав его состояние, можно определить уровень напряжения на входе. При напряжении близком к 5 В (реально более 3 В) будет считано высокое состояние, соответствующее константе HIGH. При напряжении близком к 0 (менее 1,5 В) будет считано низкое состояние, или константа LOW.

Светодиод мы должны подключить к выводу, определив его как выход, а кнопка подключается к выводу с режимом вход.

Светодиод подключается через резистор, ограничивающий ток. Вот типичная схема.

Резистор рассчитывается по формуле I = Uвыхода – Uпадения на светодиоде / R.

Uвыхода = 5 В, Uпадения на светодиоде можно принять равным 1,5 В (более точно указывается в справочнике). Получается, то в нашей схеме ток через светодиод задан на уровне 10 мА.

Можете выбрать любой вывод, но я предлагаю для простоты соединений использовать светодиод, установленный на плате. Тот самый, который мигал в первом тестовом примере. Он подключен к цифровому выводу 13. В этом случае дополнительный светодиод к плате подключать не надо.

Кнопку подключаем к любому другому выводу, например, 12. Аппаратная часть схемы подключения кнопки должна обеспечивать уровни напряжений 0 В при нажатой кнопке и 5 В при свободной. Это можно сделать простой схемой.



При отжатой кнопке резистор формирует на выводе 5 В, а при нажатой – вход замыкается на землю. Рекомендации по выбору резистора я напишу в заключительном уроке про кнопки. Сейчас предложу другой вариант. Все выводы платы имеют внутри контроллера резисторы, подключенные к 5 В. Их можно программно включать или отключать от выводов. Сопротивление этих резисторов порядка 20-50 кОм. Слишком много для реальных схем, но для нашей программы и кнопки, установленной вблизи контроллера, вполне допустимо.

В итоге схема подключения будет выглядеть так.



Кнопку можно припаять на проводах к разъему. Я установил ее на макетную плату без пайки. Купил специально для демонстрации уроков.


Функции управления вводом/выводом.

Для работы с цифровыми выводами в системе Ардуино есть 3 встроенные функции. Они позволяют установить режим вывода, считать или установить вывод в определенное состояние. Для определения состояния выводов в этих функциях используются константы HIGH и LOW, которые соответствуют высокому и низкому уровню сигнала.

pinMode(pin, mode)

Устанавливает режим вывода (вход или выход).

Аргументы: pin и mode.

  • pin – номер вывода;
  • mode – режим вывода.

Функция не возвращает ничего.

digitalWrite(pin, value)

Устанавливает состояние выхода (высокое или низкое).

Аргументы pin и value:

  • pin – номер вывода;
  • value – состояние выхода.

Функция не возвращает ничего.

digitalRead(pin)

Считывает состояние входа.

Аргументы: pin - номер вывода.

Возвращает состояние входа:

digitalRead(pin) = LOW низкий уровень на входе
digitalRead(pin) = HIGH высокий уровень на входе

Программа управления светодиодом.

С учетом предыдущего урока теперь у нас есть вся необходимая информация для написания программы. Программа в Ардуино состоит из двух функций setup() и loop. В setup() мы устанавливаем режимы выводов, а в loop() считываем состояние кнопки в переменную buttonState и передаем его на светодиод. По пути инвертируем, т.к. при нажатой кнопке низкое состояние сигнала, а светодиод светится при высоком.

/* Программа scetch_5_1 урока 5
*/

boolean buttonState; // создаем глобальную переменную buttonState

void setup() {
pinMode(13, OUTPUT); //

}

// бесконечный цикл
void loop() {



}

Для хранения промежуточного значения состояния кнопки создаем переменную buttonState с типом boolean. Это логический тип данных. Переменная может принимать одно из двух значений: true (истинно) или false (ложно). В нашем случае - светодиод светится и не светится.

Скопируйте или перепишите код программы в окно Arduino IDE. Загрузите в контроллер и проверьте.

Для сохранения проектов Ардуино я создал папку d:\Arduino Projects\Lessons\Lesson5. В каждом уроке программы называю scetch_5_1, scetch_5_2, … Вы можете поступать также или ввести свою систему сохранения файлов.

Блок программы:

buttonState = digitalRead(12); // считываем состояние 12 входа (кнопки) и записываем в buttonState
buttonState = ! buttonState; // инверсия переменной buttonState
digitalWrite(13, buttonState); // записываем состояние из buttonState на выход 13 (светодиод)

можно записать без использования промежуточной переменной buttonState.

digitalWrite(13, ! digitalRead(12));

В качестве аргумента для функции digitalWrite() выступает функция digitalRead(). Хороший стиль это именно такой вариант. Не требуются дополнительные переменные, меньше текст.

Т.е. функцию можно использовать как аргумент другой функции. Функции можно вызывать из функций.

Другой вариант этой же программы, использующий условный оператор if.

/* Программа scetch_5_2 урока 5
Зажигает светодиод (вывод 13) при нажатии кнопки (вывод 12) */

void setup() {
pinMode(13, OUTPUT); // определяем вывод 13 (светодиод) как выход
pinMode(12, INPUT_PULLUP); // определяем вывод 12 (кнопка) как вход
}

// бесконечный цикл
void loop() {
if (digitalRead(12) == LOW) digitalWrite(13, HIGH);
else digitalWrite(13, LOW);
}

В бесконечном цикле проверяется состояние вывода 12 (кнопка), и если оно низкое (LOW), то на выводе 13 (светодиод) формируется высокое состояние (HIGH). В противном случае состояние светодиода низкое (LOW).

Директива #define.

Во всех примерах для функций ввода/вывода мы указывали аргумент pin, определяющий номер вывода, в виде конкретного числа - константы. Мы помнили, что константа 12 это номер вывода кнопки, а 13 – номер вывода светодиода. Гораздо удобнее работать с символьными именами. Для этого в языке C существует директива, связывающая идентификаторы с константами, выражениями.

Директива #define определяет идентификатор и последовательность символов, которая подставляется вместо идентификатора, каждый раз, когда он встречается в тексте программы.

В общем виде она выглядит так:

#define имя последовательность_символов

Если в наших программах мы напишем:

#define LED_PIN 13 //

то каждый раз, когда в программе встретится имя LED_PIN, при трансляции вместо него будет подставлены символы 13. Функция включения светодиода выглядит так:

digitalWrite(LED_PIN, HIGH);

Окончательный вариант программы с использованием #define.

/* Программа урока 5
Зажигает светодиод (вывод 13) при нажатии кнопки (вывод 12) */

#define LED_PIN 13 // номер вывода светодиода равен 13
#define BUTTON_PIN 12 // номер вывода кнопки равен 12

void setup() {
pinMode(LED_PIN, OUTPUT); // определяем вывод 13 (светодиод) как выход
pinMode(BUTTON_PIN, INPUT_PULLUP); // определяем вывод 12 (кнопка) как вход
}

// бесконечный цикл
void loop() {
digitalWrite(LED_PIN, ! digitalRead(BUTTON_PIN));
}

Обратите внимание, что после директивы #define точка с запятой не ставится, потому что это псевдо оператор. Он не совершает никаких действий. Директива задает константы, поэтому принято имена для нее писать в верхнем регистре с разделителем – нижнее подчеркивание.

В следующем уроке будем бороться с дребезгом кнопки, разобьем программу на блоки и создадим интерфейс связи между блоками.



Есть вопросы?

Сообщить об опечатке

Текст, который будет отправлен нашим редакторам: