modbus — Modbus RTU slave protocol#

Цей модуль надає реалізацію на чистому Python підлеглого пристрою Modbus RTU, що комунікує через UART. Він підтримує внутрішній масив регістрів зберігання та відповідає на стандартні функціональні коди Modbus: 0x03 (читання регістрів зберігання), 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, що зчитує запити з UART, оновлює внутрішній масив регістрів і записує відповідну відповідь назад у UART.

class modbus.ModbusRTU(uart: machine.UART, slave_id: int = 0x01, register_num: int = 30)#

Конструює підлеглий пристрій ModbusRTU.

  • uart — екземпляр UART (наприклад, machine.UART або pyb.UART), що використовується для надсилання та отримання кадрів Modbus. UART повинен бути налаштований з відповідною швидкістю передачі (бод), парністю та тайм-аутами перед передачею.

  • slave_id — адреса підлеглого пристрою Modbus (1-247), на яку відповідає цей екземпляр. Кадри, адресовані іншим ідентифікаторам підлеглих пристроїв, ігноруються.

  • register_num — кількість 16-бітних регістрів зберігання для цього підлеглого пристрою. Регістри зберігаються у списку REGISTER та ініціалізуються нулями.

SLAVE_ID: int#

Адреса підлеглого пристрою Modbus, на яку відповідає цей екземпляр. Встановлюється з аргументу конструктора slave_id.

uart: machine.UART#

Екземпляр UART, переданий конструктору, що використовується для всіх операцій введення/виведення.

register_num: int#

Кількість 16-бітних регістрів зберігання, встановлена з аргументу конструктора register_num.

REGISTER: list[int]#

Список довжиною register_num, що містить поточні 16-бітні значення регістрів. Читання та записи, що виконуються через вхідні запити Modbus, оновлюють цей список. Код застосунку може безпосередньо читати з цього списку або записувати до нього для обміну даними з майстром Modbus.

CRC16_TABLE: list[int]#

Попередньо обчислена таблиця підстановки з 256 записів для полінома Modbus CRC-16, що використовується crc16().

any() int#

Повертає кількість байтів, що наразі доступні у буфері прийому базового UART (делегує до uart.any()). Використовуйте це для перевірки наявності вхідного запиту перед викликом handle().

clear() None#

Скидає кожен запис у REGISTER до 0.

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 Read Holding Registers — відповідає із запитаним діапазоном значень регістрів.

  • 0x06 Write Single Register — записує один регістр і повертає назад адресу та значення.

  • 0x10 Write Multiple Registers — записує суміжний діапазон регістрів і відповідає початковою адресою та кількістю.

Виняткові відповіді Modbus повертаються для:

  • Illegal Function (0x01) — непідтримуваний функціональний код.

  • Illegal Data Address (0x02) — індекс регістра виходить за межі діапазону.

  • Illegal Data Value (0x03) — кількість байтів не відповідає заявленій кількості регістрів.

Кадри, чий CRC не збігається або чия адреса підлеглого пристрою не відповідає SLAVE_ID, мовчки відкидаються.

  • debug якщо True, виводить до REPL необроблений запит, розібраний функціональний код, згенеровану відповідь та будь-які деталі помилок. За замовчуванням False.