modbus — Протокол Modbus RTU slave¶
Этот модуль предоставляет реализацию Modbus RTU slave на чистом Python, который обменивается данными по UART. Он поддерживает внутренний массив holding-регистров и отвечает на стандартные коды функций Modbus 0x03 (чтение holding-регистров), 0x06 (запись одного регистра) и 0x10 (запись нескольких регистров). CRC-16 (полином Modbus) вычисляется с помощью таблицы поиска.
Например:
from machine import UART
from modbus import ModbusRTU
uart = UART(1, 115200, timeout=10, timeout_char=10)
modbus = ModbusRTU(uart, slave_id=0x01, register_num=30)
while True:
if modbus.any():
modbus.handle(debug=False)
class ModbusRTU¶
Modbus RTU slave, который считывает запросы из UART, обновляет свой внутренний массив регистров и записывает соответствующий ответ обратно в UART.
- class modbus.ModbusRTU(uart: machine.UART, slave_id: int = 0x01, register_num: int = 30)¶
Создаёт slave
ModbusRTU.uart — это экземпляр UART (например,
machine.UARTилиpyb.UART), используемый для отправки и приёма кадров Modbus. UART должен быть настроен с соответствующей скоростью передачи, чётностью и таймаутами перед передачей.slave_id — это адрес Modbus slave (1-247), на который будет отвечать данный экземпляр. Кадры, адресованные другим slave ID, игнорируются.
register_num — это количество 16-битных holding-регистров, поддерживающих данный slave. Регистры хранятся в списке
REGISTERи инициализируются нулями.
- SLAVE_ID: int¶
Адрес Modbus slave, на который будет отвечать данный экземпляр. Устанавливается из аргумента конструктора slave_id.
- uart: machine.UART¶
Экземпляр UART, переданный в конструктор и используемый для всего ввода-вывода.
- register_num: int¶
Количество 16-битных holding-регистров, устанавливаемое из аргумента конструктора register_num.
- REGISTER: list[int]¶
Список длиной
register_num, содержащий текущие 16-битные значения регистров. Операции чтения и записи, выполняемые через входящие запросы Modbus, обновляют этот список. Код приложения может читать из этого списка или записывать в него напрямую для обмена данными с Modbus master.
- CRC16_TABLE: list[int]¶
Предварительно вычисленная таблица поиска из 256 элементов для полинома Modbus CRC-16, используемая методом
crc16().
- any() int¶
Возвращает количество байтов, доступных в данный момент в приёмном буфере UART (делегирует
uart.any()). Используйте это для проверки наличия входящего запроса перед вызовомhandle().
- crc16(data: bytes | bytearray) bytes¶
Вычисляет Modbus CRC-16 для data с использованием
CRC16_TABLEи возвращает его в виде 2-байтового объектаbytesс порядком байтов little-endian, пригодного для добавления к кадру Modbus.data — это
bytes/bytearray(или любой итерируемый объект целых чисел), содержащий байты для вычисления контрольной суммы.
- handle(debug: bool = False) None¶
Считывает один запрос Modbus из UART, при необходимости обновляет внутренний массив регистров и записывает соответствующий ответ обратно в UART.
Поддерживаемые коды функций:
0x03чтение holding-регистров — отвечает запрошенным диапазоном значений регистров.0x06запись одного регистра — записывает один регистр и возвращает адрес и значение.0x10запись нескольких регистров — записывает непрерывный диапазон регистров и отвечает начальным адресом и количеством.
Ответы с исключениями Modbus возвращаются для:
Недопустимая функция (
0x01) — неподдерживаемый код функции.Недопустимый адрес данных (
0x02) — индекс регистра вне диапазона.Недопустимое значение данных (
0x03) — количество байтов не соответствует объявленному количеству регистров.
Кадры, CRC которых не совпадает или slave-адрес которых не совпадает с
SLAVE_ID, незаметно отбрасываются.debug если
True, выводит в REPL необработанный запрос, разобранный код функции, сгенерированный ответ и любые детали ошибок. По умолчаниюFalse.