modbus — פרוטוקול Modbus RTU slave

מודול זה מספק מימוש ב-Python טהור של Modbus RTU slave המתקשר דרך UART. הוא מתחזק מערך holding-register פנימי ומגיב לקודי הפונקציה הסטנדרטיים של Modbus 0x03 (Read Holding Registers), 0x06 (Write Single Register) ו-0x10 (Write Multiple Registers). 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 slave שקורא בקשות מ-UART, מעדכן את מערך האוגרים הפנימי שלו, וכותב את התגובה המתאימה בחזרה ל-UART.

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

בונה Modbus RTU slave מסוג ModbusRTU.

  • uart הוא מופע UART (למשל machine.UART או pyb.UART) המשמש לשליחה וקבלה של פריימים של Modbus. ה-UART חייב להיות מוגדר עם קצב בָּאוּד (baud rate), זוגיות (parity) ו-timeouts מתאימים לפני העברתו.

  • slave_id היא כתובת ה-Modbus slave (1-247) שמופע זה יגיב אליה. פריימים המופנים ל-slave IDs אחרים מתעלמים מהם.

  • register_num הוא מספר ה-holding registers של 16 ביט המגבים slave זה. האוגרים מאוחסנים ברשימה REGISTER ומאותחלים לאפס.

SLAVE_ID: int

כתובת ה-Modbus slave שמופע זה יגיב אליה. מוגדרת מארגומנט הבנאי slave_id.

uart: machine.UART

מופע ה-UART שהועבר לבנאי, המשמש לכל פעולות הקלט/פלט.

register_num: int

מספר ה-holding registers של 16 ביט, מוגדר מארגומנט הבנאי register_num.

REGISTER: list[int]

רשימה באורך register_num המחזיקה את ערכי האוגרים הנוכחיים של 16 ביט. קריאות וכתיבות המבוצעות באמצעות בקשות Modbus נכנסות מעדכנות רשימה זו. קוד היישום עשוי לקרוא מרשימה זו או לכתוב אליה ישירות כדי להחליף נתונים עם ה-Modbus master.

CRC16_TABLE: list[int]

טבלת חיפוש מחושבת מראש של 256 ערכים עבור פולינום ה-CRC-16 של Modbus, המשמשת על ידי crc16().

any() int

מחזירה את מספר הבייטים הזמינים כעת בחוצץ הקבלה של ה-UART הבסיסי (מאצילה ל-uart.any()). השתמשו בזה כדי לבדוק קיום בקשה נכנסת לפני קריאה ל-handle().

clear() None

מאפסת כל ערך ב-REGISTER אל 0.

crc16(data: bytes | bytearray) bytes

מחשבת את ה-Modbus CRC-16 של data באמצעות CRC16_TABLE ומחזירה אותו כאובייקט bytes של 2 בייט בסדר 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 שלהם אינה תואמת את SLAVE_ID מושמטים בשקט.

  • debug אם True, מדפיס את הבקשה הגולמית, קוד הפונקציה המנותח, התגובה שנוצרה וכל פרטי שגיאה אל ה-REPL. ברירת המחדל היא False.