modbus — Protocolo Modbus RTU escravo#

Este módulo fornece uma implementação em Python puro de um escravo Modbus RTU que comunica através de uma UART. Mantém um array interno de registos de retenção e responde aos códigos de função Modbus padrão 0x03 (Ler Registos de Retenção), 0x06 (Escrever Registo Único) e 0x10 (Escrever Múltiplos Registos). 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)

classe ModbusRTU#

Um escravo Modbus RTU que lê pedidos de uma UART, atualiza o seu array interno de registos e escreve a resposta correspondente de volta para a 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) utilizada para enviar e receber fotogramas Modbus. A UART deve ser configurada com a taxa de baud, paridade e timeouts adequados antes de ser fornecida.

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

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

SLAVE_ID: int#

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

uart: machine.UART#

A instância UART passada ao construtor, utilizada para todas as operações de E/S.

register_num: int#

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

REGISTER: list[int]#

Lista de comprimento register_num que contém os valores atuais dos registos de 16 bits. As leituras e escritas realizadas através de pedidos Modbus recebidos 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 com 256 entradas pré-calculada para o polinómio CRC-16 Modbus, utilizada por crc16().

any() → int#

Devolve o número de bytes atualmente disponíveis no buffer de receção da UART subjacente (delega para uart.any()). Use este método para verificar se existe um pedido recebido antes de chamar handle().

clear() → None#

Repõe todas as entradas em REGISTER para 0.

crc16(data: bytes | bytearray) → bytes#

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

  • data é um bytes/bytearray (ou qualquer iterável de inteiros) que contém os bytes a verificar.

handle(debug: bool = False) → None#

Lê um único pedido Modbus da UART, atualiza o array interno de registos conforme necessário, e escreve a resposta correspondente de volta para a UART.

Códigos de função suportados:

  • 0x03 Ler Registos de Retenção — responde com o intervalo pedido de valores de registo.

  • 0x06 Escrever Registo Único — escreve num único registo e repete o endereço e o valor.

  • 0x10 Escrever Múltiplos Registos — escreve num intervalo contíguo de registos e responde com o endereço inicial e a contagem.

São devolvidas respostas de exceção Modbus para:

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

  • Endereço de Dados Ilegal (0x02) — índice de registo fora do intervalo.

  • Valor de Dados Ilegal (0x03) — contagem de bytes não corresponde à quantidade declarada de registos.

Os fotogramas cujo CRC não coincide ou cujo endereço de escravo não coincide com SLAVE_ID são silenciosamente descartados.

  • debug se True, imprime o pedido bruto, o código de função analisado, a resposta gerada e quaisquer detalhes de erro para o REPL. Por defeito é False.