modbus --- Modbus RTU slave protocol

โมดูลนี้มีการใช้งาน pure-Python ของ Modbus RTU slave ที่สื่อสารผ่าน UART โดยรักษาอาร์เรย์ holding-register ภายในและตอบสนองต่อ function code Modbus มาตรฐาน 0x03 (Read Holding Registers), 0x06 (Write Single Register) และ 0x10 (Write Multiple Registers) CRC-16 (Modbus polynomial) คำนวณโดยใช้ lookup table

ตัวอย่าง:

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)

สร้าง ModbusRTU slave

  • uart คือ UART instance (เช่น machine.UART หรือ pyb.UART) ที่ใช้ส่งและรับเฟรม Modbus UART ต้องได้รับการกำหนดค่าด้วยอัตราบอด, parity และ timeout ที่เหมาะสมก่อนส่งเข้ามา

  • slave_id คือที่อยู่ Modbus slave (1-247) ที่ instance นี้จะตอบสนอง เฟรมที่ส่งถึง slave ID อื่นจะถูกละเว้น

  • register_num คือจำนวน holding register ขนาด 16 บิตที่รองรับ slave นี้ รีจิสเตอร์ถูกเก็บในรายการ REGISTER และเริ่มต้นเป็นศูนย์

SLAVE_ID: int

ที่อยู่ Modbus slave ที่ instance นี้จะตอบสนอง กำหนดจากอาร์กิวเมนต์ constructor slave_id

uart: machine.UART

UART instance ที่ส่งเข้า constructor ใช้สำหรับ I/O ทั้งหมด

register_num: int

จำนวน holding register ขนาด 16 บิต กำหนดจากอาร์กิวเมนต์ constructor register_num

REGISTER: list[int]

รายการที่มีความยาว register_num ที่เก็บค่ารีจิสเตอร์ 16 บิตปัจจุบัน การอ่านและเขียนที่ดำเนินการผ่านคำขอ Modbus ขาเข้าจะอัปเดตรายการนี้ โค้ดแอปพลิเคชันอาจอ่านหรือเขียนรายการนี้โดยตรงเพื่อแลกเปลี่ยนข้อมูลกับ Modbus master

CRC16_TABLE: list[int]

ตาราง lookup 256 รายการที่คำนวณล่วงหน้าสำหรับ Modbus CRC-16 polynomial ใช้โดย crc16()

any() int

คืนจำนวนไบต์ที่มีอยู่ในปัจจุบันในบัฟเฟอร์รับของ UART พื้นฐาน (ส่งต่อไปยัง uart.any()) ใช้เพื่อตรวจสอบคำขอขาเข้าก่อนเรียก handle()

clear() None

รีเซ็ตทุกรายการใน REGISTER เป็น 0

crc16(data: bytes | bytearray) bytes

คำนวณ Modbus CRC-16 ของ data โดยใช้ CRC16_TABLE และคืนเป็นออบเจ็กต์ bytes little-endian 2 ไบต์ที่เหมาะสำหรับต่อท้ายเฟรม Modbus

  • data คือ bytes/bytearray (หรือ iterable ใดก็ตามของจำนวนเต็ม) ที่มีไบต์ที่จะตรวจสอบ

handle(debug: bool = False) None

อ่านคำขอ Modbus เดียวจาก UART อัปเดตอาร์เรย์รีจิสเตอร์ภายในตามที่จำเป็น และเขียนการตอบสนองที่สอดคล้องกันกลับไปยัง UART

function code ที่รองรับ:

  • 0x03 Read Holding Registers --- ตอบสนองด้วยช่วงค่ารีจิสเตอร์ที่ร้องขอ

  • 0x06 Write Single Register --- เขียนรีจิสเตอร์เดียวและ echo ที่อยู่และค่า

  • 0x10 Write Multiple Registers --- เขียนช่วงรีจิสเตอร์ต่อเนื่องและตอบสนองด้วยที่อยู่เริ่มต้นและจำนวน

การตอบสนองข้อยกเว้น Modbus จะถูกส่งคืนสำหรับ:

  • Illegal Function (0x01) --- function code ที่ไม่รองรับ

  • Illegal Data Address (0x02) --- ดัชนีรีจิสเตอร์อยู่นอกช่วง

  • Illegal Data Value (0x03) --- จำนวนไบต์ไม่ตรงกับปริมาณรีจิสเตอร์ที่ประกาศ

เฟรมที่ CRC ไม่ตรงหรือที่อยู่ slave ไม่ตรงกับ SLAVE_ID จะถูกทิ้งโดยไม่มีการแจ้งเตือน

  • debug ถ้าเป็น True จะพิมพ์คำขอ raw, function code ที่แยกวิเคราะห์, การตอบสนองที่สร้าง และรายละเอียดข้อผิดพลาดใด ๆ ไปยัง REPL ค่าเริ่มต้นคือ False