3.3.md


ИСПОЛЬЗОВАНИЕ КНОПОК ДЛЯ УПРАВЛЕНИЯ КОНТРОЛЛЕРОМ

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

Рисунок 1

КНОПКИ — самый доступный и широко используемый элемент (интерфейс) для взаимодействия цифровых устройств с человеком. Мы повседневно используем клавиатуру для набора текста на компьютере. КЛАВИАТУРА — это набор кнопок. Вот и мы в контроллере «РУДИРОН» встречаем 3 кнопки для использования в наших устройствах.

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

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

Кнопки бывают нескольких типов:

  • С фиксацией – кнопка остаётся нажатой после отпускания, без фиксации — отключается обратно.
  • Нормально разомкнутая (Normal Open, NO) — при нажатии замыкает контакты. Нормально замкнутая (Normal Closed, NC) — при нажатии размыкает контакты.
  • Тактовые кнопки — замыкают или размыкают контакт. Переключатели — обычно имеют три контакта, общий COM, нормально открытый NO и нормально закрытый NC. При отпущенной кнопке замкнута цепь COM-NC, при нажатой замыкается COM-NO.

Рисунок 1

Встроенные кнопки: На плате «РУДИРОН» есть 3 кнопки без фиксации (B1, B2, B3), которые можно использовать для управления выполнением алгоритма программы.

Рисунок 1

Схема подключения кнопок B1, B2, B3 (BUTTON1, BUTTON2, BUTTON3):

Рисунок 1

По схеме видно, что на вход контроллера поступит логический 1 (напряжение близкое к 3.3 вольт), когда мы нажмем кнопку (вход контроллера соединяется с питанием 3.3 вольта через резистор R1). Если кнопка не нажата, то на входах присутствует логический ноль (за счет внутреннего резистора микроконтроллера, подключенного к земле так называемый подтягивающий резистор).

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

ПРОГРАММНАЯ ОБРАБОТКА СОСТОЯНИЙ КНОПОК

ЗАДАЧА — написать программу по определению нажатия и удержания кнопки B1 (BUTTON1) контроллера. Если кнопка нажата, то мы подаем на светодиод L1 логическую единицу (напряжение 3.3 вольт). В этом случае светодиод L1 будет светится. Когда кнопка отпускается B1 (BUTTON1), то светодиод L1 подаем логический ноль (напряжение 0 вольт). В этом случае светодиод L1 не будет светится. Такой простейший электронный переключатель свечения светодиодом L1.

Для получения информации о уровне напряжения на входе контроллера необходимо использовать команду (функцию) digitalRead(«Номер контроллера»).

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

Внутри микроконтроллера все входы могут быть «подтянуты» (подключены) резисторами либо к плюсу питания, либо к земле. Подключение резисторов происходит через программу. Их подключение или отключение влияет на уровень напряжения на входе при отсутствии сигналов от внешних устройств

Сначала нарисуем алгоритм программы:

Рисунок 1

Используя алгоритм пишем программу:

#include «Arduino.h» void setup()

{

pinMode(BUTTON_BUILTIN_1, INPUT_PULLDOWN); pinMode(LED_BUILTIN_1, OUTPUT);

}

bool btnState;  // создаем переменную для хранения true или false

void loop()

{

digitalWrite(LED_BUILTIN_1, false); btnState = digitalRead(BUTTON_BUILTIN_1); if (btnState)

{	// обработчик нажатия

digitalWrite(LED_BUILTIN_1,  true);

}

else

{	// обработчик отпускания

digitalWrite(LED_BUILTIN_1,  false);

}

}

Рассмотрим нашу программу.

Первое изменение в блоке setup мы видим новый вариант установки режима работы вывода контроллера pinMode(BUTTON_BUILTIN_1, INPUT_PULLDOWN). Здесь самое интересное это INPUT_PULLDOWN. Это как раз подключение внутреннего подтягивающего резистора входа к земле R12. Такая установка позволит при отсутствии нажатой кнопки B1 однозначно иметь уровень логического 0 на входе.

Хорошим тоном в программировании является хранение состояния кнопки (нажата или не нажата) в отдельной переменной. Такая организация позволит в дальнейшем разрабатывать с помощью кнопок разветвленное меню управления устройством. Поэтому создаем переменную bool btnState. Причем она создана между блоками setup и loop. Это будет глобальная переменная, к которой мы сможем обращаться из любой части программы. Переменная имеет свой тип bool – может хранить 1 или 0 (true или false).

Для считывания уровня напряжения на входе контроллера на BUTTON1 (кнопка B1) используем команду:

btnState = digitalRead(BUTTON_BUILTIN_1) с занесением в переменную btnState значения true если кнопка нажата (напряжение на входе 3.3 вольта за счет резистора R1 на схеме выше) или false если кнопку не нажали (напряжение близкое к нулю за счет подключения входа контроллера к земле внутренним подтягивающим резистором R12). Для определения какое значение было записано в переменную btnState используем оператор ветвления if:

if (btnState)

{	// обработчик нажатия

digitalWrite(LED_BUILTIN_1,  true);

}

Если переменная btnState имеет значение (кнопка B1 нажата 3.3 вольта на входе контроллера) true, то выполняется команда digitalWrite(LED_BUILTIN_1, true) и светодиод светится.

Для обработки состояния когда кнопка не нажата воспользуемся возможностями оператора if, который позволяет исполнить блок кода если условие не совпало с true :

else

{	// обработчик отпускания

digitalWrite(LED_BUILTIN_1,  false);

}

