Промышленные компьютеры. Коммутаторы. Контроллеры.

Подробное описание протокола Modbus TCP с примерами команд

13 августа 2026 2026
Modbus TCP, RTU, ASCII и TCP

Куда посылать команду Modbus TCP?

В сети Ethernet адресом устройства является его IP-адрес. Обычно устройства находятся в одной подсети, где IP-адреса отличаются последними цифрами (например, 192.168.1.20) при использовании маски подсети 255.255.255.0. Интерфейсом служит сеть Ethernet, а протоколом передачи данных — TCP/IP.

Для передачи команд используется TCP-порт 502.


Описание протокола Modbus TCP

Команда Modbus TCP состоит из части сообщения Modbus RTU и специального заголовка MBAP (Modbus Application Header).

Из сообщения Modbus RTU удаляются:

  • SlaveID (адрес устройства) в начале сообщения;
  • CRC (контрольная сумма) в конце сообщения.

Получившаяся часть называется PDU (Protocol Data Unit).


Пример запроса Modbus RTU для чтения значений аналогового выхода (holding registers) из регистров #40108–40110 с адресом устройства 17

11 03 006B 0003 7687

  • 11 — Адрес устройства (SlaveID, 17 в десятичной системе = 11 в шестнадцатеричной системе);
  • 03 — Функциональный код (Function Code, чтение Analog Output Holding Registers);
  • 006B — Адрес первого регистра (40108 − 40001 = 107 = 6B hex);
  • 0003 — Количество регистров для чтения (3 регистра: 40108, 40109, 40110);
  • 7687 — Контрольная сумма (CRC).

Удалив адрес устройства (SlaveID) и контрольную сумму (CRC), получаем PDU:

03 006B 0003

К началу PDU добавляется новый 7-байтовый заголовок MBAP Header, который содержит:

  • Transaction Identifier (2 байта): идентификатор транзакции, устанавливаемый Master для уникальной идентификации каждого запроса. Повторяется устройством Slave в ответе.
  • Protocol Identifier (2 байта): идентификатор протокола, всегда равен 00 00 для Modbus.
  • Length (2 байта): длина сообщения в байтах от Unit Identifier до конца сообщения.
  • Unit Identifier (1 байт): адрес устройства, устанавливаемый Master. Повторяется Slave для идентификации устройства.

Итоговая структура сообщений

Протокол Slave ID / MBAP Header Запрос / PDU CRC
Modbus RTU 11 03 006B 0003 7687
Modbus TCP 0001 0000 0006 11 03 006B 0003
Modbus TCP MBAP Header PDU
Modbus TCP ADU, Application Data Unit

Расшифровка Modbus TCP:

  • 0001 — Идентификатор транзакции (Transaction Identifier);
  • 0000 — Идентификатор протокола (Protocol Identifier);
  • 0006 — Длина сообщения (6 байтов после заголовка);
  • 11 — Адрес устройства (Unit Identifier, 17 в десятичной системе = 11 в шестнадцатеричной системе);
  • 03 — Функциональный код (Function Code, чтение Analog Output Holding Registers);
  • 006B — Адрес первого регистра (40108 − 40001 = 107 = 6B hex);
  • 0003 — Количество регистров для чтения (3 регистра: 40108, 40109, 40110).

Пример ответа от устройства Modbus TCP Slave

0001 0000 0009 11 03 06 022B 0064 007F

Расшифровка ответа:

  • 0001 — Идентификатор транзакции (Transaction Identifier);
  • 0000 — Идентификатор протокола (Protocol Identifier);
  • 0009 — Длина сообщения (9 байтов после заголовка);
  • 11 — Адрес устройства (Unit Identifier, 17 в десятичной системе = 11 в шестнадцатеричной системе);
  • 03 — Функциональный код (Function Code, чтение Analog Output Holding Registers);
  • 06 — Количество байтов в данных (6 байтов);
  • 022B — Значение регистра AO0 (старший разряд: 02 hex, младший разряд: 2B hex, итог: 555 в десятичной системе);
  • 0064 — Значение регистра AO1 (старший разряд: 00 hex, младший разряд: 64 hex, итог: 100 в десятичной системе);
  • 007F — Значение регистра AO2 (старший разряд: 00 hex, младший разряд: 7F hex, итог: 127 в десятичной системе).

