16 885
правок
Метка: ручная отмена |
|||
(не показаны 22 промежуточные версии 3 участников) | |||
Строка 1: | Строка 1: | ||
{{DISPLAYTITLE: | {{DISPLAYTITLE: Как писать шаблоны для сторонних Modbus-устройств}} | ||
== Введение == | == Введение == | ||
Рекомендуем сперва поискать ваше устройств в [[Supported_devices | Таблице поддерживаемых устройств]] — вдруг оно уже там есть. Если устройства в списке нет, но оно поддерживает протокол [[Modbus|Modbus]], то его можно подключить к контроллеру Wiren Board. | Рекомендуем сперва поискать ваше устройств в [[Supported_devices | Таблице поддерживаемых устройств]] — вдруг оно уже там есть. Если устройства в списке нет, но оно поддерживает протокол [[Modbus|Modbus]], то его можно подключить к контроллеру Wiren Board. | ||
Строка 25: | Строка 25: | ||
Устройство Modbus TCP: | Устройство Modbus TCP: | ||
# Откройте документацию на устройство и найдите описание modbus-регистров и настроек подключения (адрес, порт). | # Откройте документацию на устройство и найдите описание modbus-регистров и настроек подключения (адрес, порт). | ||
# | # Утилита ''modbus_client'' в релизах до 2304 содержит ошибку, из-за которой она не может работать по протоколу Modbus TCP. Если успользуете устаревший релиз, то подключите устройство к компьютеру через Ethernet. | ||
# Попробуйте считать из устройства значение одного известного вам регистра | # Попробуйте [[Working_with_WB_devices_without_a_controller |считать из устройства]] значение одного известного вам регистра. | ||
Если вы смогли получить содержимое регистра — вы всё делаете верно и можете продолжать. | Если вы смогли получить содержимое регистра — вы всё делаете верно и можете продолжать. | ||
Строка 32: | Строка 32: | ||
== Создание шаблона == | == Создание шаблона == | ||
Рассказать драйверу wb-mqtt-serial, который в контроллере работает с Modbus-устройствами можно двумя способами: | Рассказать драйверу wb-mqtt-serial, который в контроллере работает с Modbus-устройствами можно двумя способами: | ||
# | # [[RS-485:Configuration_via_Web_Interface#without-template|Добавить регистры]] устройства прямо в веб-интерфейсе контроллера. Этот способ удобен для быстрой проверки работы. | ||
# Создать шаблон, который описывает регистры устройства, их тип и другие параметры. Этот способ удобен для масштабирования: просто копируете шаблон на другой контроллер и в нём появляется поддержка вашего устройства. | # Создать шаблон, который описывает регистры устройства, их тип и другие параметры. Этот способ удобен для масштабирования: просто копируете шаблон на другой контроллер и в нём появляется поддержка вашего устройства. | ||
Строка 51: | Строка 51: | ||
} | } | ||
</syntaxhighlight> | </syntaxhighlight> | ||
Полное описание смотрите в [https://github.com/wirenboard/wb-mqtt-serial документации драйвера wb-mqtt-serial]. | '''Полное описание смотрите в [https://github.com/wirenboard/wb-mqtt-serial документации драйвера wb-mqtt-serial на Github].''' | ||
Допустим, у нас есть одноканальное Modbus-реле, у которого таблица регистров, показанная ниже. | Допустим, у нас есть одноканальное Modbus-реле, у которого таблица регистров, показанная ниже. | ||
Строка 154: | Строка 154: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
#: в примере в шаблоне ''my-best-template.json'' в строке 12, символ 5 ожидается <code>,</code> or <code>}</code>, а находится что-то другое. | #: в примере в шаблоне ''my-best-template.json'' в строке 12, символ 5 ожидается <code>,</code> or <code>}</code>, а находится что-то другое. | ||
# Если с шаблоном всё в порядке, то перейдите в настройки драйвера и | # Если с шаблоном всё в порядке, то перейдите в настройки драйвера и [[RS-485:Configuration_via_Web_Interface|выберите ваш шаблон]]. | ||
== Отклонения от стандарта и что с ними делать == | |||
=== Оптимизация запросов драйвером === | |||
Стандартом Modbus RTU предусмотрен обязательный интервал тишины в 3.5 символа между фреймами данных (под символом подразумевается посылка, состоящая из стартового бита, битов данных, бита четности и стоп-битов). | Стандартом Modbus RTU предусмотрен обязательный интервал тишины в 3.5 символа между фреймами данных (под символом подразумевается посылка, состоящая из стартового бита, битов данных, бита четности и стоп-битов). | ||
Строка 168: | Строка 166: | ||
Нужное значение рассчитывается по формуле: | Нужное значение рассчитывается по формуле: | ||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
guard_interval_us = (3.5*11* | guard_interval_us = (3.5*11*10^6)/(скорость в бит/с). | ||
</syntaxhighlight> | </syntaxhighlight> | ||
Например, для скорости 9600 бит/с <code>guard_interval_us = (3.5*11* | Например, для скорости 9600 бит/с <code>guard_interval_us = (3.5*11*10^6)/9600 = 4000 мкс</code>. При проблемах с подключением стороннего устройства для теста это значение можно увеличить (например до 100000 мкс), так как сторонние устройства иногда работают не совсем корректно. | ||
=== | === Если каналы устройства периодически мигают красным === | ||
Иногда в сторонних устройствах встречаются | Со сторонними устройствами довольно частая ситуация, когда вы сделали шаблон, данные идут, но в логах сыпятся ошибки, а каналы устройства в веб-интерфейсе контроллера окрашивают красным. | ||
Основная причина этому — устройство слишком медленно обрабатывает запросы нашего драйвера. Для начала мы рекомендуем подключить такие устройства на отдельную шину, чтобы они не тормозили работу нормальных устройств, а потом использовать рекомендации ниже. | |||
Чтобы починить, попробуйте увеличить параметр <code>guard_interval_us</code> вплоть до тысяч единиц, например, 5000. Если работа стабилизируется, потихоньку уменьшайте это значение до тех пор, пока ошибки не появятся вновь. Предыдущее значение, когда всё работало хорошо и будет вашим значением в шаблоне. | |||
Ещё есть параметр <code>response_timeout_ms</code> — это максимальное время ответа устройства в миллисекундах, по умолчанию 500 мс. С ним тоже можно аккуратно поэкспериментировать. | |||
Не выставляйте без нужды огромных значений в этих параметрах — это замедлит опрос устройств на порту, куда подключено проблемное устройство. Подробнее о том, как работают эти параметры, смотрите в [https://github.com/wirenboard/wb-mqtt-serial#%D0%94%D0%B8%D0%B0%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B0-%D1%82%D0%B0%D0%B9%D0%BC%D0%B0%D1%83%D1%82%D0%BE%D0%B2-%D1%86%D0%B8%D0%BA%D0%BB%D0%B0-%D0%BE%D0%BF%D1%80%D0%BE%D1%81%D0%B0 Диаграмме таймаутов цикла опроса]. | |||
Оба параметра пишутся в секцию device шаблона: | |||
<syntaxhighlight lang="json"> | |||
"device": { | |||
"name": "BAC-6000ELNW", | |||
"id": "bac-6000elnw", | |||
"response_timeout_ms": 100, | |||
"guard_interval_us": 5000, | |||
... | |||
} | |||
</syntaxhighlight> | |||
=== Разные регистры для чтения состояния и управления === | |||
Иногда в сторонних устройствах встречаются особенности: | |||
# В некоторые регистры можно только писать информацию, но нельзя считывать. | # В некоторые регистры можно только писать информацию, но нельзя считывать. | ||
# Один и тот же | # Один и тот же параметр может читаться по одному адресу, а записываться по другому. | ||
Для того, чтобы драйвер работал с такими устройствами без ошибок, мы добавили параметр '''write_address'''. | Для того, чтобы драйвер работал с такими устройствами без ошибок, мы добавили параметр '''write_address'''. | ||
Строка 203: | Строка 223: | ||
==== Писать в один регистр, читать из другого==== | ==== Писать в один регистр, читать из другого==== | ||
Допустим, в нашем устройстве команда записывается в один регистр, а читается из другого. | Допустим, в нашем устройстве команда записывается в один регистр, а читается из другого. Этот метод можно использовать только, если у обоих регистров один тип. Если типы разные — создавайте два разных канала: на чтение и на запись. | ||
{| border="1" class="wikitable" | {| border="1" class="wikitable" | ||
Строка 214: | Строка 234: | ||
|} | |} | ||
В этом случае канал надо описывать так | В этом случае канал надо описывать так: у нас будет один параметр в контроллере, но при обмене данными запись будет производиться один регистр, а чтение — из другого: | ||
<syntaxhighlight lang="json"> | <syntaxhighlight lang="json"> | ||
{ | { | ||
Строка 226: | Строка 246: | ||
} | } | ||
</syntaxhighlight> | </syntaxhighlight> | ||
=== Произвольные значения в регистрах с бинарной логикой === | |||
Иногда бывает так, что по смыслу регистр должен представляться в веб-интерфейсе переключателем ВКЛ/ВЫКЛ, но допустимые значения у него не 1/0. | |||
В этом случае вы описываете обычный канал с типом '''switch''' и указываете значения <code>on_value</code> и <code>off_value</code>, например: | |||
<syntaxhighlight lang="json"> | |||
{ | |||
"name": "Status", | |||
"reg_type": "holding", | |||
"address": "0", | |||
"type": "switch", | |||
"format": "u16", | |||
"on_value": "0x00a5", // ВКЛ | |||
"off_value": "0x005a" // ВЫКЛ | |||
} | |||
</syntaxhighlight> | |||
Теперь драйвер будет автоматически при чтении конвертировать указанные значения в положение переключателя, а при изменении положения переключателя — записывать указанные значения. | |||
== Полезные ссылки == | == Полезные ссылки == |