Ошибка при работе modbus c С2000-ПП bolid

Настроил опрос.. в адресе чтения указано смещение, в адресе записи нет.

при попытки записать значение возникает ошибка.

image

WB не тестовом релизе.

если убрать смещения в чтении то значения пишутся.

Здравствуйте! Я — автоматический помощник техподдержки Wiren Board.
Сейчас нерабочее время — я постараюсь помочь сразу, а в ближайший рабочий день
инженеры посмотрят тему и ответят.

Похоже, дело в обработке битового смещения: отдельный адрес записи не означает отдельное смещение для записи. В коде wb-mqtt-serial смещение и ширина поля берутся из address и хранятся как общие свойства регистра. Поэтому указание 44099 в адресе записи не обязательно отменяет :8:8, заданное для чтения. Это согласуется с вашим наблюдением.

Ошибка illegal data value означает, что устройство отклонило данные запроса; сама строка лога не показывает, какое значение фактически ушло в линию.

Практический обход — разделить чтение состояния и запись команды на два канала: канал чтения с 44099:8:8 сделать доступным только для чтения, а для команд использовать отдельный канал без битового смещения. Допустимые команды нужно сверить с документацией С2000-ПП.

Для проверки именно вашей версии пришлите:

  • Модель контроллера и вывод:
    cat /etc/wirenboard-release
    dpkg-query -W wb-mqtt-serial
    
  • JSON настройки этого канала и значение, которое пытаетесь записать.

Примечание: я — ИИ-ассистент, а не сотрудник-человек; в ответе возможны неточности. Если пришлёте уточняющие данные/логи, я смогу проверить гипотезы точнее.

Для диагностики проблемы пришлите, пожалуйста, архив с диагностической информацией контроллера. Создание архива описано в документации.

приложен диагностический архив, доступен только сотрудникам поддержки
(1,8 МБ)

Добрый день. Посмотрел журналы. Судя по ним, это “Болид” возвращает ошибку, он отвергает значение, которые вы пытаетесь в него записать. Тут либо порядок байт в слове, либо вечная путаница в адресе и номере регистра, из которой рождается ошибочное смещение в единицу адреса.

У вас два варианта: или внимательно изучить документацию болида, или экспериментировать. Для начала можно убрать адрес записи, тогда запись будет выполняеться по тому же адресу (вклюачая смещение), что и чтение.

Я же написал “если убрать смещения в чтении то значения пишутся.” .. все работает - значит с регистрами все верно и с порядком байт.

Все варианты перебрал.

Коллега, я же говорил не про смещение в чтении, а про адрес записи, вообще, как таковой. Это вы пробовали, полностью убрать адрес записи?

Да

Чтобы поймать значение, которое не проходит на запись, сделайте, пожалуйста, так:

  1. В веб-интерфейсе контроллера: Настройки → Конфигурационные файлы → Настройка драйвера серийных устройств → Настройки wb-mqtt-serial, включите там отладочные сообщения.
  2. Зайдите на канал Zone 4 и попробуйте записать значение как обычно.
  3. Соберите диагностический архив через раздел Диагностика и пришлите нам.
  4. После этого обязательно выключите отладочные сообщения обратно — иначе они продолжат писаться в лог и будут быстрее заполнять диск.

Кстати, по предыдущему архиву. На контроллере очень мало свободного места на диске (корневой раздел заполнен на 99%, свободно около 37 МБ), и есть следы неудавшегося обновления — 16 июля установка пакетов прерывалась с ошибкой нехватки места. Это стоит проверить и разобраться отдельно от текущей проблемы с записью — стоит освободить место на разделе, прежде чем пытаться обновляться повторно.

приложен диагностический архив, доступен только сотрудникам поддержки
(1,5 МБ)

Добрый день.

Спасибо за архив — к сожалению, не то. Zone 4 сейчас настроен без смещения (address/write_address = 44099) — это рабочий вариант, а не тот, что нужно проверить.