Итоги

  • AO0: 02 2B hex = 555 (десятичная система);
  • AO1: 00 64 hex = 100 (десятичная система);
  • AO2: 00 7F hex = 127 (десятичная система).

Типы команд Modbus TCP и их использование

Таблица функций Modbus TCP

Код функции Описание функции Тип значения Тип доступа
01 (0x01) Чтение DO (Read Coil Status) Дискретное Чтение
02 (0x02) Чтение DI (Read Input Status) Дискретное Чтение
03 (0x03) Чтение AO (Read Holding Registers) 16-битное Чтение
04 (0x04) Чтение AI (Read Input Registers) 16-битное Чтение
05 (0x05) Запись одного DO (Force Single Coil) Дискретное Запись
06 (0x06) Запись одного AO (Preset Single Register) 16-битное Запись
15 (0x0F) Запись нескольких DO (Force Multiple Coils) Дискретное Запись
16 (0x10) Запись нескольких AO (Preset Multiple Registers) 16-битное Запись

Отправка команды Modbus TCP для чтения дискретного выхода (0x01)

Эта команда используется для чтения значений дискретных выходов (DO).

В запросе указывается начальный адрес первого регистра DO и количество необходимых значений. Адресация DO начинается с нуля.

Значения DO возвращаются в ответе в одном или нескольких байтах, где:

  • 1 означает включенное состояние (ON),
  • 0 — выключенное состояние (OFF).

Младший бит первого байта данных соответствует первому запрашиваемому адресу DO, остальные биты — последующим адресам. Если запрашивается менее 8 значений, неиспользованные биты заполняются нулями.


Пример структуры запроса и ответа

Байт Запрос Байт Ответ
01 Идентификатор транзакции 01 Идентификатор транзакции
02 Идентификатор протокола 02 Идентификатор протокола
00 Длина сообщения 00 Длина сообщения
06 04
01 Адрес устройства 01 Адрес устройства
01 Функциональный код 01 Функциональный код
00 Адрес первого регистра (Hi) 01 Количество байт далее
00 Адрес первого регистра (Lo) 02 Значение регистра DO 0-1
00 Количество регистров (Hi)
02 Количество регистров (Lo)

Пример результата: Состояния DO0-1 представлены значением 0x02 (в двоичном виде: 0000 0010).

  • DO1 (второй справа бит) = 1 (ON).
  • DO0 (первый справа бит) = 0 (OFF).

Остальные 6 бит заполнены нулями.


Отправка команды Modbus TCP для чтения дискретного ввода (0x02)

Эта команда используется для чтения значений дискретных входов (DI).

Структура запроса и ответа аналогична команде 0x01, но функциональный код заменяется на 0x02.

Пример структуры запроса и ответа

Байт Запрос Байт Ответ
01 Идентификатор транзакции 01 Идентификатор транзакции
02 Идентификатор протокола 02 Идентификатор протокола
00 Длина сообщения 00 Длина сообщения
06 04
01 Адрес устройства 01 Адрес устройства
02 Функциональный код 02 Функциональный код
00 Адрес первого регистра (Hi) 01 Количество байт далее
00 Адрес первого регистра (Lo) 03 Значение регистра DI 0-1
00 Количество регистров (Hi)
02 Количество регистров (Lo)

Пример результата: Состояния DI0-1 представлены значением 0x03 (в двоичном виде: 0000 0011).

  • DI1 (второй справа бит) = 1 (ON).
  • DI0 (первый справа бит) = 1 (ON).

Остальные 6 бит заполнены нулями.


Отправка команды Modbus TCP для чтения аналогового вывода (0x03)

Команда 0x03 используется для чтения значений аналоговых выходов (AO).

В запросе указывается начальный адрес первого регистра AO и количество регистров, которые необходимо прочитать. Каждый регистр содержит 16-битное значение.

Пример структуры запроса и ответа

