Перейти к основному содержимому

Обработка кнопки

Скриншот схемы Tinkercad: кнопка подключена к Arduino через макетную плату

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

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

Коротко

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

Зачем это нужно

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

Если просто добавить блок «если вход включён», проект иногда ведёт себя неожиданно:

  • действие выполняется много раз за одно долгое нажатие;
  • вход самопроизвольно меняется, когда кнопка отпущена;
  • одно физическое нажатие засчитывается как несколько;
  • условие оказывается перевёрнутым из-за схемы с подтяжкой к питанию;
  • длинная пауза для борьбы с дребезгом останавливает остальную логику робота.

Поэтому обработка кнопки начинается со схемы, а заканчивается точным описанием требуемого поведения.

Главная идея

Контроллер не «видит нажатие» как человек. Цифровой вход сообщает только один из двух логических уровней: HIGH или LOW. Программа придаёт этому уровню смысл в соответствии со схемой подключения.

Для первого проекта удобно использовать внутренний подтягивающий резистор:

  1. вход настраивается как цифровой вход с подтяжкой к питанию;
  2. кнопка соединяет этот вход с общей землёй;
  3. отпущенная кнопка не замыкает контакт, поэтому подтяжка удерживает HIGH;
  4. нажатая кнопка замыкает вход на землю, поэтому контроллер читает LOW.

Получается простое правило:

электрическая схема → прочитанный уровень → смысл в программе → действие

В Tinkercad состояние кнопки читают синим блоком цифрового входа, а затем помещают его в условие if. Нажатие не обязано означать HIGH: это зависит от того, как в виртуальной схеме подключены кнопка и подтягивающий резистор.

Почему входу нужна подтяжка

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

Подтяжка создаёт слабую связь входа с известным уровнем. Она не предназначена для питания нагрузки. В показанной модели Tinkercad используется внешний резистор, поэтому логику входа нужно проверять именно по этой схеме.

Состояние кнопки при INPUT_PULLUPЭлектрический путьЗначение входаКак читать в алгоритме
отпущенавход удерживается подтяжкой к питаниюHIGHкнопка не нажата
нажатавход соединён с GNDLOWкнопка нажата
Активный LOW

Выражение «активный LOW» означает, что действие считается включённым при низком уровне. Это не ошибка и не «отрицательное напряжение»: просто выбранная схема назначает уровню LOW смысл «нажато».

У тактовой кнопки часто четыре вывода. Два вывода с одной стороны уже соединены внутри корпуса, а нажатие соединяет две стороны между собой. Расположение зависит от детали. Перед сборкой полезно свериться со схемой кнопки или проверить пары мультиметром в режиме прозвонки. Если поставить провода на уже соединённую пару, вход не будет меняться при нажатии.

Как собрать программу из блоков

Базовый алгоритм разделяется на настройку и повторяющуюся часть.

В области запуска:

  1. выбрать контакт кнопки;
  2. настроить его как цифровой вход с внутренней подтяжкой;
  3. настроить исполнительный выход, если им управляет программа;
  4. задать безопасное начальное состояние исполнительного устройства.

В бесконечном цикле:

  1. прочитать цифровой вход;
  2. сравнить значение с LOW;
  3. выполнить действие для нажатой кнопки;
  4. выполнить другое действие или ничего не менять для отпущенной кнопки.

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

Состояние и событие — разные задачи

Проверка состояния отвечает на вопрос: «кнопка нажата сейчас?» Событие отвечает на другой вопрос: «кнопку только что нажали?»

Если блок цикла выполняется сотни или тысячи раз в секунду, удерживаемая кнопка будет обнаружена на множестве итераций. Это правильно для движения «пока держим», но неправильно для счётчика или переключателя режима.

Требуемое поведениеЧто отслеживатьПример
действие продолжается всё время удержаниятекущее состояниеманипулятор движется, пока держат кнопку
действие начинается один разпереход «отпущена → нажата»робот начинает маршрут
действие завершается один разпереход «нажата → отпущена»сохраняется длительность удержания
каждое нажатие меняет режимсобытие нажатия и сохранённый режимфара переключается включено/выключено

Для собственного детектора события нужны два значения: предыдущее устойчивое состояние и текущее устойчивое состояние. В схеме с подтяжкой событие нажатия выглядит как переход HIGH → LOW, а событие отпускания — LOW → HIGH. После обработки текущее состояние сохраняют как предыдущее для следующей итерации.

Скриншот Tinkercad: блоки чтения кнопки и ветвления

