modbus — Protocol slave Modbus RTU

Acest modul oferă o implementare în Python pur a unui slave Modbus RTU care comunică printr-un UART. Acesta menține un tablou intern de regiștri de menținere (holding registers) și răspunde la codurile de funcție Modbus standard 0x03 (Read Holding Registers), 0x06 (Write Single Register) și 0x10 (Write Multiple Registers). CRC-16 (polinomul Modbus) este calculat folosind un tabel de căutare.

De exemplu:

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

Un slave Modbus RTU care citește cereri de la un UART, își actualizează tabloul intern de regiștri și scrie răspunsul corespunzător înapoi pe UART.

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

Construiește un slave ModbusRTU.

  • uart este o instanță UART (de ex. machine.UART sau pyb.UART) folosită pentru a trimite și a recepționa cadre Modbus. UART-ul trebuie configurat cu rata baud, paritatea și timpii de așteptare corespunzători înainte de a fi transmis.

  • slave_id este adresa de slave Modbus (1-247) la care va răspunde această instanță. Cadrele adresate altor ID-uri de slave sunt ignorate.

  • register_num este numărul de regiștri de menținere pe 16 biți care susțin acest slave. Regiștrii sunt stocați în lista REGISTER și inițializați cu zero.

SLAVE_ID: int

Adresa de slave Modbus la care va răspunde această instanță. Setată din argumentul slave_id al constructorului.

uart: machine.UART

Instanța UART transmisă constructorului, folosită pentru toate operațiunile de I/O.

register_num: int

Numărul de regiștri de menținere pe 16 biți, setat din argumentul register_num al constructorului.

REGISTER: list[int]

Listă de lungimea register_num care conține valorile curente ale regiștrilor pe 16 biți. Citirile și scrierile efectuate prin cererile Modbus primite actualizează această listă. Codul aplicației poate citi din sau scrie direct în această listă pentru a face schimb de date cu masterul Modbus.

CRC16_TABLE: list[int]

Tabel de căutare cu 256 de intrări, precalculat pentru polinomul CRC-16 Modbus, folosit de crc16().

any() int

Returnează numărul de octeți disponibili în prezent în tamponul de recepție al UART-ului subiacent (deleagă către uart.any()). Folosiți acest lucru pentru a verifica dacă există o cerere primită înainte de a apela handle().

clear() None

Resetează fiecare intrare din REGISTER la 0.

crc16(data: bytes | bytearray) bytes

Calculează CRC-16 Modbus al data folosind CRC16_TABLE și îl returnează ca un obiect bytes de 2 octeți în format little-endian, potrivit pentru a fi adăugat la un cadru Modbus.

  • data este un bytes/bytearray (sau orice iterabil de numere întregi) care conține octeții pentru care se calculează suma de control.

handle(debug: bool = False) None

Citește o singură cerere Modbus de la UART, actualizează tabloul intern de regiștri după caz și scrie răspunsul corespunzător înapoi pe UART.

Coduri de funcție acceptate:

  • 0x03 Read Holding Registers — răspunde cu intervalul solicitat de valori ale regiștrilor.

  • 0x06 Write Single Register — scrie un singur registru și retransmite adresa și valoarea.

  • 0x10 Write Multiple Registers — scrie un interval contiguu de regiștri și răspunde cu adresa de start și numărul lor.

Răspunsuri de excepție Modbus sunt returnate pentru:

  • Illegal Function (0x01) — cod de funcție neacceptat.

  • Illegal Data Address (0x02) — indice de registru în afara intervalului.

  • Illegal Data Value (0x03) — numărul de octeți nu se potrivește cu cantitatea declarată de regiștri.

Cadrele al căror CRC nu se potrivește sau a căror adresă de slave nu se potrivește cu SLAVE_ID sunt eliminate în mod silențios.

  • debug dacă este True, afișează cererea brută, codul de funcție analizat, răspunsul generat și orice detalii despre erori în REPL. Valoarea implicită este False.