Байт Запрос Байт Ответ
01 Идентификатор транзакции 01 Идентификатор транзакции
02 Идентификатор протокола 02 Идентификатор протокола
00 Длина сообщения 00 Длина сообщения
06 07
01 Адрес устройства 01 Адрес устройства
03 Функциональный код 03 Функциональный код
00 Адрес первого регистра (Hi) 04 Количество байт далее
00 Адрес первого регистра (Lo) 02 Значение регистра Hi (AO0)
00 Количество регистров (Hi) 2B Значение регистра Lo (AO0)
02 Количество регистров (Lo) 00 Значение регистра Hi (AO1)
64 Значение регистра Lo (AO1)

Пример результата:

  • Значение AO0 представлено байтами 02 2B (в шестнадцатеричной системе), что соответствует значению 555 в десятичной системе.
  • Значение AO1 представлено байтами 00 64 (в шестнадцатеричной системе), что соответствует значению 100 в десятичной системе.

Каждое значение регистра занимает 2 байта, где:

  • Старший байт (Hi) передает старшие 8 бит значения,
  • Младший байт (Lo) передает младшие 8 бит значения.

Отправка команды Modbus TCP для чтения аналогового ввода (0x04)

Команда 0x04 используется для чтения значений аналоговых входов (AI).

В запросе указывается начальный адрес первого регистра AI и количество регистров, которые необходимо прочитать. Каждый регистр содержит 16-битное значение.

Пример структуры запроса и ответа

Байт Запрос Байт Ответ
01 Идентификатор транзакции 01 Идентификатор транзакции
02 Идентификатор протокола 02 Идентификатор протокола
00 Длина сообщения 00 Длина сообщения
06 07
01 Адрес устройства 01 Адрес устройства
04 Функциональный код 04 Функциональный код
00 Адрес первого регистра (Hi) 04 Количество байт далее
00 Адрес первого регистра (Lo) 00 Значение регистра Hi (AI0)
00 Количество регистров (Hi) 0A Значение регистра Lo (AI0)
02 Количество регистров (Lo) 00 Значение регистра Hi (AI1)
64 Значение регистра Lo (AI1)

Пример результата:

  • Значение AI0 представлено байтами 00 0A (в шестнадцатеричной системе), что соответствует значению 10 в десятичной системе.
  • Значение AI1 представлено байтами 00 64 (в шестнадцатеричной системе), что соответствует значению 100 в десятичной системе.

Каждое значение регистра занимает 2 байта, где:

  • Старший байт (Hi) передает старшие 8 бит значения,
  • Младший байт (Lo) передает младшие 8 бит значения.

Отправка команды Modbus TCP для записи дискретного вывода (0x05)

Команда 0x05 используется для записи значения одного дискретного выхода (DO).

  • Значение FF 00 (в шестнадцатеричной системе) устанавливает выход в состояние включен (ON).
  • Значение 00 00 устанавливает выход в состояние выключен (OFF).
  • Любые другие значения недопустимы и не изменят состояние выхода.

Ответ на запрос представляет собой эхо-запрос (повтор запроса), который подтверждает изменение состояния выхода.

Пример структуры запроса и ответа

Байт Запрос Байт Ответ
01 Идентификатор транзакции 01 Идентификатор транзакции
02 Идентификатор протокола 02 Идентификатор протокола
00 Длина сообщения 00 Длина сообщения
06 06
01 Адрес устройства 01 Адрес устройства
05 Функциональный код 05 Функциональный код
00 Адрес регистра (Hi) 00 Адрес регистра (Hi)
01 Адрес регистра (Lo) 01 Адрес регистра (Lo)
FF Значение (Hi) FF Значение (Hi)
00 Значение (Lo) 00 Значение (Lo)

Пример результата:

В данном случае:

  • Запрос: устанавливает состояние дискретного выхода DO1 в положение включен (ON), используя значение FF 00.
  • Ответ: подтверждает выполнение команды, повторяя запрос.

Состояние DO1 изменилось с выключен (OFF) на включен (ON).


Отправка команды Modbus TCP для записи аналогового вывода (0x06)

Команда 0x06 используется для записи одного значения аналогового выхода (AO).