На скриншоте видно базовое ветвление: программа читает цифровой вход и выбирает действие в зависимости от результата. Для режима «пока держим» этого достаточно; для одиночного события позже добавляют переменную предыдущего состояния и проверку перехода.

Откуда берётся дребезг

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

Программное подавление дребезга обычно строят так:

  1. программа замечает новое сырое значение;
  2. запоминает момент изменения;
  3. продолжает наблюдение, не останавливая весь проект;
  4. принимает новое состояние только тогда, когда оно оставалось неизменным заданный интервал;
  5. после принятия состояния формирует событие, если нужный переход действительно произошёл.

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

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

Пример: кнопка запускает один маршрут

Робот должен начать последовательность действий по одному нажатию. Если проверять только LOW, команда старта будет повторяться, пока палец остаётся на кнопке. Алгоритм строится иначе:

  1. получить устойчивое текущее состояние;
  2. сравнить его с сохранённым предыдущим;
  3. при переходе HIGH → LOW проверить, не выполняется ли маршрут уже;
  4. если робот свободен, установить признак «маршрут активен»;
  5. отдельно выполнять шаги маршрута по этому признаку;
  6. сохранить состояние кнопки для следующего прохода.

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

Пример: одно нажатие переключает свет

Нужна переменная «свет включён». В начале она получает безопасное значение. При каждом подтверждённом событии нажатия программа меняет её на противоположную. Выход затем устанавливается по этой переменной. Если изменить переменную при каждом чтении LOW, она будет многократно переключаться за одно удержание и итог станет непредсказуемым.

Такой пример показывает три разных вида данных:

  • сырой уровень физического входа;
  • подтверждённое событие нажатия;
  • сохранённое состояние режима.

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

Что запомнить про кнопку

  • Цифровой вход должен иметь определённый уровень и не оставаться плавающим.
  • При внутренней подтяжке кнопка обычно соединяет вход с землёй: отпущено — HIGH, нажато — LOW.
  • Состояние подходит для действия «пока держим», событие — для однократной команды.
  • Событие определяется по переходу между предыдущим и текущим устойчивыми состояниями.
  • Дребезг фильтруют до формирования события.
  • Долгая блокирующая задержка может мешать остальным частям робота.
  • Готовый блок «кнопка нажата» может скрывать настройку входа и инверсию, поэтому его поведение проверяют тестом.

Практика

Задание 1

Соберите кнопку по схеме с внутренней подтяжкой. В визуальной программе показывайте два разных наблюдаемых состояния для LOW и HIGH. Запишите, какое значение получается при отпущенной и нажатой кнопке.

Задание 2

Сделайте управление индикатором «горит, пока кнопка удерживается». Объясните в комментарии к проекту, почему условие нажатия проверяет LOW.

Задание 3

Создайте счётчик подтверждённых нажатий. Одно долгое удержание должно увеличивать значение только один раз. Добавьте обработку дребезга без длинной остановки всего цикла.

Задание 4

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

Проверьте себя

  1. Почему разомкнутый вход без подтяжки может менять значение самопроизвольно?
  2. Какой уровень соответствует нажатой кнопке в схеме INPUT_PULLUP?
  3. Чем текущее состояние кнопки отличается от события нажатия?
  4. Какой переход означает нажатие при активном LOW?
  5. Зачем хранить предыдущее устойчивое состояние?
  6. Что называют дребезгом контактов?
  7. Почему длинная задержка после нажатия может мешать роботу?
  8. Как проверить расположение соединённых выводов четырёхконтактной кнопки?
Ориентиры для самопроверки

Сначала ответьте без подсказки. Ответ можно считать полным, если вы:

  • формулируете основную мысль своими словами;
  • называете важные условия, ограничения или меры безопасности;
  • для схемы, кода или расчёта показываете ход решения и ожидаемый результат.

Если один из пунктов объяснить не получается, найдите соответствующую главу статьи, перечитайте её и повторите ответ.

Словарь статьи

ТерминЗначение
цифровой входконтакт контроллера, который программа читает как один из двух логических уровней
HIGHвысокий логический уровень; его физическое напряжение зависит от платы
LOWнизкий логический уровень, близкий к общей земле схемы
подтяжкарезистивная связь входа с известным уровнем, задающая состояние разомкнутой линии
INPUT_PULLUPрежим цифрового входа с включённой внутренней подтяжкой к питанию
активный LOWсоглашение, при котором состояние считается активным при уровне LOW
событиеобнаруженный переход состояния, который обрабатывается один раз
дребезгбыстрые повторные замыкания и размыкания механического контакта
подавление дребезгапроверка устойчивости сигнала перед признанием нового состояния

Связанные темы

Источники