modbus — Protocolo escravo Modbus RTU#

Este módulo fornece uma implementação em Python puro de um escravo Modbus RTU que se comunica por uma UART. Ele mantém um array interno de registradores de retenção (holding registers) e responde aos códigos de função Modbus padrão 0x03 (Read Holding Registers), 0x06 (Write Single Register) e 0x10 (Write Multiple Registers). O CRC-16 (polinômio Modbus) é calculado usando uma tabela de consulta.

Por exemplo:

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#

Um escravo Modbus RTU que lê requisições de uma UART, atualiza seu array interno de registradores e escreve a resposta correspondente de volta na UART.

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

Constrói um escravo ModbusRTU.

  • uart é uma instância de UART (por exemplo, machine.UART ou pyb.UART) usada para enviar e receber quadros Modbus. A UART deve ser configurada com taxa de transmissão (baud rate), paridade e timeouts apropriados antes de ser passada.

  • slave_id é o endereço de escravo Modbus (1-247) ao qual esta instância responderá. Quadros endereçados a outros IDs de escravo são ignorados.

  • register_num é o número de registradores de retenção de 16 bits que respaldam este escravo. Os registradores são armazenados na lista REGISTER e inicializados em zero.

SLAVE_ID: int#

O endereço de escravo Modbus ao qual esta instância responderá. Definido a partir do argumento slave_id do construtor.

uart: machine.UART#

A instância de UART passada ao construtor, usada para toda a E/S.

register_num: int#

O número de registradores de retenção de 16 bits, definido a partir do argumento register_num do construtor.

REGISTER: list[int]#

Lista de comprimento register_num que mantém os valores atuais dos registradores de 16 bits. Leituras e escritas realizadas por requisições Modbus recebidas atualizam esta lista. O código da aplicação pode ler ou escrever diretamente nesta lista para trocar dados com o mestre Modbus.

CRC16_TABLE: list[int]#

Tabela de consulta de 256 entradas pré-computada para o polinômio CRC-16 do Modbus, usada por crc16().

any() int#

Retorna o número de bytes atualmente disponíveis no buffer de recepção da UART subjacente (delega para uart.any()). Use isto para verificar se há uma requisição recebida antes de chamar handle().

clear() None#

Reinicia todas as entradas em REGISTER para 0.

crc16(data: bytes | bytearray) bytes#

Calcula o CRC-16 Modbus de data usando CRC16_TABLE e o retorna como um objeto bytes little-endian de 2 bytes adequado para anexar a um quadro Modbus.

  • data é um bytes/bytearray (ou qualquer iterável de inteiros) contendo os bytes a serem somados na verificação.

handle(debug: bool = False) None#

Lê uma única requisição Modbus da UART, atualiza o array interno de registradores conforme necessário e escreve a resposta correspondente de volta na UART.

Códigos de função suportados:

  • 0x03 Read Holding Registers — responde com o intervalo solicitado de valores de registradores.

  • 0x06 Write Single Register — escreve um único registrador e ecoa o endereço e o valor.

  • 0x10 Write Multiple Registers — escreve um intervalo contíguo de registradores e responde com o endereço inicial e a contagem.

Respostas de exceção Modbus são retornadas para:

  • Illegal Function (0x01) — código de função não suportado.

  • Illegal Data Address (0x02) — índice de registrador fora do intervalo.

  • Illegal Data Value (0x03) — a contagem de bytes não corresponde à quantidade declarada de registradores.

Quadros cujo CRC não corresponde ou cujo endereço de escravo não corresponde a SLAVE_ID são silenciosamente descartados.

  • debug se True, imprime no REPL a requisição bruta, o código de função interpretado, a resposta gerada e quaisquer detalhes de erro. O padrão é False.