Ported the relevant lazyhome.ru dokuwiki pages to markdown, verified against the code; each page carries a 'cross-check with code' section where behavior differs from or extends the wiki.
23 KiB
Аналоговые входы и преобразования map
Источник: Wiki LightHub (lazyhome.ru), страницы «аналоговые_входы» и «использование_преобразований_map». Снапшот от 2026-10-02.
Общая информация
На разьем X36 контроллера LightHub выведены 12 аналоговых входов и 4 дискретных. Аналоговые входы: A0-A11, Дискретные - DA12-DA15
Каждый из данных входов защищен от статического электричества и импульсных помех мощным TWS диодом, защищающий вход процессора как от отрицательного напряжения так и от напряжения более 5В В случае использования процессорной платы DUE на 3,3 Вольт, автоматически, используется дополнительный диод, ограничивающий потенциал на входе процессора до допустимой величины в 3,5В
При необходимости, каждый из данных входов, может быть использован как слаботочный низковольтный выход.
Аппаратное конфигурирование
Каждый вход может быть настроен для работы в разных режимах путем запаивания специальных контактных дорожек (перемычек) на плате Для каждого входа предусмотрено две перемычки: подтяжка к GND и подтяжка к VCC (в зависимости от типа процессора, 5 или 3,3 В)
-
Вход 0-10 В: запаяна перемычка GND. В этом случае, образуется делитель, при котором максимум значения ADC соответствует, примерно, 10В входного напряжения. В плавающем режиме на входе низкий уровень.
-
Датчик протечки: запаяна перемычка VCC. В плавающем режиме, на входе высокий уровень. Между входом и нулем можно подключить проводной датчик протечки. В случае попадания влаги, на входе образуется низкий уровень.
-
Плавающий высокоомный вход или выход: перемычки не запаяны. При этом вход измеряет напряжение от 0 до VCC, при более высоком напряжении - входит в насыщение, оставаясь при этом электрически защищенным от перенапряжения.
Также, к данным входам можно подключать датчики типа DHT22 или внешний CAN адаптер Максимальное напряжение на входе - 24В (уточнить)
Программное конфигурирование
Входы настраиваются в секции in конфигурации контроллера
Формат:
"in":{
"pin#": { "T":<type>, "emit":"<emit>", item:"<item>", "scmd": "ON|OFF|TOGGLE|HALT|REST|XON|XOFF", "rcmd": "ON|OFF|TOGGLE|HALT|REST|XON|XOFF", "map":[<in_min>,<in_max>,<out_min>,<out_max>,<noize>]}
}
Типы входов
-
pin# - номер входа (входы-выходы , столбец "MPU PIN #")
-
- целое число, побитно кодирующее тип входа. (значение по-умолчанию 0):
Для аналоговых входов, допустимы следующие значения:
- 66 - Аналоговый вход без встроенной подтяжки
- 64 - Аналоговый вход с подключением встроенного подтягивающего резистора
Для дискретных входов применимы следующие значения:
- 0 - дискретный вход с подключением встроенного подтягивающего резистора, низкий уровень соответствует значению ON
- 2 - дискретный вход без подключения встроенного подтягивающего резистора, высокий уровень соответствует значению ON
- 1 - дискретный вход с подключением встроенного подтягивающего резистора, вход меняет значение между ON и OFF по низкому уровню входного напряжения
- 3 - дискретный вход без подключения встроенного подтягивающего резистора,, вход меняет значение между ON и OFF по высокому уровню входного напряжения
- 4 - датчик температуры и влажности DHT22
- 5 - датчик качества воздуха CCS811
- 6 - датчик температуры и влажности HDC1080
- 8 - COUNTER вход
- 16 - UPTIME вход
Действия при срабатывании входа (старый метод настройки)
-
- имя MQTT топика в который будет выводиться значение при изменениях на входе. Если имя не содержит символа "/",то слева от значения будет автоматически подставлен префикс статусного топика (см. раздел работа с MQTT)
-
- значение, передаваемое в топик при переключении входа в состояние ON (по-умолчанию, ON)
-
- значение, передаваемое в топик при переключении входа в состояние OFF (по-умолчанию, OFF)
-
- имя канала из секции items которому локально на вход будет передано значение при изменении состояния входа
-
- параметр, который позволяет преобразовывать диапазон получаемых значений на аналоговом порту к иному диапазону или к дискретным значениям ON/OFF, подавлять шумы. Примеры:
"map":[0,850,0,100] - при получении значения 850 преобразование выдаст на выходе число 100
"map":[100,500,0,256,10] - при изменении входного значения от 100 до 500 преобразование выдаст на выходе число от 0 до 256, флуктуации в пределах 10 единиц между замерами (после преобразования) , будут игнорироваться.
При выходе величины изменения между текущим и предыдущим учтенным замером за пределы шумоподавления, шумоподавление отключается для нескольких последовательных замеров.
"map":[100,500] - при понижении значения ниже 100 будет предприняты действия, аналогично дискретному входу, состояние OFF, при повышении значения выше 500 будет предприняты действия, аналогично дискретному входу, состояние ON
См. также несколько кнопок на одном входе
Использование преобразований map
Внутри контроллера команды и значения между каналами передаются в унифицированном виде (см itemCmd) Но для управления реальными устройствами, данные необходимо конвертировать из унифицированного вида в формат, который понимает устройство и наоборот
Для этого существует механизм преобразований, который может производить как конвертацию значений так и переобразования между командами и значениями
Первое место, где используются преобразования - это интеграция Modbus v2. см настройка modbus это обьясняется тем, что в Modbus все взаимодействие с устройством происходит через регистры, в которые пишутся, либо, из которых считываются числовые значения.
Типы преобразований
Предусмотрено два типа преобразований - преобразования команды и преобразование значения
Также, существуют два направления преобразования - прямое (когда из унифицированного вида создается значение для записи в устройство) и обратное - когда считанное из устройства значение преобразуется в унифицированный вид
Преобразование определяется при помощи JSON обьекта "map" который добавляется в описание регистра устройства в разделе конфигурирования modbus. Разберем на примерах:
"fanspeed" :{"reg":40000,"map":{"val":[1,255,1,5],"cmd":[["OFF",0]]},"id":7},
прямое преобразование:
При управлении fanspeed (напрямую, в нотации /fanspeed/set или через суффикс №7 (fan) в нотации /fan), сперва произойдет попытка преобразования команды
В случае, если передана команда OFF, в регистр 40000 будет записано значение 0 В противном случае, осуществляется попытка преобразовать переданное значение, конвертировав его из шкалы 1-255 в шкалу 1-5 если в результате преобразований будет получено число - произойдет запись в указанный регистр модбас.
при считывании значения из регистра, будет происходить обратное преобразование
При этом, те же правила применяются в обратном направлении. Сначала производится попытка преобразовать полученное из регистра значение в команду. В случае неуспеха - в число.
В примере выше - если считано значение 0 - оно будет преобразовано в команду OFF в случае не успешного преобразования в команду будет осуществлено обратное преобразование значения из шкалы 1-5 в шкалу 1-255
Следует отметить, что если преобразование типа "val" не указано, то число, прочитанное из регистра, будет передано на выход без преобразования - именно в том виде, как оно было прочитано из регистра. При этом, преобразование считается выполненным успешно и "сценарий по умолчанию" (def) выполнен не будет.
Данное поведение можно отменить, задав null для преобразования значения, как указано в примере ниже. Это приведет к тому, что при невозможности преобразовать полученное значение в команду, преобразование в число производиться не будет и отработает "сценарий по умолчанию" (def)
"acon":{"reg":40003,"map":{"cmd":[1,["OFF",0]],"val":null,"def":40001},"id":8},
Для этого примера преобразования будут действовать следующим образом:
Прямое:
Команда OFF приведет к записи 0 в регистр 40003 Любая другая команда или значение будут проигнорированы
Обратное:
Если из регистра 40003 считан ноль, он будет преобразован в команду OFF.
любые другие значения будут проигнорированы. Преобразование при этом будет считаться не успешным. и будет выполнен "сценарий по умолчанию", заданный в параметре "def" обьекта "map".
Сценарии преобразования по умолчанию
Этот параметр (используется только для обратных преобразований modbus) применяется в том случае, если для считанного из регистра значения не удалось применить преобразование. В этом случае, можно использовать значение, считанное из иного регистра.
Параметр def может иметь либо цифровое либо строковое значение. В случае цифрового значения - задается номер регистра. в случае строкового значения - задается имя параметра. Логика работы сценария по умолчанию немного разная для данных двух случаев.
цифровое значение:
Контроллер пытается найти считанное из modbus значение в текущем буфере (на тот случай, если данное значение было считано в одном цикле опроса командой чтения нескольких последовательных регистров)
Если значение не было считано, регистр считывается отдельно. Для примера выше, требуется, чтобы номер регистра (40001), также, был определен. Например, таким образом:
"acmode" :{"reg":40001,"map":{"cmd":[["FAN_ONLY",1],["HEAT",4],["COOL",2],["AUTO",8]]},"id":8},
Соответственно, в случае если значение регистра 40003 не нулевое (сработал "сценарий по умолчанию") - будет прочитан регистр 40001, полученное из него значение будет преобразовано к соответствующей команде, результат данного преобразования будет возвращен как результат преобразования первого параметра (acon)
Данное поведение, тем не менее, не отменяет стандартной логики того, что когда произойдет опрос регистра 40001 (если его опрос задан в параметре poll устройства) - будут произведены все преобразования из параметра acmode, которые будут переданы на обработку, если acmode описан в разделе items файла конфигурации.
строковое значение:
В этом случае, используется последнее, ранее считанное, значение, сохраненное в параметре, имя которого указано в параметре def. Для данного значения, производятся преобразования, определенные для данного параметра и их результат возвращается как результат преобразования первого параметра.
В примере ниже, если значение coil 0 равно нулю - обратное преобразование сразу вернет команду OFF
Иначе, так как преобразование в число отменено (val=null), преобразование для параметра pwr будет считаться не успешным и контроллер посмотрит ранее считанное значение регистра 1, из параметра описанного в acmode, применит все указанные для регистра acmode преобразования и их результат вернет для параметра pwr
важно: параметр acmode должен быть описан в разделе items, даже если сам по себе он ни для каких действий более не используется. достаточно в данном описании поставить пустой JSON обьект - именно в нем контроллер сохраняет ранее считанные значения)
"pwr":{"coil":0,"map":{"cmd":[1,["OFF",0]],"val":null, "def":"acmode"},"id":1},
"acmode":{"reg":1,"map":{"cmd":[["FAN_ONLY",4],["HEAT",2],["COOL",1],["DRY",3],["AUTO",5]],"val":null},"id":1},
Ограничения диапазона при линейном преобразовании значений
В простейшем случае, в параметре val задается массив, содержащий 4 значения
"val":[вход_мин, вход_макс, выход_мин, выход_макс]
например
"val":[1, 5, 1, 255]
В случае прямого преобразования, числа 1,2,3,4,5 будут преобразованы к 1, 64, 128, 195, 255 В случае обратного - числа из интервала 1-64 к 1, 65-128 к 2, 129-195 к 3, 196-254 к 4 и 255 к 5
NEW если входное значение не укладывается в указанные границы - преобразование считается не успешным. То есть в примере выше, если на вход преобразования придет число 0 или 6 то оно не сработает.
можно определить значения, которые будут являться результатом преобразования если. входное значение меньше минимума или больше максимума диапазона преобразования
"val":[вход_мин, вход_макс, выход_мин, выход_макс, вход<мин_прямое, вых<мин_обратное, вход>макс_прямое, вых>макс_обратное]
соответственно, используя данный синтаксис, можно доработать пример выше таким образом, что значение 0 будет транслироваться в 0 как в прямом так и в обратном направлении
"val":[1, 5, 1, 255, 0, 0]
Параметры подставляемые при срабатывании ограничений не обязательны. Если какие-то требуется пропустить - можно указать null
Предопределенные шаблоны преобразований
Шаблон "cmd":"fan"
данный шаблон в случае прямого преобразования позволяет провести трансляцию стандартных команд OFF, LOW, MEDIUM, HIGH в значения 0, 20, 128, 255 соответственно
Для обратного преобразования: Значения 0, 1-127, 128-254, 255 преобразуются в OFF, LOW, MEDIUM, HIGH
"fanspeed":{"reg":42,"type":"u8l","id":7,"map":{"cmd":"fan"}},
Сверка с кодом (2026-10-02)
- Корректно: типы аналоговых входов соответствуют коду:
IN_ANALOG = 64(вход с встроенной подтяжкой,INPUT_PULLUP) и66 = IN_ANALOG | IN_ACTIVE_HIGH(вход без подтяжки, обычныйINPUT) —lighthub/inputs.h:29,33иlighthub/inputs.cpp:255-260. - Корректно: дискретные типы 0/1/2/3 (
IN_PUSH_ON,IN_PUSH_TOGGLE,IN_ACTIVE_HIGH) —lighthub/inputs.h:33-34; типы 4/5/6/8/16 (DHT22, CCS811, HDC1080, COUNTER, UPTIME) обрабатываются вlighthub/inputs.cpp:262-265,315-321. - Корректно: параметр
mapдля аналогового входа (линейное преобразование/порог/шумоподавление) обрабатывается вlighthub/inputs.cpp:875,1095. - Корректно: преобразования modbus (
mapсval/cmd/def) реализованы вlighthub/modules/out_modbus.cpp(строки 216, 465, 600, 1084); шаблон"cmd":"fan"—lighthub/itemCmd.cpp:1364,1473. - Уточнение: в описании «нескольких кнопок на одном входе» и в примерах используется параметр
mapв двух разных смыслах (диапазон ADC для входа и преобразование регистра modbus) — в обоих случаях это разные контексты конфига, в коде они обрабатываются независимо.