modbus --- Giao thức Modbus RTU slave

Module này cung cấp một cài đặt thuần Python của Modbus RTU slave giao tiếp qua UART. Nó duy trì một mảng thanh ghi lưu giữ nội bộ và phản hồi các mã hàm Modbus chuẩn 0x03 (Đọc Holding Registers), 0x06 (Ghi Single Register) và 0x10 (Ghi Multiple Registers). CRC-16 (đa thức Modbus) được tính bằng bảng tra cứu.

Ví dụ:

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

Một Modbus RTU slave đọc yêu cầu từ UART, cập nhật mảng thanh ghi nội bộ và ghi phản hồi tương ứng trở lại UART.

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

Khởi tạo một ModbusRTU slave.

  • uart là một UART instance (ví dụ: machine.UART hoặc pyb.UART) dùng để gửi và nhận các khung Modbus. UART phải được cấu hình với tốc độ baud, parity và timeout phù hợp trước khi được truyền vào.

  • slave_id là địa chỉ Modbus slave (1-247) mà instance này sẽ phản hồi. Các khung gửi đến slave ID khác sẽ bị bỏ qua.

  • register_num là số lượng thanh ghi lưu giữ 16-bit của slave này. Các thanh ghi được lưu trong danh sách REGISTER và được khởi tạo về không.

SLAVE_ID: int

Địa chỉ Modbus slave mà instance này sẽ phản hồi. Được đặt từ tham số khởi tạo slave_id.

uart: machine.UART

UART instance được truyền vào hàm khởi tạo, dùng cho tất cả I/O.

register_num: int

Số lượng thanh ghi lưu giữ 16-bit, được đặt từ tham số khởi tạo register_num.

REGISTER: list[int]

Danh sách độ dài register_num chứa các giá trị thanh ghi 16-bit hiện tại. Các thao tác đọc và ghi qua các yêu cầu Modbus đến sẽ cập nhật danh sách này. Mã ứng dụng có thể đọc hoặc ghi vào danh sách này trực tiếp để trao đổi dữ liệu với Modbus master.

CRC16_TABLE: list[int]

Bảng tra cứu 256 mục được tính trước cho đa thức Modbus CRC-16, được sử dụng bởi crc16().

any() int

Trả về số byte hiện có trong bộ đệm nhận của UART bên dưới (ủy thác cho uart.any()). Dùng để kiểm tra yêu cầu đến trước khi gọi handle().

clear() None

Đặt lại mỗi mục trong REGISTER về 0.

crc16(data: bytes | bytearray) bytes

Tính CRC-16 Modbus của data bằng CRC16_TABLE và trả về dưới dạng đối tượng bytes 2 byte little-endian phù hợp để nối vào khung Modbus.

  • data là một bytes/bytearray (hoặc bất kỳ iterable nào của số nguyên) chứa các byte cần tính tổng kiểm.

handle(debug: bool = False) None

Đọc một yêu cầu Modbus đơn từ UART, cập nhật mảng thanh ghi nội bộ theo yêu cầu và ghi phản hồi tương ứng trở lại UART.

Các mã hàm được hỗ trợ:

  • 0x03 Đọc Holding Registers --- phản hồi với phạm vi giá trị thanh ghi được yêu cầu.

  • 0x06 Ghi Single Register --- ghi một thanh ghi và phản hồi lại địa chỉ và giá trị.

  • 0x10 Ghi Multiple Registers --- ghi một phạm vi liên tiếp các thanh ghi và phản hồi với địa chỉ bắt đầu và số lượng.

Các phản hồi ngoại lệ Modbus được trả về cho:

  • Illegal Function (0x01) --- mã hàm không được hỗ trợ.

  • Illegal Data Address (0x02) --- chỉ mục thanh ghi nằm ngoài phạm vi.

  • Illegal Data Value (0x03) --- số byte không khớp với số lượng thanh ghi đã khai báo.

Các khung có CRC không khớp hoặc địa chỉ slave không khớp với SLAVE_ID sẽ bị loại bỏ silently.

  • debug nếu là True, in ra yêu cầu thô, mã hàm đã phân tích cú pháp, phản hồi đã tạo và bất kỳ chi tiết lỗi nào ra REPL. Mặc định là False.