Files
lighthub/documentation/core/rotary_encoder.md
T
2026-10-11 01:27:15 +03:00

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 (переходы между профилями по событиям, «сценарный» энкодер).

Связанные документы