modbus — Modbus RTU slavprotokoll

Denna modul tillhandahåller en ren Python-implementation av en Modbus RTU-slav som kommunicerar över en UART. Den underhåller en intern array med holding-register och svarar på standardiserade Modbus-funktionskoder 0x03 (Read Holding Registers), 0x06 (Write Single Register) och 0x10 (Write Multiple Registers). CRC-16 (Modbus-polynom) beräknas med hjälp av en uppslagstabell.

Till exempel:

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

En Modbus RTU-slav som läser förfrågningar från en UART, uppdaterar sin interna registerarray och skriver tillbaka motsvarande svar till UART:en.

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

Konstruerar en ModbusRTU-slav.

  • uart är en UART-instans (t.ex. machine.UART eller pyb.UART) som används för att skicka och ta emot Modbus-ramar. UART:en måste konfigureras med lämplig baudhastighet, paritet och timeouter innan den skickas in.

  • slave_id är den Modbus-slavadress (1-247) som denna instans svarar på. Ramar adresserade till andra slav-ID:n ignoreras.

  • register_num är antalet 16-bitars holding-register som backar denna slav. Register lagras i listan REGISTER och initieras till noll.

SLAVE_ID: int

Den Modbus-slavadress som denna instans svarar på. Anges via konstruktorargumentet slave_id.

uart: machine.UART

UART-instansen som skickades till konstruktorn, används för all I/O.

register_num: int

Antalet 16-bitars holding-register, anges via konstruktorargumentet register_num.

REGISTER: list[int]

Lista med längden register_num som håller de aktuella 16-bitars registervärdena. Läsningar och skrivningar som utförs via inkommande Modbus-förfrågningar uppdaterar denna lista. Applikationskod kan läsa från eller skriva till denna lista direkt för att utbyta data med Modbus-mastern.

CRC16_TABLE: list[int]

Förberäknad uppslagstabell med 256 poster för Modbus CRC-16-polynomet, används av crc16().

any() int

Returnerar antalet byte som för närvarande finns tillgängliga i den underliggande UART:ens mottagningsbuffert (delegerar till uart.any()). Använd detta för att kontrollera om det finns en inkommande förfrågan innan du anropar handle().

clear() None

Återställer varje post i REGISTER till 0.

crc16(data: bytes | bytearray) bytes

Beräknar Modbus CRC-16 för data med hjälp av CRC16_TABLE och returnerar den som ett 2-byte little-endian bytes-objekt lämpligt att lägga till i en Modbus-ram.

  • data är ett bytes/bytearray (eller vilken iterabel av heltal som helst) som innehåller de byte som ska checksummeras.

handle(debug: bool = False) None

Läser en enskild Modbus-förfrågan från UART:en, uppdaterar den interna registerarrayen efter behov och skriver tillbaka motsvarande svar till UART:en.

Funktionskoder som stöds:

  • 0x03 Read Holding Registers — svarar med det begärda intervallet av registervärden.

  • 0x06 Write Single Register — skriver ett enskilt register och ekar tillbaka adressen och värdet.

  • 0x10 Write Multiple Registers — skriver ett sammanhängande intervall av register och svarar med startadressen och antalet.

Modbus-undantagssvar returneras för:

  • Illegal Function (0x01) — funktionskod som inte stöds.

  • Illegal Data Address (0x02) — registerindex utanför intervallet.

  • Illegal Data Value (0x03) — byteantalet matchar inte det deklarerade antalet register.

Ramar vars CRC inte matchar eller vars slavadress inte matchar SLAVE_ID förkastas tyst.

  • debug skriver, om True, ut den råa förfrågan, den tolkade funktionskoden, det genererade svaret och eventuella feldetaljer till REPL. Standardvärdet är False.