12 KiB
Rotary Encoder
Источник: авторский документ «Rotary Encoder» (docx, 2026-10-02), сверен с кодом
lighthub/inputs.cpp.
Появилась возможность подключить к контроллеру орган управления, который называется Rotary encoder (далее — энкодер).
Энкодер упрощает управление такими устройствами, как диммируемое и светодиодное освещение, позволяя выбор яркости/цвета/насыщенности/цветовой температуры делать тактильно, вращением рукоятки регулятора. Одним энкодером можно управлять несколькими, как локальными, так и удаленными устройствами. Освещение здесь приведено в качестве самого применимого примера. Если хотите — данным элементом управления можно регулировать все, что поддерживает команды на увеличение и уменьшение. Например, через автоматизации Home Assistant можно управлять громкостью ресивера или колонки Алиса.
Многие энкодеры также имеют контакт нажатия, и данная возможность тоже может быть использована. Все варианты анализа одинарных-двойных-тройных-длительных нажатий могут быть использованы аналогично с настройкой дискретных входов контроллера и использоваться для любых нужд, в том числе для включения, выключения устройств, переключения профилей управления энкодера.
Все возможности доступны при настройке энкодера через JSON-конфигурацию.
Подключить энкодер можно к прошивке LightHub на всех платформах (включенных с флагом ROTARYENCODER, см. «Доступность» ниже). Особенно хочется подчеркнуть возможность подключить такой элемент (наряду с дополнительными кнопками и датчиками) к контроллеру LightSpot на базе STM32 или ESP32 — минималистической системе, которая может быть смонтирована в каждом выключателе и которая может общаться с основным контроллером LightHub по двухпроводной шине CAN (см. CAN и lightspot). Также можно собрать универсальный выключатель с кнопками и рукояткой энкодера на базе ESP32 или ESP8266, взаимодействующий с остальными системами дома через WiFi (как с контроллерами LightHub, так и с другими устройствами, управляемыми через MQTT), хотя вариант проводного подключения, конечно, предпочтителен.
Настройка
Рассмотрим настройку энкодера на примерах.
В данном примере энкодер подключен к следующим PIN-ам контроллера:
- 14 — контакт нажатия;
- 4 и 5 — контакты A и B энкодера, соответственно.
Четвертый (опциональный) параметр массива # может задавать режим подключения энкодера. Имеет смысл пробовать менять значение в интервале 1-3, если значение по умолчанию (2) не работает корректно для какого-то отдельно взятого энкодера.
Параметр T соответствует значению 32 — это тип входа «rotary encoder».
Параметр "+-" определяет обработчик, вызываемый при вращении рукоятки энкодера по или против часовой стрелки. Обработчик аналогичен описанному в разделе «диммирование с использованием кнопок» (button_presses.md). Но там пары параметров icmd/irev и ecmd/erev используются поочередно, а в случае энкодера первый параметр используется в случае вращения по часовой стрелке, а второй — против часовой.
Настройка в примере ниже переключает локальное устройство dimmer между состояниями ON и OFF (команда toggle) по однократному клику на энкодер (параметр click), а при вращении рукоятки по и против часовой стрелки увеличивает или уменьшает яркость локального устройства dimmer соответственно (команды %+1 и %-1):
{
"T": 32, "#": [14, 4, 5, 2],
"+-": { "item": "dimmer/set", "icmd": "%+1", "irev": "%-1" },
"click": { "item": "dimmer/cmd", "icmd": "toggle" }
}
Поворот по часовой и против часовой стрелки можно разнести на два отдельных обработчика, если вдруг это будет необходимо, чтобы управлять разными устройствами при вращении в разных направлениях. Следующее описание эквивалентно предыдущему:
{
"T": 32, "#": [14, 4, 5],
"+": { "item": "dimmer/set", "icmd": "%+1" },
"-": { "item": "dimmer/set", "icmd": "%-1" },
"click": { "item": "dimmer/cmd", "icmd": "toggle" }
}
Теперь попробуем управлять удаленным устройством dimmer2, подключенным к контроллеру с именем light через MQTT:
{
"T": 32, "#": [14, 4, 5],
"+-": { "emit": "myhome/light/dimmer2/set", "ecmd": "%+1", "erev": "%-1" },
"click": { "emit": "myhome/light/dimmer2/cmd", "ecmd": "toggle" }
}
И пример по управлению удаленным устройством с itemid = 31, настроенным на контроллере с адресом 13 по CAN-шине (см. CAN и lightspot):
{
"T": 32, "#": [14, 4, 5],
"+-": { "can": [13, 31, "set"], "icmd": "%+1", "irev": "%-1" },
"click": { "can": [13, 31, "cmd"], "icmd": "toggle" }
}
Профили (act)
Усложним задачу. Теперь попробуем управлять одним энкодером яркостью, цветом и насыщенностью светодиодной ленты. Для этого понадобится создать несколько профилей энкодера.
Профили можно задать в виде JSON-массива или JSON-объекта в параметре act. Массив и объект аналогичны: в первом случае для активации нужного профиля будет использоваться целое число, определяющее порядковый номер элемента в массиве, содержащего нужный профиль (начиная с 1, так как значение 0 зарезервировано для активации «корневого профиля», который может быть описан непосредственно в объекте входа, на одном уровне с параметрами #, T — аналогично предыдущим примерам). Во втором случае для активации можно пользоваться именем объекта (пустая строка активирует корневой профиль). Это, конечно, делает конфиг более читаемым, но чуть более ресурсоемко.
В примере ниже изначально активен корневой профиль, в котором осуществляется управление яркостью светодиодной ленты. Однократный клик (команда activate в обработчике события click) активирует профиль номер 1 — в котором управляется насыщенность цвета. Однократный клик из профиля 1 переводит энкодер в профиль 2, в котором можно настроить оттенок цвета. Ну и, соответственно, клик из профиля 2 активирует корневой профиль (0). В каждом профиле длительное нажатие включает или выключает led.
{
"T": 32, "#": [14, 4, 5],
"+-": { "item": "led/set", "icmd": "%+1", "irev": "%-1" },
"lcmd": { "item": "led/cmd", "icmd": "toggle" },
"click": { "activate": 1 },
"act": [
{
"+-": { "item": "led/hue", "icmd": "%+1", "irev": "%-1" },
"lcmd": { "item": "led/cmd", "icmd": "toggle" },
"click": { "activate": 2 }
},
{
"+-": { "item": "led/sat", "icmd": "%+1", "irev": "%-1" },
"lcmd": { "item": "led/cmd", "icmd": "toggle" },
"click": { "activate": 0 }
}
]
}
NB: activate можно использовать в описании других входов контроллера — таким образом, например, нажатием других кнопок можно выбирать режим действия энкодера.
Доступность (сверка с кодом, 2026-10-02)
- Тип входа
T:32(IN_RE) работает при компиляции с флагомROTARYENCODER(inputs.cpp). - Флаг включен по умолчанию: due, esp32-wifi, esp32c3-wifi, esp8266-wifi, lighthub21, nrf52840, stm32, stm32-noip (
build-flags/*). - Массив
#:[контакт_нажатия, A, B, режим]; режим по умолчанию — 2 (inputs.cpp,setupRotaryEncoder). activateподдерживает число (индекс профиля, 0 — корневой), строку (имя профиля) и массив["имя_входа", <значение>]— активация профиля во внешнем входе (inputs.cpp,checkInstructions).
Не реализовано
Черновик из исходного документа, не реализованный в текущем коде:
- вход
T:99с профилями и обработчикамиgoto/onenter(переходы между профилями по событиям, «сценарный» энкодер).