Просьба повторить, в таком порядке:

  1. Вернуть у Zone 4 «Адрес» = 44099:0:8, «Адрес для записи» — пусто.
  2. Включить отладочные сообщения.
  3. Сразу попробовать записать значение.
  4. Сразу выключить отладочные сообщения.
  5. Собрать диагностику и прислать.

Порядок важен: лог debug обрезается до ~20-30 секунд, если не выключить сразу после записи — момент из архива вытеснится.

Отдельно: место на диске по-прежнему на исходе — 37 МБ свободно из 2 ГБ (99%). Стоит сначала разобраться с этим, прежде чем продолжать с записью — при таком заполнении под угрозой стабильная работа контроллера.

приложен диагностический архив, доступен только сотрудникам поддержки
(1,5 МБ)

Сейчас удалось понять, что происходило

  1. Было в регистре: 0x6D2F (в старшей половине 0x6D, в младшей — 0x2F). В MQTT-топике канала — 0x6D (только старшая половина, за счёт фильтра)
  2. Вы поменяли только старшую половину на 0x18
  3. Младшую половину (0x2F) трогать нельзя — канал сконфигурирован только на старший байт, что лежит в младшем байте (другая зона/параметр) ему не известно, поэтому драйвер сохраняет его как было, чтобы не затереть вслепую
  4. Драйвер собрал новое число: старшая половина 0x18 + младшая половина 0x2F (как было) = 0x182F
  5. Отправил в устройство: “запиши в регистр 44099 значение 0x182F”
  6. Устройство ответило: значение недопустимо

Опишите, что вы делаете и зачем применяете эти фильтры, найдем решение.

Итак… в регистре хранится информация состояния раздела 1й байт - состояние, 2й байт приоритет. для корректного понимания нужно учитывать только один байт (состояния) так как приоритет может меняться. а вот устанавливать нужно значением только состояния то есть 1й состояние 2й приоритет=0.

можно! логика формирования записи в регистр (в моем понимании):

указа просто адрес (без адреса записи) - читаем и пишем целиком

указам адрес целиком запись со смещением - читаем все пишем часть

указан адрес с смещением (без адреса записи) читаем и пишем по правилу

указан адрес с смещением и адрес записи без смещения - читаем, фильтруем а пишем целиком

указан адрес с смещением и адрес записи с смещением - читаем фильтруем пишем ту часть что в смещении записи

Уточнил механизм записи. При записи в канал с заданным смещением/шириной драйвер берёт полное значение регистра из внутреннего кэша (заполняется предыдущим чтением), обнуляет только те биты, что относятся к вашему каналу (DataOffset/DataWidth), и в это очищенное место записывает новое значение. Всё, что вне диапазона канала — остаётся нетронутым, то есть значение приоритета сохраняется таким же, каким было прочитано, а не сбрасывается в 0.

Поэтому обнулить приоритет через один и тот же канал с маской нельзя — драйвер целенаправленно сохраняет соседний байт. Если нужно принудительно устанавливать приоритет=0 при записи состояния, нужно писать в регистр целиком (без смещения) готовое значение “состояние × 256”

ну и как это сделать? вы же написали что драйвер не пишет регистр целиком если есть маска при чтении.

Тут же в Адрес для записи - [ адрес:смещение:число бит ] я так понимаю что это не работает.

Напрямую записать «состояние + обнулённый приоритет» одним каналом не получится. Рабочий вариант — уйти от смещения при записи:

  1. Оставить канал чтения как есть (44099:8:8, только для чтения) — показывает текущее состояние.
  2. Завести отдельный канал для записи: адрес 44099 целиком, без смещения. Записывать туда не «состояние», а готовое число состояние × 256 — тогда приоритет всегда будет 0.
  3. Пересчёт состояние × 256 — в wb-rules, на виртуальном устройстве.

Логичным продолжением, я считаю, следует репорт на правку драйвера.?