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.