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().
- 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.
Підтримувані функціональні коди:
0x03Read Holding Registers — відповідає із запитаним діапазоном значень регістрів.0x06Write Single Register — записує один регістр і повертає назад адресу та значення.0x10Write Multiple Registers — записує суміжний діапазон регістрів і відповідає початковою адресою та кількістю.
Виняткові відповіді Modbus повертаються для:
Illegal Function (
0x01) — непідтримуваний функціональний код.Illegal Data Address (
0x02) — індекс регістра виходить за межі діапазону.Illegal Data Value (
0x03) — кількість байтів не відповідає заявленій кількості регістрів.
Кадри, чий CRC не збігається або чия адреса підлеглого пристрою не відповідає
SLAVE_ID, мовчки відкидаються.debug якщо
True, виводить до REPL необроблений запит, розібраний функціональний код, згенеровану відповідь та будь-які деталі помилок. За замовчуваннямFalse.