Интерфейсы для микроконтроллеров
Энкодер вместо потенциометра: как одна ручка управляет целым меню
Выясняем, почему две почти одинаковые ручки говорят с контроллером на разных языках, как каналы A и B определяют направление и что нужно программе, чтобы один поворот стал навигацией, точной регулировкой или быстрой прокруткой.
Краткий ответ: энкодер не является цифровым потенциометром и не выдаёт готовое значение громкости, температуры или частоты. Он сообщает только о движении. Зато программа может решить, что именно это движение означает — и здесь одна ручка действительно получает почти служебное повышение до целого пульта управления.
Содержание статьи
Ручки-близнецы, но не родственники
Поставьте рядом панельный потенциометр и механический энкодер — оба имеют вал, резьбу, гайку и убедительный вид детали, которую надо крутить. На этом сходство почти заканчивается.
У потенциометра положение вала связано с состоянием резистивного делителя. Если ручка повёрнута примерно наполовину, контроллер может измерить соответствующую долю напряжения. Энкодер работает иначе: он не говорит «я стою на 47%». Он говорит «только что был переход в эту сторону» — и оставляет программе всю бухгалтерию.
Энкодер может заменить потенциометр как орган управления цифрового устройства. Но он не заменяет резистивный делитель, реостат или аналоговый регулятор простой перепайкой трёх ножек.
Что сообщает потенциометр
В самом известном режиме потенциометр — это резистивная дорожка с двумя концами и подвижным ползунком. Между крайними контактами подаём напряжение, а с ползунка получаем его долю. Выходное отношение зависит от положения, хотя в реальной цепи на него также влияют нагрузка, концевое сопротивление и характеристика самой дорожки.[1]
Сильная сторона потенциометра
Положение ручки само по себе сохраняет уставку. Выключили питание, вернулись завтра — вал никуда не делся. Физическая риска на панели всё ещё что-то означает.
Его ограничение
Одна физическая позиция обычно соответствует одному значению. Если программно изменить громкость или профиль настроек, метка на ручке может перестать совпадать с фактическим состоянием.
Поэтому потенциометр прекрасно чувствует себя в простом аналоговом регуляторе, на панели с подписанной шкалой или там, где устройство должно работать без микроконтроллера. Ему не нужно меню, чтобы быть полезным. Иногда это не старомодность, а очень здоровая инженерная лень.
Что сообщает инкрементальный энкодер
Механический инкрементальный энкодер обычно имеет два канала — A и B — и общий контакт C. Во время вращения контакты переключаются в определённом порядке. Контроллер видит последовательность логических состояний и из неё восстанавливает направление и количество переходов. Сам абсолютный угол такая деталь не сообщает.[2]
После включения программный счётчик стартует с того значения, которое назначит прошивка. Если предыдущую громкость надо помнить, её сохраняют в независимой памяти. Если нужна настоящая абсолютная позиция вала, ищут абсолютный угловой датчик или добавляют процедуру начального позиционирования.
Ручку можно крутить без механических концевых упоров. Это не обещание получить число угла от 0° до 360°.
А где кнопка?
Многие панельные энкодеры имеют отдельный нажимной контакт на валу. Он электрически не является частью квадратурных каналов: это обычная кнопка, которую программа может использовать для подтверждения, входа в режим редактирования или возврата. Но слово «EC11» ещё не гарантирует ни кнопки, ни конкретного количества фиксаций. Официальная серия Alps EC11E содержит различные комбинации импульсов, фиксаций и исполнений с кнопкой или без неё.[4]
Четыре состояния квадратуры: где прячется направление
Два входа дают четыре возможные комбинации: 00, 01, 11 и 10. В правильном соседнем переходе изменяется только один бит. Один условный направление выглядит так:
Учебная модель
00→01→11→10→0000→10→11→01→00Какой из них физически будет «вправо», зависит от маркировки каналов, ориентации детали и порядка подключения A/B.
Именно порядок состояний, а не один отдельный уровень, показывает направление. В документации TI этот принцип описан как определение того, какой из двух сигналов опережает другой.[3]
Зачем смотреть на оба бита
Скачок 00 → 11 изменяет оба бита одновременно. Для идеальной квадратуры это не соседнее состояние. Такое событие означает, что программа пропустила промежуточную выборку, контакты создали помеху или сигнал обрабатывается слишком грубо. Таблица переходов позволяет не принимать каждый фронт на веру.
Клик, импульс, фронт и count: четверо у одной ручки
В карточках товаров и библиотеках эти слова часто гуляют без бейджиков. Отсюда рождается странная арифметика: тот же энкодер в одном примере имеет 20 шагов, во втором — 40, а в третьем вдруг 80.
| Термин | Что это | Кто это видит |
|---|---|---|
| Фиксация, detent | Механическое положение, которое ощущается пальцем как «клик». | Человек |
| Импульс / цикл | Повторяющаяся электрическая форма сигнала; определение зависит от datasheet. | Осциллограф или спецификация |
| Фронт | Одно изменение LOW→HIGH или HIGH→LOW на канале. | GPIO, прерывание |
| Count | Единица, которую добавляет программный или аппаратный декодер. | Алгоритм |
В конкретной демонстрации TI энкодер с 20 механическими фиксациями давал четыре счётных изменения между соседними фиксациями. Это полезный пример, но не универсальный закон для каждого KY-040 или EC11.[3] Производители прямо выпускают модели, где количество фиксаций и импульсов не совпадает.[4]
Почему значение скачет назад: дребезг и пропущенные переходы
В механическом контакте металлические поверхности не всегда переходят из разомкнутого состояния в замкнутое одним идеальным движением. Они могут несколько раз коротко коснуться и разойтись. На экране это выглядит как лишние шаги, короткое движение в противоположную сторону или пропущенная команда. Контактные энкодеры требуют debounce так же серьёзно, как кнопки.[2]
Почему одной delay() мало
Глухая задержка после первого фронта может случайно скрыть часть дребезга, но вместе с ним скроет и полезные переходы при быстром вращении. Хуже того, блокирующий код в это время не обслуживает другие задачи.
- регулярно читать оба канала;
- принимать только соседние квадратурные переходы;
- накапливать полную валидную последовательность;
- только после неё выдавать событие меню;
- отдельно фильтровать нажимную кнопку.
Аппаратные C/R-цепи могут помочь, но не выдают справку о безусловном освобождении программиста от ответственности. Alps рекомендует учитывать скорость вращения, время выборки, masking time и конкретное исполнение энкодера.[5]
Polling или interrupts?
Для ручки меню регулярный неблокирующий опрос часто достаточен, если цикл гарантированно успевает видеть переходы. Прерывания полезны, когда основной код может надолго занять процессор или контроллер имеет аппаратный квадратурный счётчик. Но ISR не должна обновлять дисплей, записывать память или решать судьбу всего меню. Её работа — быстро зафиксировать состояние или событие.
Подтягивание и логические уровни: где 5 В перестают быть мелочью
Механический контакт не создаёт HIGH сам по себе. Когда канал разомкнут, вход нужно подтянуть к определённому логическому уровню. Когда контакт замыкается на common/GND, вход становится LOW. Для кнопки между входом и GND Arduino документирует тот же активный LOW с режимом INPUT_PULLUP.[7]
На ATmega328P внутренние подтягивающие резисторы имеют гарантированный диапазон 20–50 кОм — это параметр именно этого микроконтроллера, а не универсальная константа для всех плат.[6]
Если модуль имеет внешние резисторы к 5 В, его выход может подняться до 5 В. Это неприемлемо для GPIO, которые допускают только 3,3 В. Например, официальная документация Raspberry Pi прямо ограничивает вход GPIO максимумом 3,3 В.[8]
Перед подключением 3,3-вольтового контроллера посмотрите не только на название модуля, но и на его схему: куда подключены pull-up, где common, есть ли последовательные резисторы и конденсаторы. Механическому энкодеру питание как таковое часто не нужно — оно нужно плате вокруг него, чтобы сформировать уровни и фильтрацию.
Когда энкодер действительно лучше — а когда оставить потенциометр
| Задача | Лучший кандидат | Почему |
|---|---|---|
| Прямое аналоговое регулирование | Потенциометр | Работает без прошивки и сразу формирует электрическое отношение. |
| Ручка со шкалой 0…100% | Потенциометр | Физическое положение остаётся видимой уставкой. |
| Навигация по дисплейному меню | Энкодер | Неограниченная прокрутка, контекстные команды и нажатие. |
| Большой числовой диапазон | Энкодер | Программный шаг и ускорение без механической шкалы. |
| Значение изменяется также дистанционно | Энкодер | Ручка не претендует на абсолютное положение и не противоречит состоянию программы. |
| Уставка должна пережить выключение без памяти | Потенциометр | Механическое положение сохраняется физически. |
Три модуля MyProject: похожая ручка, разные контакты
В каталоге есть три модуля, которые подходят для экспериментов с квадратурным вводом. Здесь важнее не угадать «лучший», а прочитать маркировку именно своей платы.
| Модуль | Контакты на плате | Выход кнопки | Практический сценарий |
|---|---|---|---|
| KY-040, SKU 1228 | GND, +, SW, DT, CLK |
Отдельно обозначен SW |
Макетирование меню с вращением и подтверждением. |
| EC11 на круглой PCB, SKU 1414 | GND, S1, S2, KEY, 5V |
Отдельно обозначен KEY |
Панельная ручка для меню; точное соотношение кликов и переходов следует проверить. |
| Модуль A/C/B, SKU 1702 | VCC, GND, A, C, B |
Не выведен | Вращение и регулировка; для подтверждения меню нужна отдельная кнопка. |
Для SKU 1702 поставщик заявляет исполнение на 20 импульсов за оборот. Это не следует автоматически переводить как «20 механических кликов»: количество фиксаций и способ программного подсчёта — отдельные характеристики.
Чек-лист перед первым вращением
- Найдите A/B или CLK/DT и не путайте их с кнопкой.
- Определите common и проверьте, куда он подключён.
- Выясните, к какому напряжению подтянуты выходы.
- Не подавайте 5 В на 3,3-вольтовый GPIO без проверки.
- Считайте оба бита и проверяйте допустимые переходы.
- Не используйте долгую блокирующую
delay()как единственный debounce. - Проверьте один полный оборот и посчитайте реальные события.
- Отделите декодер от логики дисплея и меню.
- Сохраняйте уставку программно, если она должна пережить выключение.
- Проверьте, выведена ли кнопка на контакты модуля.
Часто задаваемые вопросы
- Можно ли подключить энкодер к любым цифровым входам?
- Если эти входы поддерживают нужные логические уровни и программа читает их достаточно часто — да. Для прерываний или аппаратного квадратурного блока выбор пинов уже зависит от конкретного MCU.
- Обязательно ли использовать прерывания?
- Нет. Для ручного ввода регулярный неблокирующий опрос может быть достаточным. Важно не само слово «interrupt», а гарантия, что все нужные переходы будут замечены.
- Почему после перезагрузки значение стало нулевым?
- Инкрементальный энкодер не сохраняет абсолютное положение. Значение нужно восстановить из независимой памяти или задать начально.
- Почему направление в моём скетче обратное?
- Порядок A/B относителен. Поменяйте каналы местами или инвертируйте знак события. Это не неисправность энкодера.
- Означает ли надпись «20 pulses» двадцать кликов?
- Не обязательно. Нужно отдельно знать количество механических фиксаций, определение pulse в datasheet и режим подсчёта программы.
- Может ли энкодер управлять аналоговой громкостью?
- Да, но опосредованно: контроллер должен изменять цифровой потенциометр, ЦАП, кодек или другой электронный регулятор. Сам механический энкодер не стоит в сигнальном тракте как резистивный делитель.
Главное правило ручки
Потенциометр отвечает на вопрос «где я стою?». Инкрементальный энкодер — «куда и насколько только что сдвинулись?». Первый удобен там, где физическое положение само является уставкой. Второй — там, где значение живёт в программе, изменяется из разных источников и зависит от контекста экрана.
Чтобы одна ручка действительно управляла целым меню, не нужна тайная библиотека. Нужны четыре дисциплинированных шага: правильно сформировать логические уровни, прочитать оба канала, принимать только валидные переходы и отдать чистые события отдельному автомату меню. Остальное — уже дизайн интерфейса, где даже один клик должен знать свою должностную инструкцию.
Технические источники
- Bourns — The Potentiometer Handbook — поддерживает модель потенциометра как делителя, связь выхода с положением ползунка и практические погрешности.
- Texas Instruments — Incremental Rotary Encoders, SBOA200B, revised December 2021 — поддерживает инкрементальную модель, двухканальное определение направления и необходимость debounce для контактных энкодеров.
- Texas Instruments — Quadrature Encoder Position Counter With MSP430 MCUs, SLAA795, 2017 — поддерживает квадратурный автомат состояний и показывает границы переноса count-per-detent между моделями.
- Alps Alpine — EC11E Series, 11 mm Size Metal Shaft Type — поддерживает разнообразие фиксаций, импульсов и исполнений с кнопкой/без кнопки в одном семействе.
- Alps Alpine — Metal Shaft Encoder Product Catalog, update 2510 — поддерживает требования учитывать скорость, sampling/masking time и C/R-фильтры.
- Microchip — ATmega328P Datasheet, 7810D–AVR–01/15 — поддерживает параметры внутренних pull-up и пороги GPIO именно ATmega328P.
- Arduino — INPUT_PULLUP и Digital Input Pull-Up Resistor — поддерживает активный LOW для контакта между входом и GND.
- Raspberry Pi — A history of GPIO usage on Raspberry Pi devices and current best practices — поддерживает предел 3,3 В для входов GPIO Raspberry Pi.
Написать комментарий