Ответ на запрос представляет собой эхо-запрос (повтор запроса), который подтверждает успешное выполнение команды.

Пример структуры запроса и ответа

Байт Запрос Байт Ответ
01 Идентификатор транзакции 01 Идентификатор транзакции
02 Идентификатор протокола 02 Идентификатор протокола
00 Длина сообщения 00 Длина сообщения
06 06
01 Адрес устройства 01 Адрес устройства
06 Функциональный код 06 Функциональный код
00 Адрес регистра (Hi) 00 Адрес регистра (Hi)
01 Адрес регистра (Lo) 01 Адрес регистра (Lo)
55 Значение (Hi) 55 Значение (Hi)
FF Значение (Lo) FF Значение (Lo)

Пример результата

В данном случае:

  • Запрос: записывает значение 55 FF (в шестнадцатеричной системе) в регистр AO0.
  • Ответ: подтверждает выполнение команды, повторяя запрос.

Результат:

  • Состояние выхода AO0 изменилось на значение 55 FF (в шестнадцатеричной системе), что соответствует значению 22015 в десятичной системе.

Каждое значение состоит из 2 байт:

  • Старший байт (Hi) содержит старшие 8 бит значения,
  • Младший байт (Lo) содержит младшие 8 бит значения.

Отправка команды Modbus TCP для записи нескольких дискретных выводов (0x0F)

Команда 0x0F используется для записи нескольких значений дискретных выходов (DO).

В запросе указывается начальный адрес первого регистра, количество регистров, которые нужно записать, и их значения. Значения передаются в виде битов, где:

  • 1 — выход включен (ON),
  • 0 — выход выключен (OFF).

Ответ на запрос подтверждает успешную запись, возвращая количество записанных регистров.

Пример структуры запроса и ответа

Байт Запрос Байт Ответ
01 Идентификатор транзакции 01 Идентификатор транзакции
02 Идентификатор протокола 02 Идентификатор протокола
00 Длина сообщения 00 Длина сообщения
08 06
01 Адрес устройства 01 Адрес устройства
0F Функциональный код 0F Функциональный код
00 Адрес первого регистра (Hi) 00 Адрес первого регистра (Hi)
00 Адрес первого регистра (Lo) 00 Адрес первого регистра (Lo)
00 Количество регистров (Hi) 00 Кол-во записанных рег. (Hi)
02 Количество регистров (Lo) 02 Кол-во записанных рег. (Lo)
01 Количество байт далее
02 Значение байт

Пример результата:

  • Запрос:

Указывает начальный адрес регистра DO0.

Записывает значения двух регистров:

  • DO1 изменяется на включен (ON),
  • DO0 остается выключен (OFF).

Значения передаются как 02 (в шестнадцатеричной системе), что соответствует 0000 0010 в двоичном виде.

  • Ответ: подтверждает, что два регистра успешно записаны.

Результат:

Состояние выходов:

  • DO1: включен (ON),
  • DO0: выключен (OFF).

Остальные биты в байте значения остаются заполненными нулями, так как они не используются.


Отправка команды Modbus TCP для записи нескольких аналоговых выводов (0x10)

Команда 0x10 используется для записи нескольких значений аналоговых выходов (AO).

В запросе указываются начальный адрес первого регистра, количество регистров для записи и их значения. Значения передаются в виде 16-битных слов (2 байта на каждое значение).

Ответ на запрос подтверждает успешную запись, возвращая количество записанных регистров.

Пример структуры запроса и ответа

Байт Запрос Байт Ответ
01 Идентификатор транзакции 01 Идентификатор транзакции
02 Идентификатор протокола 02 Идентификатор протокола
00 Длина сообщения 00 Длина сообщения
0B 06
01 Адрес устройства 01 Адрес устройства
10 Функциональный код 10 Функциональный код
00 Адрес первого регистра (Hi) 00 Адрес первого регистра (Hi)
00 Адрес первого регистра (Lo) 00 Адрес первого регистра (Lo)
00 Количество регистров (Hi) 00 Кол-во записанных рег. (Hi)
02 Количество регистров (Lo) 02 Кол-во записанных рег. (Lo)
04 Количество байт далее
00 Значение Hi (AO0)
0A Значение Lo (AO0)
01 Значение Hi (AO1)
02 Значение Lo (AO1)

