Modbus TCP — тот же Modbus, что на линии RS-485, но переданный по Ethernet: код функции и данные (PDU) остаются прежними, а вместо адреса устройства и CRC перед ними встаёт 7-байтный заголовок MBAP. Запрос «прочитать 10 регистров хранения с адреса 0» занимает 12 байт: 00 01 00 00 00 06 01 03 00 00 00 0A. Калькулятор собирает такие кадры для функций 01–06, 15, 16 и 23, разбирает байты из Wireshark или журнала программы и показывает, как тот же запрос выглядит в Modbus RTU.
Браузер не может открыть соединение TCP с портом 502, поэтому калькулятор работает только с байтами: ничего никуда не отправляет и устройство не опрашивает.
Коротко
- Кадр (ADU): заголовок MBAP (7 байт) и PDU — код функции и данные, всего не больше 260 байт.
- Заголовок MBAP: транзакция (2 байта), протокол (2 байта, всегда 0), длина (2 байта), Unit ID (1 байт); все поля — старшим байтом вперёд.
- Длина считает байты после неё: Unit ID и PDU.
- CRC и пауз нет: границы кадра задаёт поле длины, целостность — Ethernet и TCP.
- Порт: 502.
- Unit ID: 0xFF или 0 для устройства прямо в сети, 1–247 — адрес устройства на RS-485 за шлюзом.
Как пользоваться калькулятором
Собрать запрос. Задайте номер транзакции и Unit ID — десятичными числами или в виде 0x1501, — затем функцию и её поля, как в калькуляторе Modbus RTU: адрес с нуля, количество, значения через пробел или запятую. На выходе — кадр с заголовком MBAP, таблица полей, длина нормального ответа и ответа с исключением, а для функций записи — весь ответ байт в байт. Строка «Тот же запрос в Modbus RTU» показывает кадр, который отправит шлюз на линию: Unit ID становится адресом устройства, в конце добавляется CRC-16.
Разобрать кадр. Вставьте байты в любом виде: 00 01 00 00, 0x00,0x01 или 00010000. Калькулятор проверит идентификатор протокола и поле длины, разберёт PDU по полям, покажет регистры как uint16 и int16, а пары регистров — как uint32, int32 и float32 в четырёх порядках байтов. Если вставлен кадр Modbus RTU — с адресом в начале и верной CRC в конце, — калькулятор узнает его и покажет тот же кадр в виде Modbus TCP.
Состояние хранится в адресе страницы: ссылкой на собранный запрос или разобранный кадр можно поделиться.
Заголовок MBAP
| Поле | Размер | Кто заполняет | В примере |
|---|---|---|---|
| Идентификатор транзакции | 2 байта | клиент; сервер копирует его в ответ | 00 01 |
| Идентификатор протокола | 2 байта | клиент, всегда 0 — это Modbus; сервер копирует | 00 00 |
| Длина | 2 байта | каждый для своего кадра: число байтов после поля длины | 00 06 |
| Unit ID | 1 байт | клиент; сервер копирует | 01 |
| Код функции | 1 байт | начало PDU, как в RTU | 03 |
| Данные | 0–252 байта | зависят от функции | 00 00 00 0A |
Поле длины считает Unit ID и PDU, поэтому длина на 6 меньше длины всего кадра. В запросе на чтение PDU занимает 5 байт: длина — 6, кадр — 12 байт. В ответе с десятью регистрами PDU — 22 байта (код функции, счётчик байт и 20 байт данных): длина — 23, кадр — 29 байт.
Пример из руководства Modbus по TCP/IP — чтение регистра № 5 с номером транзакции 0x1501 и незначащим Unit ID:
15 01 | 00 00 | 00 06 | FF | 03 00 04 00 01
TID протокол длина Unit PDU: функция 03, адрес 4, количество 1
Регистр № 5 в кадре имеет адрес 4: адреса Modbus считаются с нуля. Вставьте эти байты в режим «Разобрать кадр» — калькулятор разложит их так же.
Отличия от Modbus RTU
PDU одинаков на обоих транспортах: те же коды функций, адреса, количества и форматы данных, те же коды исключений. Меняется только обёртка.
| Modbus RTU | Modbus TCP | |
|---|---|---|
| Перед PDU | адрес устройства, 1 байт | заголовок MBAP, 7 байт |
| После PDU | CRC-16, 2 байта, младший байт первым | ничего |
| Граница кадра | тишина не короче 3,5 символа | поле длины в заголовке |
| Кадр, байт | до 256 | до 260 |
| Адресация | адрес 1–247 на шине, 0 — широковещательный | IP-адрес и порт 502; Unit ID — для шлюза |
| Запросы | один за другим: следующий — только после ответа или таймаута | несколько сразу, ответ находят по номеру транзакции |
| Проверка ошибок | CRC-16 кадра | CRC-32 Ethernet и контрольная сумма TCP |
Нет CRC. Кадр Ethernet защищён своей CRC-32, а TCP повторяет потерянные и искажённые сегменты, поэтому своя контрольная сумма Modbus не нужна. Посчитать CRC-16 для кадра RTU можно в калькуляторе CRC.
Нет пауз в 3,5 символа. На последовательной линии конец кадра находят по тишине, а TCP — это поток байтов без пауз: один кадр может прийти двумя сегментами, а два кадра — одним. Поэтому длина записана в заголовке явно. Приёмник читает 6 байт, берёт из них длину и дочитывает ровно столько байтов. Калькулятор так же предупреждает, если байтов меньше, чем обещает поле длины, и показывает отдельно лишние байты — начало следующего кадра.
Unit ID вместо адреса. Устройство в сети TCP/IP находят по IP-адресу, и Unit ID для него ничего не значит: руководство рекомендует 0xFF, допускает и 0. Значение нужно шлюзу Modbus TCP — RTU: у шлюза один IP-адрес на всю линию RS-485, и по Unit ID он выбирает, какому устройству на линии переслать запрос. Тогда Unit ID — это обычный адрес от 1 до 247. Как шлюз поступит с Unit ID 0, руководство не говорит; если он передаст его на линию как есть, это будет широковещательный адрес 0: запрос выполнят все устройства, ответа не будет, а запрос на чтение потеряет смысл. Поэтому калькулятор предупреждает о Unit ID 0 в кадре RTU — это наш вывод, а не правило спецификации.
Транзакции. На линии RS-485 ведущий ждёт ответа на каждый запрос. По TCP клиент может отправить несколько запросов подряд и разобрать ответы по номеру транзакции: сервер копирует его из запроса. Сколько запросов одновременно держит клиент, руководство относит к его характеристикам — от 1 до 16. Ответ с номером, которого клиент не ждёт, отбрасывается.
Функции и длина кадров
| Код | Функция | Запрос | Нормальный ответ |
|---|---|---|---|
| 01, 02 | чтение выходов и входов | 12 байт | 9 байт + количество / 8 с округлением вверх |
| 03, 04 | чтение регистров | 12 байт | 9 байт + 2 × количество |
| 05, 06 | запись одного выхода или регистра | 12 байт | 12 байт, PDU повторяет запрос |
| 15 (0x0F) | запись нескольких выходов | 13 байт + количество / 8 с округлением вверх | 12 байт |
| 16 (0x10) | запись нескольких регистров | 13 байт + 2 × количество | 12 байт |
| 23 (0x17) | запись и чтение регистров одним запросом | 17 байт + 2 × количество для записи | 9 байт + 2 × количество для чтения |
| любая | ответ с исключением | — | 9 байт |
Каждый кадр Modbus TCP на 4 байта длиннее того же кадра RTU: 7 байт заголовка вместо 1 байта адреса и 2 байт CRC. Пределы количества те же, что на последовательной линии: до 2000 битов и 125 регистров на чтение, 1968 битов и 123 регистра на запись — их задаёт размер PDU в 253 байта, а не транспорт.
Функция 23 (Read/Write Multiple registers) сначала записывает регистры, затем читает — за один обмен. В запросе по порядку: адрес и количество для чтения (до 125), адрес и количество для записи (до 121), счётчик байт и значения. Пример из спецификации — записать три регистра с адреса 14 (0x0E) значениями 00FF и прочитать шесть с адреса 3:
запрос PDU: 17 00 03 00 06 00 0E 00 03 06 00 FF 00 FF 00 FF
ответ PDU: 17 0C 00 FE 0A CD 00 01 00 03 00 0D 00 FF
В ответе — счётчик байт 0C и шесть регистров: 00FE, 0ACD, 0001, 0003, 000D, 00FF.
Исключения и шлюзы
Ответ с исключением в Modbus TCP — 9 байт: заголовок с длиной 3, код функции плюс 0x80 и код исключения. На запрос чтения регистров, которых нет, устройство ответит, например, 00 01 00 00 00 03 01 83 02. Коды те же, что в RTU, их таблица — в калькуляторе Modbus RTU. Два из них встречаются в основном в TCP:
- 0A, GATEWAY PATH UNAVAILABLE — шлюз не смог выделить путь к устройству: неверно настроен или перегружен;
- 0B, GATEWAY TARGET DEVICE FAILED TO RESPOND — шлюз переслал запрос на линию, но устройство с таким Unit ID не ответило. Чаще всего неверен Unit ID, скорость или формат порта шлюза.
Сервер, у которого кончились свободные транзакции, отвечает исключением 06 — устройство занято. А кадр с идентификатором протокола не 0 сервер не разбирает вовсе и молча отбрасывает: ответа не будет.
Типичные ошибки
- Кадр RTU по TCP. Некоторые преобразователи Ethernet — RS-485 работают «прозрачно» и передают по TCP кадр RTU с адресом и CRC. Спецификация такой режим не описывает, и с клиентом Modbus TCP он не работает: калькулятор распознаёт такой кадр по верной CRC и показывает правильный вид.
- Неверная длина. Поле длины считает Unit ID и PDU, но не 6 байт заголовка перед ним. Длина, равная длине всего кадра, — частая ошибка самодельных реализаций.
- Unit ID не тот. Устройство прямо в сети может отвечать только на один Unit ID или игнорировать его; шлюз пересылает запрос по Unit ID на линию. Если ответа нет или приходит исключение 0B, проверьте Unit ID первым делом.
- Сдвиг на один регистр. Адреса в кадре считаются с нуля: регистр 40001 — адрес 0. Номер в нотации Modicon переведёт в адрес калькулятор Modbus RTU в режиме «Номер → адрес».
Как устроены функции и данные самого протокола — в статье «Modbus RTU». Прибор на линии RS-485 можно опросить прямо из браузера через Web Serial в Modbus RTU мастере, а сетевой адрес и маску для контроллера с Ethernet подобрать в калькуляторе подсетей.
Частые вопросы
Из чего состоит кадр Modbus TCP?
Из заголовка MBAP длиной 7 байт и PDU — кода функции с данными. Заголовок — это номер транзакции (2 байта), идентификатор протокола (2 байта, всегда 0), длина (2 байта) и Unit ID (1 байт). Запрос на чтение 10 регистров хранения с адреса 0 — 00 01 00 00 00 06 01 03 00 00 00 0A: транзакция 1, протокол 0, длина 6, Unit ID 1 и тот же PDU 03 00 00 00 0A, что в Modbus RTU.
Что считает поле длины в заголовке MBAP?
Число байтов после него: Unit ID и PDU. Сам заголовок до поля длины включительно (6 байт) не считается. Для запроса чтения регистров PDU занимает 5 байт, поэтому длина равна 6, а весь кадр — 12 байт. По этому полю приёмник находит конец кадра в потоке TCP, даже если кадр пришёл двумя сегментами.
Какой Unit ID ставить в Modbus TCP?
Если устройство подключено к сети напрямую, руководство Modbus по TCP/IP рекомендует незначащее значение 0xFF (255); значение 0 тоже допускается. Если запрос идёт через шлюз Modbus TCP — RTU, Unit ID — это адрес устройства на линии RS-485, от 1 до 247: по нему шлюз решает, кому переслать запрос. Многие устройства на практике ждут Unit ID 1 — что принимает конкретный прибор, смотрите в его документации.
Почему в Modbus TCP нет CRC?
Целостность кадра уже проверяют нижние уровни: Ethernet добавляет к каждому кадру CRC-32, а TCP — свою контрольную сумму и повторную передачу потерянных сегментов. Границы кадра задаёт поле длины в заголовке, поэтому не нужны и паузы в 3,5 символа, как в RTU. Если в кадре из сети в конце стоят два байта CRC, это не Modbus TCP, а кадр RTU, переданный по TCP как есть: такой режим спецификация не описывает.
Можно ли отправить запрос Modbus TCP прямо из браузера?
Нет. Страница в браузере не может открыть соединение TCP с произвольным портом, в том числе с портом 502: ей доступны только HTTP, WebSocket и подобные протоколы. Поэтому калькулятор только собирает и разбирает байты. Отправить кадр можно утилитой вроде modpoll или netcat, а прибор на последовательной линии опросить из браузера через Web Serial — в Modbus RTU мастере.
Источники
- Modbus Organization. MODBUS Messaging on TCP/IP Implementation Guide V1.0b, 2006 — ADU из заголовка MBAP и PDU, Unit ID вместо адреса устройства, длина в заголовке вместо пауз (разд. 3.1.2); поля MBAP: транзакция, протокол 0, длина, Unit ID, 7 байт, старшим байтом вперёд, порт 502 (3.1.3); пример запроса, несколько запросов без ожидания ответа, Unit ID 0xFF и 0 (4.4.1.2); проверка ответа по номеру транзакции и протоколу (4.4.1.3); кадр с протоколом не 0 отбрасывается, при нехватке транзакций — исключение 06 (4.4.2.2)
- Modbus Organization. MODBUS Application Protocol Specification V1.1b3, 2012 — PDU не длиннее 253 байт, ADU Modbus TCP — до 260 байт (разд. 4.1); форматы функций 01–06, 15 и 16 (6.1–6.6, 6.11, 6.12); функция 23 и её пример (6.17); коды исключений, в том числе 0A и 0B для шлюзов (7)
- Modicon. Modbus Protocol Reference Guide PI-MBUS-300 Rev. J, 1996 — пример кадра RTU 11 03 00 6B 00 03 76 87 — чтение регистров 40108–40110 устройства 17; на нём проверено преобразование RTU ↔ TCP
Где пригодится
- Как подключить прибор Modbus RTU к сети Ethernet?Шлюз Modbus TCP — RTU: IP шлюза, порт 502, Unit ID = адрес на линии RS-485
- Почему прибор за шлюзом Modbus TCP не отвечает?Unit ID, настройки линии, таймауты, исключения 0A и 0B, доступ по IP
- Чем Modbus RTU over TCP отличается от Modbus TCP?RTU over TCP — кадр с адресом и CRC через сокет; Modbus TCP — заголовок MBAP без CRC
- Сколько регистров можно прочитать одним запросом Modbus?125 на чтение, 123 на запись, 2000 и 1968 битов — из-за PDU в 253 байта
- Почему устройство Modbus TCP не пускает второго клиента?Лимит соединений задаёт устройство; держите одно соединение и не открывайте его на каждый запрос
Встроить калькулятор на свой сайт
Скопируйте код и вставьте его в HTML страницы, статьи или вики. Виджет бесплатный, без рекламы, счётчиков и cookie. Условие одно — ссылка на GAW под рамкой остаётся на месте. Подробнее о виджетах
<iframe src="https://gaw.ru/embed/modbus-tcp/" title="Modbus TCP: сборка и разбор кадров" width="100%" height="640" style="border:1px solid #e3e5e9;border-radius:8px" loading="lazy" allow="clipboard-write"></iframe>
<p style="margin:6px 0 0;font-size:14px">Калькулятор: <a href="https://gaw.ru/tools/modbus-tcp/">Modbus TCP: сборка и разбор кадров</a> — GAW.ru</p>Автоподстройка высоты рамки
Если сайт разрешает скрипты, добавьте этот код один раз в любом месте страницы: рамка будет менять высоту вместе с результатом расчёта.
<script>window.addEventListener("message",function(e){if(e.origin!=="https://gaw.ru"||!e.data||e.data.type!=="gaw:embed-height")return;var f=document.querySelectorAll('iframe[src^="https://gaw.ru/embed/"]');for(var i=0;i<f.length;i++)if(f[i].contentWindow===e.source)f[i].style.height=e.data.height+"px"})</script>Обновлено .
Нашли ошибку в расчёте?