mirror of
https://github.com/anklimov/lighthub
synced 2026-10-28 11:15:00 +00:00
docs: import wiki pages into the repo (core/integrations/hardware)
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.
This commit is contained in:
@@ -0,0 +1,233 @@
|
||||
# Аналоговые входы и преобразования 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 конфигурации контроллера
|
||||
|
||||
Формат:
|
||||
|
||||
```json
|
||||
"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# - номер входа ([входы-выходы](../hardware/pins_io.md) , столбец "MPU PIN #")
|
||||
|
||||
- <type> - целое число, побитно кодирующее тип входа. (значение по-умолчанию 0):
|
||||
|
||||
Для *аналоговых входов*, допустимы следующие значения:
|
||||
|
||||
* 66 - Аналоговый вход без встроенной подтяжки
|
||||
* 64 - Аналоговый вход с подключением встроенного подтягивающего резистора
|
||||
|
||||
Для *дискретных входов* применимы следующие значения:
|
||||
* 0 - дискретный вход с подключением встроенного подтягивающего резистора, **низкий** уровень соответствует значению ON
|
||||
* 2 - дискретный вход без подключения встроенного подтягивающего резистора, **высокий** уровень соответствует значению ON
|
||||
* 1 - дискретный вход с подключением встроенного подтягивающего резистора, вход меняет значение между ON и OFF по низкому уровню входного напряжения
|
||||
* 3 - дискретный вход без подключения встроенного подтягивающего резистора,, вход меняет значение между ON и OFF по высокому уровню входного напряжения
|
||||
* 4 - датчик температуры и влажности DHT22
|
||||
* 5 - датчик качества воздуха CCS811
|
||||
* 6 - датчик температуры и влажности HDC1080
|
||||
* 8 - COUNTER вход
|
||||
* 16 - UPTIME вход
|
||||
|
||||
### Действия при срабатывании входа (старый метод настройки)
|
||||
|
||||
- <emit> - имя MQTT топика в который будет выводиться значение при изменениях на входе. Если имя не содержит символа "/",то слева от значения будет автоматически подставлен префикс статусного топика (см. раздел [работа с MQTT](https://www.lazyhome.ru/dokuwiki/doku.php?id=работа_с_mqtt))
|
||||
|
||||
- <scmd> - значение, передаваемое в топик при переключении входа в состояние ON (по-умолчанию, ON)
|
||||
|
||||
- <rcmd> - значение, передаваемое в топик при переключении входа в состояние OFF (по-умолчанию, OFF)
|
||||
|
||||
- <item> - имя канала из секции items которому локально на вход будет передано значение при изменении состояния входа
|
||||
|
||||
- <map> - параметр, который позволяет преобразовывать диапазон получаемых значений на аналоговом порту к иному диапазону или к дискретным значениям ON/OFF, подавлять шумы.
|
||||
Примеры:
|
||||
|
||||
```json
|
||||
"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
|
||||
```
|
||||
|
||||
См. также [несколько кнопок на одном входе](button_presses.md#несколько-кнопок-на-одном-входе)
|
||||
|
||||
## Использование преобразований map
|
||||
|
||||
Внутри контроллера команды и значения между каналами передаются в унифицированном виде (см itemCmd)
|
||||
Но для управления реальными устройствами, данные необходимо конвертировать из унифицированного вида в формат, который понимает устройство и наоборот
|
||||
|
||||
Для этого существует механизм преобразований, который может производить как конвертацию значений так и переобразования между командами и значениями
|
||||
|
||||
Первое место, где используются преобразования - это интеграция Modbus v2. см [настройка modbus](../integrations/modbus_setup.md) это обьясняется тем, что в Modbus все взаимодействие с устройством происходит через регистры, в которые пишутся, либо, из которых считываются числовые значения.
|
||||
|
||||
### Типы преобразований
|
||||
|
||||
Предусмотрено два типа преобразований - **преобразования команды** и **преобразование значения**
|
||||
|
||||
Также, существуют два направления преобразования - **прямое** (когда из унифицированного вида создается значение для записи в устройство) и **обратное** - когда считанное из устройства значение преобразуется в унифицированный вид
|
||||
|
||||
Преобразование определяется при помощи JSON обьекта "map" который добавляется в описание регистра устройства в разделе конфигурирования modbus. Разберем на примерах:
|
||||
|
||||
```json
|
||||
"fanspeed" :{"reg":40000,"map":{"val":[1,255,1,5],"cmd":[["OFF",0]]},"id":7},
|
||||
```
|
||||
|
||||
**прямое преобразование:**
|
||||
|
||||
При управлении fanspeed (напрямую, в нотации <item>/fanspeed/set или через суффикс №7 (fan) в нотации <item>/fan), сперва произойдет попытка преобразования команды
|
||||
|
||||
В случае, если передана команда OFF, в регистр 40000 будет записано значение 0
|
||||
В противном случае, осуществляется попытка преобразовать переданное значение, конвертировав его из шкалы 1-255 в шкалу 1-5
|
||||
если в результате преобразований будет получено число - произойдет запись в указанный регистр модбас.
|
||||
|
||||
при считывании значения из регистра, будет происходить **обратное преобразование**
|
||||
|
||||
При этом, те же правила применяются в обратном направлении.
|
||||
Сначала производится попытка преобразовать полученное из регистра значение в команду. В случае неуспеха - в число.
|
||||
|
||||
В примере выше - если считано значение 0 - оно будет преобразовано в команду OFF
|
||||
в случае не успешного преобразования в команду будет осуществлено обратное преобразование значения из шкалы 1-5 в шкалу 1-255
|
||||
|
||||
Следует отметить, что если преобразование типа "val" не указано, то число, прочитанное из регистра, будет передано на выход без преобразования - именно в том виде, как оно было прочитано из регистра. При этом, преобразование считается выполненным успешно и "сценарий по умолчанию" (def) выполнен не будет.
|
||||
|
||||
Данное поведение можно отменить, задав null для преобразования значения, как указано в примере ниже.
|
||||
Это приведет к тому, что при невозможности преобразовать полученное значение в команду, преобразование в число производиться не будет и отработает "сценарий по умолчанию" (def)
|
||||
|
||||
```json
|
||||
"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), также, был определен. Например, таким образом:
|
||||
|
||||
```json
|
||||
"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 обьект - именно в нем контроллер сохраняет ранее считанные значения)
|
||||
|
||||
```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 значения
|
||||
|
||||
```json
|
||||
"val":[вход_мин, вход_макс, выход_мин, выход_макс]
|
||||
```
|
||||
|
||||
например
|
||||
|
||||
```json
|
||||
"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 то оно не сработает.
|
||||
|
||||
можно определить значения, которые будут являться результатом преобразования если. входное значение меньше минимума или больше максимума диапазона преобразования
|
||||
|
||||
```json
|
||||
"val":[вход_мин, вход_макс, выход_мин, выход_макс, вход<мин_прямое, вых<мин_обратное, вход>макс_прямое, вых>макс_обратное]
|
||||
```
|
||||
|
||||
соответственно, используя данный синтаксис, можно доработать пример выше таким образом, что значение 0 будет транслироваться в 0 как в прямом так и в обратном направлении
|
||||
|
||||
```json
|
||||
"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
|
||||
|
||||
```json
|
||||
"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) — в обоих случаях это разные контексты конфига, в коде они обрабатываются независимо.
|
||||
Reference in New Issue
Block a user