modbus — Protocollo slave Modbus RTU¶
Questo modulo fornisce un’implementazione in puro Python di uno slave Modbus RTU che comunica tramite una UART. Mantiene un array interno di holding register e risponde ai codici funzione Modbus standard 0x03 (Read Holding Registers), 0x06 (Write Single Register) e 0x10 (Write Multiple Registers). Il CRC-16 (polinomio Modbus) viene calcolato usando una lookup table.
Ad esempio:
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¶
Uno slave Modbus RTU che legge le richieste da una UART, aggiorna il proprio array interno di registri e riscrive la risposta corrispondente sulla UART.
- class modbus.ModbusRTU(uart: machine.UART, slave_id: int = 0x01, register_num: int = 30)¶
Costruisce uno slave
ModbusRTU.uart è un’istanza UART (ad es.
machine.UARTopyb.UART) usata per inviare e ricevere frame Modbus. La UART deve essere configurata con baud rate, parità e timeout appropriati prima di essere passata.slave_id è l’indirizzo dello slave Modbus (1-247) a cui questa istanza risponderà. I frame indirizzati ad altri ID slave vengono ignorati.
register_num è il numero di holding register a 16 bit che supportano questo slave. I registri sono memorizzati nella lista
REGISTERe inizializzati a zero.
- SLAVE_ID: int¶
L’indirizzo dello slave Modbus a cui questa istanza risponderà. Impostato dall’argomento del costruttore slave_id.
- uart: machine.UART¶
L’istanza UART passata al costruttore, usata per tutto l’I/O.
- register_num: int¶
Il numero di holding register a 16 bit, impostato dall’argomento del costruttore register_num.
- REGISTER: list[int]¶
Lista di lunghezza
register_numche contiene i valori correnti dei registri a 16 bit. Le letture e le scritture eseguite tramite richieste Modbus in arrivo aggiornano questa lista. Il codice applicativo può leggere o scrivere direttamente da questa lista per scambiare dati con il master Modbus.
- CRC16_TABLE: list[int]¶
Lookup table precalcolata di 256 voci per il polinomio Modbus CRC-16, usata da
crc16().
- any() int¶
Restituisce il numero di byte attualmente disponibili nel buffer di ricezione della UART sottostante (delega a
uart.any()). Usalo per verificare la presenza di una richiesta in arrivo prima di chiamarehandle().
- crc16(data: bytes | bytearray) bytes¶
Calcola il CRC-16 Modbus di data usando
CRC16_TABLEe lo restituisce come oggettobyteslittle-endian di 2 byte adatto per essere accodato a un frame Modbus.data è un oggetto
bytes/bytearray(o qualsiasi iterabile di interi) contenente i byte di cui calcolare il checksum.
- handle(debug: bool = False) None¶
Legge una singola richiesta Modbus dalla UART, aggiorna l’array interno dei registri come richiesto e riscrive la risposta corrispondente sulla UART.
Codici funzione supportati:
0x03Read Holding Registers — risponde con l’intervallo richiesto di valori dei registri.0x06Write Single Register — scrive un singolo registro e restituisce in eco l’indirizzo e il valore.0x10Write Multiple Registers — scrive un intervallo contiguo di registri e risponde con l’indirizzo iniziale e il conteggio.
Le risposte di eccezione Modbus vengono restituite per:
Illegal Function (
0x01) — codice funzione non supportato.Illegal Data Address (
0x02) — indice di registro fuori intervallo.Illegal Data Value (
0x03) — il conteggio dei byte non corrisponde alla quantità dichiarata di registri.
I frame il cui CRC non corrisponde o il cui indirizzo slave non corrisponde a
SLAVE_IDvengono scartati silenziosamente.debug se
True, stampa sulla REPL la richiesta grezza, il codice funzione analizzato, la risposta generata e gli eventuali dettagli degli errori. Il valore predefinito èFalse.