Пример результата

  • Запрос:

Указывает начальный адрес регистра AO0.

Записывает значения двух регистров:

  • AO0 изменяется на 00 0A (в шестнадцатеричной системе), что соответствует 10 в десятичной системе.
  • AO1 изменяется на 01 02 (в шестнадцатеричной системе), что соответствует 258 в десятичной системе.
  • Ответ: подтверждает, что два регистра успешно записаны.

Результат:

Состояния выходов:

  • AO0: 10 (десятичное значение),
  • AO1: 258 (десятичное значение).

Каждое значение занимает 2 байта:

  • Старший байт (Hi) содержит старшие 8 бит значения,
  • Младший байт (Lo) содержит младшие 8 бит значения.

Ошибки запроса Modbus TCP

Если устройство не может обработать полученный запрос, оно отправляет ответ с кодом ошибки. В ответе функциональный код изменяется: его старший бит устанавливается в 1, чтобы указать на ошибку.

Пример изменения функционального кода в случае ошибки:

Функциональный код в запросе Функциональный код ошибки в ответе Бинарное представление
01 (01 hex) 129 (81 hex) 0000 0001 → 1000 0001
02 (02 hex) 130 (82 hex) 0000 0010 → 1000 0010
03 (03 hex) 131 (83 hex) 0000 0011 → 1000 0011
04 (04 hex) 132 (84 hex) 0000 0100 → 1000 0100
05 (05 hex) 133 (85 hex) 0000 0101 → 1000 0101
06 (06 hex) 134 (86 hex) 0000 0110 → 1000 0110
15 (0F hex) 143 (8F hex) 0000 1111 → 1000 1111
16 (10 hex) 144 (90 hex) 0001 0000 → 1001 0000

Пример запроса и ответа с ошибкой

Байт Запрос Байт Ответ
01 Идентификатор транзакции 01 Идентификатор транзакции
02 Идентификатор протокола 02 Идентификатор протокола
00 Длина сообщения 00 Длина сообщения
06 03
0A Адрес устройства 0A Адрес устройства
01 Функциональный код 81 Функциональный код с измененным битом
04 Адрес первого регистра Hi 02 Код ошибки
A1 Адрес первого регистра Lo
00 Количество регистров Hi
01 Количество регистров Lo

Расшифровка кодов ошибок

Код ошибки Описание
01 Принятый код функции не может быть обработан.
02 Адрес данных, указанный в запросе, недоступен.
03 Значение, содержащееся в поле данных запроса, является недопустимой величиной.
04 Невосстанавливаемая ошибка имела место, пока ведомое устройство пыталось выполнить затребованное действие.
05 Ведомое устройство приняло запрос и обрабатывает его, но это требует много времени. Ответ предохраняет ведущее устройство от генерации ошибки тайм-аута.
06 Ведомое устройство занято обработкой команды. Ведущее устройство должно повторить сообщение позже, когда ведомое освободится.
07 Ведомое устройство не может выполнить программную функцию, заданную в запросе. Возвращается для функций 13 или 14.
08 Ведомое устройство при чтении расширенной памяти обнаружило ошибку паритета. Повторите запрос или выполните ремонт устройства.
10 (0A hex) Шлюз неправильно настроен или перегружен запросами.
11 (0B hex) Устройство отсутствует в сети или не отвечает.

Итог:

Если запрос обработан с ошибкой, ведущее устройство получает модифицированный функциональный код и код ошибки, указывающий на причину проблемы. Это позволяет эффективно диагностировать и устранять неполадки.


Программы для работы с протоколом Modbus TCP

Ниже представлены программы, которые помогут легко взаимодействовать с устройствами Modbus TCP.

Modbus TCP client с поддержкой Modbus TCP. Скачать

Интерфейс программы Modbus Master Tool для работы с протоколами Modbus RTU, ASCII и TCP

Modbus TCP client с поддержкой Modbus TCP. Скачать

Интерфейс программы Modbus TCP client для работы с протоколом Modbus TCP

Оставить заявку