modbus — Protokół slave Modbus RTU¶
Moduł ten dostarcza czysto pythonową implementację urządzenia slave Modbus RTU, które komunikuje się przez UART. Utrzymuje wewnętrzną tablicę rejestrów holding i odpowiada na standardowe kody funkcji Modbus 0x03 (Read Holding Registers), 0x06 (Write Single Register) oraz 0x10 (Write Multiple Registers). CRC-16 (wielomian Modbus) jest obliczany przy użyciu tablicy przeglądowej.
Na przykład:
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)
klasa ModbusRTU¶
Urządzenie slave Modbus RTU, które odczytuje żądania z UART, aktualizuje swoją wewnętrzną tablicę rejestrów i odsyła odpowiednią odpowiedź z powrotem do UART.
- class modbus.ModbusRTU(uart: machine.UART, slave_id: int = 0x01, register_num: int = 30)¶
Konstruuje urządzenie slave
ModbusRTU.uart to instancja UART (np.
machine.UARTlubpyb.UART) używana do wysyłania i odbierania ramek Modbus. UART musi zostać skonfigurowany z odpowiednią szybkością transmisji (baud), parzystością i limitami czasu przed jego przekazaniem.slave_id to adres slave Modbus (1-247), na który ta instancja będzie odpowiadać. Ramki adresowane do innych identyfikatorów slave są ignorowane.
register_num to liczba 16-bitowych rejestrów holding obsługiwanych przez to urządzenie slave. Rejestry są przechowywane na liście
REGISTERi inicjalizowane wartością zero.
- SLAVE_ID: int¶
Adres slave Modbus, na który ta instancja będzie odpowiadać. Ustawiany z argumentu konstruktora slave_id.
- uart: machine.UART¶
Instancja UART przekazana do konstruktora, używana do całej komunikacji we/wy.
- register_num: int¶
Liczba 16-bitowych rejestrów holding, ustawiana z argumentu konstruktora register_num.
- REGISTER: list[int]¶
Lista o długości
register_numprzechowująca bieżące 16-bitowe wartości rejestrów. Odczyty i zapisy wykonywane poprzez przychodzące żądania Modbus aktualizują tę listę. Kod aplikacji może bezpośrednio odczytywać z tej listy lub zapisywać do niej, aby wymieniać dane z masterem Modbus.
- CRC16_TABLE: list[int]¶
Wstępnie obliczona tablica przeglądowa o 256 wpisach dla wielomianu CRC-16 Modbus, używana przez
crc16().
- any() int¶
Zwraca liczbę bajtów aktualnie dostępnych w buforze odbiorczym bazowego UART (deleguje do
uart.any()). Użyj tego, aby sprawdzić obecność przychodzącego żądania przed wywołaniemhandle().
- crc16(data: bytes | bytearray) bytes¶
Oblicza CRC-16 Modbus dla data przy użyciu
CRC16_TABLEi zwraca je jako 2-bajtowy obiektbytesw kolejności little-endian, odpowiedni do dołączenia do ramki Modbus.data to obiekt
bytes/bytearray(lub dowolny iterowalny obiekt liczb całkowitych) zawierający bajty do obliczenia sumy kontrolnej.
- handle(debug: bool = False) None¶
Odczytuje pojedyncze żądanie Modbus z UART, w razie potrzeby aktualizuje wewnętrzną tablicę rejestrów i odsyła odpowiednią odpowiedź z powrotem do UART.
Obsługiwane kody funkcji:
0x03Read Holding Registers — odpowiada żądanym zakresem wartości rejestrów.0x06Write Single Register — zapisuje pojedynczy rejestr i odsyła echo adresu oraz wartości.0x10Write Multiple Registers — zapisuje ciągły zakres rejestrów i odpowiada adresem początkowym oraz liczbą.
Odpowiedzi wyjątkowe Modbus są zwracane dla:
Illegal Function (
0x01) — nieobsługiwany kod funkcji.Illegal Data Address (
0x02) — indeks rejestru poza zakresem.Illegal Data Value (
0x03) — liczba bajtów nie odpowiada zadeklarowanej liczbie rejestrów.
Ramki, których CRC się nie zgadza lub których adres slave nie odpowiada
SLAVE_ID, są po cichu odrzucane.debug jeśli ma wartość
True, wypisuje surowe żądanie, sparsowany kod funkcji, wygenerowaną odpowiedź oraz wszelkie szczegóły błędów do REPL. DomyślnieFalse.