modbus — Modbus-RTU-Slave-Protokoll

Dieses Modul stellt eine reine Python-Implementierung eines Modbus-RTU-Slaves bereit, der über einen UART kommuniziert. Es verwaltet ein internes Holding-Register-Array und antwortet auf die Standard-Modbus-Funktionscodes 0x03 (Read Holding Registers), 0x06 (Write Single Register) und 0x10 (Write Multiple Registers). Die CRC-16 (Modbus-Polynom) wird mithilfe einer Nachschlagetabelle berechnet.

Zum Beispiel:

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

Ein Modbus-RTU-Slave, der Anfragen aus einem UART liest, sein internes Register-Array aktualisiert und die entsprechende Antwort zurück an den UART schreibt.

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

Konstruiert einen ModbusRTU-Slave.

  • uart ist eine UART-Instanz (z. B. machine.UART oder pyb.UART), die zum Senden und Empfangen von Modbus-Frames verwendet wird. Der UART muss vor der Übergabe mit passender Baudrate, Parität und Timeouts konfiguriert werden.

  • slave_id ist die Modbus-Slave-Adresse (1-247), auf die diese Instanz antwortet. Frames, die an andere Slave-IDs adressiert sind, werden ignoriert.

  • register_num ist die Anzahl der 16-Bit-Holding-Register, die diesen Slave hinterlegen. Die Register werden in der REGISTER-Liste gespeichert und mit null initialisiert.

SLAVE_ID: int

Die Modbus-Slave-Adresse, auf die diese Instanz antwortet. Wird aus dem Konstruktorargument slave_id gesetzt.

uart: machine.UART

Die an den Konstruktor übergebene UART-Instanz, die für alle Ein-/Ausgaben verwendet wird.

register_num: int

Die Anzahl der 16-Bit-Holding-Register, gesetzt aus dem Konstruktorargument register_num.

REGISTER: list[int]

Liste der Länge register_num, die die aktuellen 16-Bit-Registerwerte enthält. Lese- und Schreibvorgänge, die über eingehende Modbus-Anfragen ausgeführt werden, aktualisieren diese Liste. Anwendungscode kann direkt aus dieser Liste lesen oder in sie schreiben, um Daten mit dem Modbus-Master auszutauschen.

CRC16_TABLE: list[int]

Vorberechnete Nachschlagetabelle mit 256 Einträgen für das Modbus-CRC-16-Polynom, verwendet von crc16().

any() int

Gibt die Anzahl der aktuell im Empfangspuffer des zugrunde liegenden UART verfügbaren Bytes zurück (delegiert an uart.any()). Verwenden Sie dies, um auf eine eingehende Anfrage zu prüfen, bevor Sie handle() aufrufen.

clear() None

Setzt jeden Eintrag in REGISTER auf 0 zurück.

crc16(data: bytes | bytearray) bytes

Berechnet die Modbus-CRC-16 von data mithilfe von CRC16_TABLE und gibt sie als 2 Byte großes bytes-Objekt im Little-Endian-Format zurück, das zum Anhängen an einen Modbus-Frame geeignet ist.

  • data ist ein bytes/bytearray (oder ein beliebiges Iterable von Ganzzahlen), das die zu prüfsummenden Bytes enthält.

handle(debug: bool = False) None

Liest eine einzelne Modbus-Anfrage aus dem UART, aktualisiert bei Bedarf das interne Register-Array und schreibt die entsprechende Antwort zurück an den UART.

Unterstützte Funktionscodes:

  • 0x03 Read Holding Registers — antwortet mit dem angeforderten Bereich von Registerwerten.

  • 0x06 Write Single Register — schreibt ein einzelnes Register und sendet Adresse und Wert zurück.

  • 0x10 Write Multiple Registers — schreibt einen zusammenhängenden Bereich von Registern und antwortet mit der Startadresse und der Anzahl.

Modbus-Ausnahmeantworten werden zurückgegeben für:

  • Illegal Function (0x01) — nicht unterstützter Funktionscode.

  • Illegal Data Address (0x02) — Registerindex außerhalb des gültigen Bereichs.

  • Illegal Data Value (0x03) — Bytezahl stimmt nicht mit der angegebenen Registeranzahl überein.

Frames, deren CRC nicht übereinstimmt oder deren Slave-Adresse nicht mit SLAVE_ID übereinstimmt, werden stillschweigend verworfen.

  • debug gibt, falls True, die rohe Anfrage, den geparsten Funktionscode, die erzeugte Antwort und etwaige Fehlerdetails an die REPL aus. Standardwert ist False.