~/notes / modbus-rtu-pyserial

2026-02-24⚙️ АСУ ТП1 мин0 просм.

Modbus RTU через pyserial: подводные камни

Проблема

При работе с Modbus RTU через pyserial часто сталкиваешься с тем, что устройство не отвечает, хотя физически всё подключено правильно. Разберём основные причины и способы их устранения.

Таймауты

Самая частая ошибка — неправильный таймаут. По стандарту Modbus RTU между фреймами должна быть пауза минимум 3.5 символа. При 9600 бод это около 4 мс.

import serial

ser = serial.Serial(
    port='/dev/ttyUSB0',
    baudrate=9600,
    parity=serial.PARITY_NONE,
    stopbits=serial.STOPBITS_ONE,
    bytesize=serial.EIGHTBITS,
    timeout=1
)

Чётность и стоп-биты

По умолчанию Modbus RTU использует 8N1 (8 бит, без чётности, 1 стоп-бит), но некоторые устройства требуют 8E1 или 8O1. Всегда смотри документацию на конкретный прибор.

Совет: если устройство молчит — первым делом проверь настройки порта через stty -F /dev/ttyUSB0

Права доступа

На Linux пользователь должен быть в группе dialout:

sudo usermod -aG dialout $USER

После этого обязательно перелогиниться. Без этого pyserial будет падать с Permission denied даже если порт существует.

CRC и порядок байт

Modbus RTU использует CRC16. Библиотека minimalmodbus считает его автоматически, но если пишешь свой стек — следи за порядком байт: сначала младший, потом старший.

Итог

Большинство проблем решается проверкой трёх вещей: таймаут, настройки порта и права на устройство. Если всё это в порядке — смотри осциллографом на линии.