modbus — Protocolo esclavo Modbus RTU¶
Este módulo proporciona una implementación en Python puro de un esclavo Modbus RTU que se comunica a través de un UART. Mantiene un array interno de registros de retención y responde a los códigos de función Modbus estándar 0x03 (Read Holding Registers), 0x06 (Write Single Register) y 0x10 (Write Multiple Registers). El CRC-16 (polinomio Modbus) se calcula mediante una tabla de búsqueda.
Por ejemplo:
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 esclavo Modbus RTU que lee solicitudes desde un UART, actualiza su array interno de registros y escribe la respuesta correspondiente de vuelta al UART.
- class modbus.ModbusRTU(uart: machine.UART, slave_id: int = 0x01, register_num: int = 30)¶
Construye un esclavo
ModbusRTU.uart es una instancia de UART (p. ej.
machine.UARTopyb.UART) utilizada para enviar y recibir fotogramas Modbus. El UART debe configurarse con la velocidad en baudios, la paridad y los tiempos de espera adecuados antes de pasarlo.slave_id es la dirección de esclavo Modbus (1-247) a la que responderá esta instancia. Los fotogramas dirigidos a otros IDs de esclavo se ignoran.
register_num es el número de registros de retención de 16 bits que respaldan a este esclavo. Los registros se almacenan en la lista
REGISTERy se inicializan a cero.
- SLAVE_ID: int¶
La dirección de esclavo Modbus a la que responderá esta instancia. Se establece a partir del argumento del constructor slave_id.
- uart: machine.UART¶
La instancia de UART pasada al constructor, utilizada para todas las operaciones de E/S.
- register_num: int¶
El número de registros de retención de 16 bits, establecido a partir del argumento del constructor register_num.
- REGISTER: list[int]¶
Lista de longitud
register_numque contiene los valores actuales de los registros de 16 bits. Las lecturas y escrituras realizadas mediante solicitudes Modbus entrantes actualizan esta lista. El código de la aplicación puede leer o escribir directamente en esta lista para intercambiar datos con el maestro Modbus.
- CRC16_TABLE: list[int]¶
Tabla de búsqueda precalculada de 256 entradas para el polinomio CRC-16 de Modbus, utilizada por
crc16().
- any() int¶
Devuelve el número de bytes disponibles actualmente en el búfer de recepción del UART subyacente (delega en
uart.any()). Úsalo para comprobar si hay una solicitud entrante antes de llamar ahandle().
- crc16(data: bytes | bytearray) bytes¶
Calcula el CRC-16 de Modbus de data usando
CRC16_TABLEy lo devuelve como un objetobyteslittle-endian de 2 bytes adecuado para añadirlo a un fotograma Modbus.data es un
bytes/bytearray(o cualquier iterable de enteros) que contiene los bytes a los que aplicar la suma de comprobación.
- handle(debug: bool = False) None¶
Lee una única solicitud Modbus desde el UART, actualiza el array interno de registros según sea necesario y escribe la respuesta correspondiente de vuelta al UART.
Códigos de función admitidos:
0x03Read Holding Registers — responde con el rango solicitado de valores de registro.0x06Write Single Register — escribe un único registro y devuelve como eco la dirección y el valor.0x10Write Multiple Registers — escribe un rango contiguo de registros y responde con la dirección inicial y la cantidad.
Se devuelven respuestas de excepción Modbus para:
Illegal Function (
0x01) — código de función no admitido.Illegal Data Address (
0x02) — índice de registro fuera de rango.Illegal Data Value (
0x03) — el número de bytes no coincide con la cantidad declarada de registros.
Los fotogramas cuyo CRC no coincide o cuya dirección de esclavo no coincide con
SLAVE_IDse descartan silenciosamente.debug si es
True, imprime la solicitud sin procesar, el código de función analizado, la respuesta generada y cualquier detalle de error en el REPL. El valor predeterminado esFalse.