Если переменная btnState имеет значение (кнопка B1 не нажата 0 вольт на входе контроллера) false, то выполняется команда digitalWrite(LED_BUILTIN_1, false) и светодиод не светится.

ВАЖНО Работа кнопки В2 может иногда работать наоборот. Программа будет считать, что кнопка нажата, хотя вы ее не трогали. Это происходит из-за установки перемычки IRQ необходимой для работы радио модуля.

Рисунок 1

Вы можете снять перемычку. И программа корректно заработает. Усложним задачу: при нажатии кнопки В1 должен включиться светодиод LED1, при нажатии кнопки В3 должен включиться светодиод LED2, при нажатии кнопки B2 выключаются оба светодиода LED1, LED2.

#include “Arduino.h” void setup()

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

pinMode(BUTTON_BUILTIN_1, INPUT_PULLDOWN); pinMode(BUTTON_BUILTIN_2, INPUT_PULLDOWN); pinMode(BUTTON_BUILTIN_3,  INPUT_PULLDOWN);

// настраиваем выходы светодиодов pinMode(LED_BUILTIN_1, OUTPUT); pinMode(LED_BUILTIN_2, OUTPUT);

// подаем лог 0 на светодиоды, чтобы они не светили digitalWrite(LED_BUILTIN_1, false); digitalWrite(LED_BUILTIN_2, false);

}

bool btnState;  // создаем переменную для хранения true или false

void loop()

{

// обрабатываем нажатие кнопки В2

btnState = digitalRead(BUTTON_BUILTIN_2);

if (btnState)

{

// лог 0 на оба светодиода - не светятся digitalWrite(LED_BUILTIN_1, false); digitalWrite(LED_BUILTIN_2, false);

}

// обрабатываем нажатие кнопки В1 btnState = digitalRead(BUTTON_BUILTIN_1);

if (btnState)

{

// лог 1 на светодиод LED1 - светится

digitalWrite(LED_BUILTIN_1,  true);

}

// обрабатываем нажатие кнопки В3 btnState = digitalRead(BUTTON_BUILTIN_3);

if (btnState)

{

// лог 1 на светодиод LED2 - светится

digitalWrite(LED_BUILTIN_2,  true);

}

РЕЗУЛЬТАТ ВЫПОЛНЕНИЯ

ЗАРАБОТАЛО! При нажатии кнопки В1 «загорается» светодиод LED1, при нажатии кнопки В3 «загорается» светодиод LED2, а при нажатии кнопки B2 «гаснут» оба светодиода LED1, LED2.

ПРИМЕЧАНИЕ Если Вы хотите выполнять программу при последующих включениях «Рудирона», то не забудьте переставить перемычку из положения «Режим программирования» обратно в «Режим выполнения». Если этого не сделать, то программа при включении «Рудирона» выполняться не будет.

ВЫВОДЫ

Мы научились работать со встроенными кнопками «Рудирона», изучили управление встроенными светодиодами через кнопки

ПИСОК КОНТРОЛЬНЫХ ВОПРОСОВ

  1. Что такое кнопка и для чего она предназначена?
  2. Какие виды кнопок бывают?
  3. Сколько доступных для управления пользователем кнопок есть на плате?
  4. Сколько доступных для управления пользователем светодиодов есть на плате?
  5. Что обозначают названия LED_BUILTIN_1 и LED_BUILTIN_2?
  6. Что обозначают названия BUTTON_BUILTIN_1, BUTTON_BUILTIN_2 и BUTTON_BUILTIN_3?
  7. Для чего нужна переменная btnState и какого она типа?
  8. Что будет результатом выполнения нашей программы?
  9. Какую команды мы используем для считывания уровня напряжения на входе контроллера на BUTTON1(кнопка B1)?
  10. Что происходит на выходе кнопки B1 при установке режима работы вывода контроллера pinMode(BUTTON_BUILTIN_1, INPUT_PULLDOWN) и в каком разделе программы его надо написать?

СПИСОК ДОПОЛНИТЕЛЬНЫХ ЗАДАЧ

  1. Использовать для написания программы среду Arduino IDE.
  2. Запрограммировать задачу: При нажатии кнопки В1 «загорается» светодиод LED2, при нажатии кнопки В3 «загорается» светодиод LED1, а при нажатии кнопки B2 «гаснут» оба светодиода LED1, LED2.
  3. Запрограммировать задачу: При нажатии кнопки В1 «гаснет» светодиод LED1, при нажатии кнопки В3 «гаснет» светодиод LED2, а при нажатии кнопки B2 «загораются» оба светодиода LED1, LED2. Исходное состояние светодиодов LED1 и LED2 — включены.
  4. Запрограммировать задачу: При нажатии кнопки В1 «гаснет» светодиод LED1, при нажатии кнопки В3 «гаснет» светодиод LED2, а при нажатии кнопки B2 «загораются» оба светодиода LED1, LED2. Исходное состояние светодиодов LED1 и LED2 – выключены.

ЭЛЕМЕНТЫ КОНТРОЛЯ И ПРОВЕДЕНИЯ СОРЕВНОВАНИЙ

  1. Проведение тестирования по контрольным вопросам. Критерии: кто быстрее и допустил меньшее количество ошибок.
  2. Написание одного из 3 вариантов программы из списка дополнительных задач и загрузка этого варианта в контроллер. Критерии: Правильно написанная программа согласно выданного задания, работающий контроллер и наименьшее количество времени затраченного на эти работы.