SCADA опрашивает holding register 40001, ожидает температуру 85 °C, получает 0 или 65280. Интегратор открывает утилиту шлюза - там значение верное. Меняют адрес на 40002 - приходит давление с соседнего прибора. Классика: карта преобразования на шлюзе Modbus RTU-TCP сдвинута на один регистр, перепутан byte swap или несколько slave за одним TCP-портом разведены не тем Unit ID.
Здесь не курс Modbus с нуля и не сравнение RTU с TCP. Разбираем шлюз, который снаружи говорит Modbus TCP, а внутри опрашивает RS-485: mapping table, offset, byte order, несколько slave на одном сокете. Статья не дублирует три режима Modbus - для фрейминга есть отдельный материал.
Когда шлюз Modbus RTU-TCP отдает «не те» регистры, в 80% случаев ошибка в карте преобразования: неверный стартовый адрес (offset 0-based vs 1-based), смещение блока, перепутан тип (holding vs input), byte swap (ABCD vs CDAB), неверный Unit ID для нужного slave. Диагностика: сравнить запрос SCADA, ответ TCP и фактический опрос на стороне RS-485 в утилите шлюза; сверить таблицу mapping построчно.
Исправление - не «подобрать адрес на глаз», а зафиксировать в паспорте объекта: для каждого тега - адрес TCP, адрес RTU, тип регистра, порядок байт, slave ID. Одна строка ошибки в Excel на пуске превращается в год «магических» смещений.
Шлюз принимает Modbus TCP (MBAP + PDU) от SCADA. В PDU - function code, start address, quantity. Шлюз переводит запрос в кадр Modbus RTU на UART: другой slave ID, иногда другой адрес и длина. Ответ RTU упаковывается обратно в TCP. Между «адресом, который видит SCADA» и «адресом на приборе» лежит таблица mapping.
Типичные колонки таблицы: TCP start, RTU start, length, function, slave ID, byte order. Если TCP 40001 мапится на RTU 0 (а не 1) - SCADA с адресацией «как в мануале 4xxxx» уедет на регистр. Если в карте указан input register (3x), а клиент читает holding (4x) - придут другие данные или exception.
Вечный спор: адрес 40001 - это регистр 0 или 1 в PDU? Modbus PDU нумерует с 0. Документация приборов часто пишет с 1. Шлюз может показывать «Modbus address 1», драйвер SCADA - «40001». Ошибка на единицу дает сдвиг всего блока: температура читается как статус, статус как температура.
Проверка: прочитать один известный регистр с прибора напрямую по RS-485 (USB-адаптер) и сравнить с тем, что отдает шлюз на тот же logical address. Затем сдвинуть mapping на ±1 и повторить. Зафиксировать правило для проекта в одном месте.
Два регистра под float или DINT требуют согласованного порядка слов и байт. Шлюз отдал big-endian AB CD, SCADA ждет CD AB - число выглядит огромным или нулевым. Особенно часто на счетчиках энергии и частотниках.
Симптом: «младшие байты на месте, старшие нули» или наоборот. В утилите шлюза часто есть переключатель Byte Order per mapping line. Сверьте с мануалом slave, не с привычкой «как на прошлом объекте».
Один IP:502, разные Unit ID в MBAP - разные устройства на RS-485. Ошибка Unit ID - «живой» ответ с чужого прибора. SCADA думает, что читает расходомер, а получает данные температуры с ID=2.
Проверьте: в Wireshark поле Unit Identifier, в карте шлюза - привязка ID к порту RS-485. При нескольких шлюзах на одном IP (разные порты) не перепутайте порты в драйвере.
Подробнее про Unit ID и транзакции - в «Modbus TCP для интегратора: Unit ID, транзакции, таймауты». Про выбор режима RTU/TCP/RTU-over-TCP - в «Три режима Modbus: RTU, TCP и RTU-over-TCP».
| Запрос SCADA | Неверный ответ | Где ошибка в карте |
|---|---|---|
| 40001, FC03, 2 reg | нули или мусор | неверный RTU адрес / offset ±1 |
| 40010 float | огромное число | byte swap или word swap |
| 30001 input | exception или нули | в карте holding вместо input |
| Unit ID=1 | данные другого прибора | slave ID в строке mapping |
| блок 20 регистров | обрезанный ответ | length меньше, чем в запросе |
| после замены прибора | все сдвинуто | новая карта регистров не обновлена |
Захватите TCP в Wireshark: function, address, quantity, Unit ID. Откройте веб-интерфейс шлюза - trace RS-485: какой кадр ушел на шину. Сравните адреса. Прочитайте тот же регистр утилитой производителя slave. Если на RS-485 верно, а в TCP нет - ошибка в mapping или swap. Если на RS-485 неверно - шлюз правильно транслирует неправильный запрос.
Не меняйте сразу и адрес в SCADA, и строку в шлюзе. Меняйте одно звено, иначе «заработало» случайно и сломается на следующем теге.
Выгрузите таблицу mapping в Excel или PDF: TCP tag, TCP address, RTU slave, RTU address, FC, type, byte order, комментарий (единицы, масштаб). Привяжите к as-built. На объекте без этой таблицы каждый новый интегратор снова подбирает смещение.
Для панелей оператора с Modbus-картой экрана те же правила - см. «Modbus-карта экрана оператора: масштаб и bad quality».
На схеме часто стоят и прозрачный serial server (RTU-over-TCP), и полноценный Modbus TCP-RTU шлюз с mapping, и прибор с нативным Modbus TCP. SCADA настроили «как на прошлом заводе» - и половина тегов читается, половина со сдвигом. Перед правкой карты убедитесь, какой тип узла перед вами. Признак TCP-шлюза с mapping - веб-таблица адресов; признак туннеля - один к одному адрес на обеих сторонах.
Материал «Три режима Modbus: RTU, TCP и RTU-over-TCP» помогает не смешивать разбор кадра на проводе с настройкой драйвера. Ошибка режима выглядит как «неверные регистры», хотя карта правильная для другого типа транспорта.
Даже при верном адресе температура приходит как сырой int16 в тысячных долях, а SCADA ждет float в градусах. Интегратор двигает адрес - становится «другое неверное число». Сначала сверяют raw value в утилите шлюза и в SCADA без масштаба. Потом - множитель. В карте mapping некоторые шлюзы позволяют задать scale на строку; если нет - масштаб только в SCADA, но адрес должен быть стабильным.
Для 32-битных счетчиков проверяют, что запрос читает два регистра подряд и swap согласован на всей цепочке. Типичная ошибка: в карте одно слово, в SCADA - DINT из двух регистров со сдвигом.
Два мастера опрашивают один шлюз агрессивно. Шлюз перемешивает ответы или отвечает с задержкой - SCADA иногда получает PDU от предыдущего запроса. Симптом: «неверный регистр» случайно, исчезает после снижения частоты опроса. В Wireshark смотрят Transaction ID: ответ не тому запросу - проблема очереди, не mapping.
Решение: один мастер на линию RS-485 за шлюзом, таймауты с запасом, групповое чтение блоков вместо сотен одиночных регистров. Подробнее про таймауты и Unit ID - в статье для интегратора Modbus TCP.
Перед сдачей объекта для каждого slave: прочитать 3-5 эталонных регистров напрямую по RS-485, тем же адресом через TCP, сверить с паспортом прибора. Зафиксировать скрин mapping и строку в таблице сигналов. При замене прибора на той же позиции - обновить только строку карты, не «подбирать на глаз» в SCADA.
Если шлюз перепрошили и конфигурация слетела, а бэкапа нет, восстановление идет неделями. Бэкап XML/CSV карты - в тот же архив, что и проект ПЛК.
В драйвере SCADA включена опция «Modicon addressing» - к адресу прибавляется 40001 для holding. В карте шлюза адрес уже «человеческий». В итоге запрос уезжает на сотни регистров. Симптом: стабильно неверные данные на всех тегах блока. Лечение: выключить лишнее смещение в одном месте - либо в драйвере, либо в шлюзе, не в обоих.
Аналогично для input registers (3xxxx) и coils (0xxxx). Таблица сигналов должна явно писать: «адрес в PDU», «адрес в SCADA», «адрес в шлюзе».
Утилита веб-интерфейса шлюза с trace RS-485, Modbus Poll или аналог для прямого опроса slave, Wireshark на порту TCP 502, таблица сигналов Excel. Порядок работы: сначала прямой опрос slave (эталон), затем trace шлюза, затем запрос SCADA. Не наоборот - иначе неделю «крутят» offset в SCADA, хотя карта шлюза изначально верна.
При замене модели прибора с другой картой регистров не копируют старую строку mapping с новым IP. Делают новую строку с нуля по мануалу - это быстрее, чем объяснять цеху, почему «температура» показывает счетчик моточасов.
Иногда регистр читается верно, но значение скачет из-за помех на RS-485, а интегратор снова крутит offset. Сначала стабилизируют поле: терминатор, GND, один мастер, скорость. Сравнение «напрямую RS-485» и «через шлюз» при одном и том же запросе за минуту отделяет ошибку карты от ошибки шины. Материал про стабильную связь Modbus RTU vs TCP дополняет эту диагностику.
Почему утилита шлюза показывает верно, SCADA - нет?
Разные адреса опроса или swap в драйвере SCADA, не в шлюзе.
Нужно ли дублировать карту в SCADA и в шлюзе?
Лучше один источник истины. Либо шлюз прозрачный (1:1), либо вся адресация на шлюзе, SCADA читает «виртуальные» регистры.
Exception 02 - illegal address
Запрос выходит за карту или за память slave. Проверьте length и max address в mapping.