Laboratório 4 Protocolo de Comunicação Modbus
Prof. César Ofuchi
1. Protocolo Modbus
Modbus é um protocolo de comunicação de dados utilizado em sistemas de automação industrial. Criado na década de 1970 pela Modicon, é um dos mais antigos protocolos utilizados em redes de Controladores lógicos programáveis (PLC) para aquisição de sinais de instrumentos e comandar atuadores. A Modicon (atualmente faz parte do grupo Schneider Electric) colocou as especificações e normas que definem o Modbus em domínio público. Por esta razão, esse protocolo passou a ser utilizado em milhares de equipamentos existentes e é uma das soluções de rede mais baratas para automação industrial.
O mecanismo de controle de acesso é baseado em um esquema de mestre-escravo. O dispositivo mestre envia mensagens solicitando dos escravos que enviem os dados lidos pela instrumentação ou envia sinais a serem escritos nas saídas para o controle dos atuadores. O protocolo possui comandos para envio de dados discretos (entradas e saídas digitais) ou numéricos (entradas e saídas analógicas).
1.1. Formato do quadro Modbus
O formato do quadro MODBUS define as sequências dos dados que são enviados/recebidos. Como ele trabalha no contexto mestre-escravo, somente o mestre pergunta e os escravos só podem responder. Portanto temos dois tipos de quadros principais de mensagens: perguntas do mestre e mensagens de resposta do escravo.
Formato padrão da mensagem de pergunta do Mestre
A mensagem de pergunta do mestre contém o endereço do dispositivo escravo, o código da função, definindo a ação solicitada, dados referentes à função, e um campo de checagem de erro. O formato do quadro de pergunta do protocolo é:
8 bits 8 bits 16 bits 16 bits 16 bits
Endereço do Escravo Código da Função Endereço do Comando Dados Checagem de Erro
Endereço do Escravo: valor de 8 bits representando o dispositivo escravo que está sendo endereçado (1 a 247), 0 é reservado para broadcast (comunicação para todos os escravos). Código da Função: valor de 8 bits que diz ao escravo o tipo de ação a ser tomada.
Endereço do comando: Valor de 16 bits que diz ao escravo qual o endereço inicial relativo ao comando especificado.
Dados: Valor de 16 bits que diz ao escravo qual os parâmetros dos comandos.
Checagem de Erro: Valor de 16 bits que representa o valor do Código de Redundância Cíclica (CR) calculado de toda a mensagem. Ele serve para que o escravo detecte se algum bit do quadro foi alterado devidos a ruídos durante a transmissão.
Formato padrão da mensagem de resposta do Escravo
A mensagem de resposta do escravo contém campos confirmando a ação executada, dados referentes à ação, e um campo de checagem e erro. O formato do quadro de resposta do protocolo é:
8 bits 8 bits 8 bits 8 bits *Tamanho 16 bits Endereço do
Escravo
Código da Função
Tamanho Dados Checagem de
Erro
Endereço do Escravo: valor de 8 bits que identifica o dispositivo escravo que está respondendo. Código da Função: valor de 8 bits que é uma cópia do código da função da mensagem de pergunta para indicar a resposta à mesma.
Tamanho: Valor de 8 bits que contém o número de bytes do campo de dados.
Dados: Contém os dados referentes a função e comandos indagados. Esse campo tem tamanho variável igual a 8 bits vezes o valor recebido no campo Tamanho
Checagem de Erro: Valor de 16 bits que representa o valor do CRC calculado de toda a mensagem.
2. Procedimento
Leia atentamente cada instrução do procedimento a seguir.
2.1. Utilizando o Protocolo Modbus para Acionamento de saídas
Desenvolva um programa que comunique utilizando o protocolo Modbus via serial USB com um computador. O computador irá fazer o papel de Mestre utilizando o programa Modbus poll (verifique no site o guia de utilização desse programa). O seu kit será o escravo que deve responder ao Mestre e realizar os comandos pedidos. Nesta seção do laboratório você deve implementar somente o comando "Escrever em uma saída". Este comando é voltado para ações como ligar/desligar um motor, acender/apagar uma lâmpada, etc. No nosso caso iremos utilizar esse comando para ligar e desligar os LED´s da placa. Se o computador (mestre) demorar mais que 100ms (timeout) para enviar o próximo dado do protocolo, o programa deve descartar os dados recebidos anteriormente e entender que se trata de um novo começo de mensagem.
A seguir será definido o endereço dos escravos e como deve ser os valores das mensagens de pergunta e resposta no caso do comando "Escreve em uma saída".
Definição dos endereços
Os endereços válidos para dispositivos escravos vão do 1 ao 247, e qualquer escravo nessa faixa pode ser endereçado individualmente. O endereço "0" é usado para broadcast, onde todos os escravos irão ser endereçados a mesmo tempo. Os endereços de 248 a 255 são endereços reservados dentro do padrão MODBUS e serão mantidos para fins de compatibilidade. O dispositivo mestre endereça um escravo, quando insere o endereço do escravo no campo de endereço do protocolo da mensagem. Quando o escravo responde à mensagem ele insere o seu próprio endereço no campo de endereço do protocolo, que irá identificar a resposta do escravo. Como não existe mensagem de pergunta ao Mestre, na rede MODBUS o dispositivo mestre não possui endereço.
A tabela de endereços abaixo especifica os dispositivos e seus respectivos endereços dentro da rede MODBUS para este laboratório.
Tabela de Endereços Endereço
(decimal)
Dispositivo Escravo Endereço(Hexadecimal)
0 broadcast 00H
1 Kit 1 01H
2 Kit 2 02H
3 Kit 3 03H
5 Kit 5 05H 6 Kit 6 06H 7 Kit 7 07H 8 Kit 8 08H 9-246 Não utilizado 09H-F6H 247-255 Reservado F7H-FFH
Comando "Escreve em uma saída" ou "Write single coil" (código 05H)
Este comando muda o estado Ligado/Desligado de uma saída e é identificado pelo código hexadecimal 05H no campo "Comando".
A mensagem de pergunta do Mestre deve especificar o endereço da saída e se a mesma deve ser ligada/desligada. As saídas são endereçadas no protocolo iniciando em zero até 65535 ou FFFF em hexadecimal. Quando utilizado o endereço "0" de broadcast muda o estado da saída de todos os escravos. O estado da saída; ligado e desligado é escolhido através da inserção de um código em hexadecimal pré-definido. O valor 0000H solicita que a saída seja desligada. O valor FF00H define que a saída seja ligada.
Para este laboratório os endereços irão corresponder aos LED's da placa como descrito na tabela abaixo:
Endereço(Dec) Endereço(Hex) Descrição
0 00H LED 4
1 01H LED 5
2 02H LED 19
3 03H LED 18
Por exemplo, se quisermos ligar o LED19 do Kit 7, o Mestre irá gerar a seguinte pergunta:
CAMPO CONTEÚDO(HEX) Endereço do Escravo 07H Código da Função 05H Endereço inicial (MSB) 00H Endereço inicial (LSB) 02H Dados (MSB) FFH Dados (LSB) 00H Checagem de erro (LSB) -- Checagem de erro (MSB) --
O campo CRC é gerado a partir dos dados dos campos anteriores e deve ser calculado. A resposta do escravo será um eco da pergunta, retornado após a saída ter mudado de estado. Exemplo: CAMPO CONTEÚDO(HEX) Endereço do Escravo 07H Código da Função 05H Endereço inicial (MSB) 00H Endereço inicial (LSB) 02H Dados (MSB) FFH Dados (LSB) 00H
Checagem de erro (LSB) 2DH Checagem de erro (MSB) 9CH
2.2. Acrescentando ao Modbus o comando de Leitura de Entradas
Nesta parte você deverá acrescentar ao programa do kit a habilidade de responder ao comando de leitura de entradas. Além disso, agora a resposta do kit não será uma cópia ou eco da pergunta e será necessário que o seu programa calcule qual será os valores que irão no campo CRC. Dica: Utilize
o código exemplo no site para calcular o valor dos bytes de CRC.
Comando "Leitura de Entradas" ou "Read Discrete Inputs" (código 02H)
Lê o estado ligado/desligado das entradas discretas do escravo. A mensagem de pergunta especifica a entrada discreta inicial pelo campo de "endereço" e a quantidade de entradas a serem lidas pelo campo de "dados". As entradas são endereçadas no protocolo iniciando em zero. Broadcast não é suportado.
Para o nosso kit serão especificadas como entradas discretas as chaves listadas na tabela a seguir:
Endereço(Dec) Endereço(Hex) Descrição Mnemônico 0 00H Estado LED 4* LED4
1 01H Estado LED 5* LED5
2 02H Estado LED 19* LED19 3 03H Estado LED 18* LED18
4 0AH Joystick Center JCE
5 0BH Joystick Up JUP
6 0DH Joystick Down JDO
7 0DH Joystick Left JLE
8 0EH Joystck Right JRI
* 1 para LED aceso e 0 para LED apagado
Por exemplo, para ler a LED4 e LED5 do KIT 2 o mestre deve gerar a seguinte pergunta:
CAMPO CONTEÚDO(HEX) Endereço do Escravo 02H Código da Função 02H Endereço inicial (MSB) 00H Endereço inicial (LSB) 00H Número de pontos(MSB) 00H Número de pontos(LSB) 02H Checagem de erro (LSB) F9H Checagem de erro (MSB) F8H
Na resposta o estado da entrada é encapsulado na mensagem como um bit por entrada. O estado é indicado por "1"=ligado e "0"=desligado. O bit menos significativo do campo de dados contém o estado da entrada endereçada na pergunta (LED4). Os bits subseqüentes contém o estado das próximas entradas (LED5). Observe o exemplo abaixo:
CAMPO CONTEÚDO(HEX) Endereço do Escravo 02H Código da Função 02H Tamanho(Bytes) 01H Dados 03H Checagem de erro (LSB) 69H Checagem de erro (MSB) F8H
No exemplo, o LED4 e LED5 estão ligados (0000 0011). Observe que na resposta o campo CRC não é o mesmo da pergunta porque as mensagens são diferentes. Portanto agora o escravo precisa calcular o valor dos bits de CRC. Dica: Utilize o código exemplo no site para calcular o valor
dos bytes de CRC.
2.3. Comando "Leitura de Registradores" ou "Read holding registers" (código 03H)
Nesta parte você deverá acrescentar ao programa do kit a habilidade de responder ao comando de leitura de registradores. Os registradores podem ser vistos como qualquer variável do seu programa. Para podermos testar esse programa antes é preciso ter algum tipo de registrador para podermos ler. Utilizando o timer crie uma variável que seja acrescentada a cada segundo que conte de 0 a 59. Crie uma outra variável que seja acrescentada a cada minuto, de 0 a 59 e por fim crie uma variável que seja acrescentada a cada hora de 0 a 23. Ou seja, crie um relógio interno no seu escravo. Comando "Leitura de Registradores" ou "Read holding registers" (código 03H)
Lê o valor de variáveis ou registradores do escravo. A mensagem de pergunta especifica a variável pelo campo de "endereço" e a quantidade de variáveis/registradores a serem lidas pelo campo de "dados". As entradas são endereçadas no protocolo iniciando em zero. Broadcast não é suportado.
Para o nosso kit serão especificadas os seguintes registradores da tabela a seguir: Endereço(Dec) Endereço(Hex) Descrição
1 01H Acelerômetro X
2 02H Acelerômetro Y
3 03H Acelerômetro Z
4 04H Sensor Luminosidade
5 05H Periodo Amostragem Sensores(ms)
Por exemplo, para ler os 3 registradores do kit 2 o mestre deve gerar a seguinte pergunta:
CAMPO CONTEÚDO(HEX) Endereço do Escravo 02H Código da Função 03H Endereço inicial (MSB) 00H Endereço inicial (LSB) 00H Número de pontos(MSB) 00H Número de pontos(LSB) 03H Checagem de erro (LSB) 05H Checagem de erro (MSB) F8H
Na resposta como foi pedido para ler 3 registradores teremos 3 no campo de tamanho. Os dados serão as 3 variáveis: acelX,acelY e acelZ. Observe o exemplo abaixo:
CAMPO CONTEÚDO(HEX) Endereço do Escravo 02H Código da Função 03H Tamanho(Bytes) 06H Dados (acelX MSB) 00H Dados (acelX LSB) 02H Dados (acelY MSB) 00H Dados (acelY LSB) 08H Dados (acelY MSB) 00H Dados (acelY LSB) 05H Checagem de erro (LSB) -H Checagem de erro (MSB) -H
Observe que na resposta o campo CRC não é mostrada neste exemplo, mas na prática precisa ser calculada e enviada.
2.4. Comando "Escrita em Registradores" ou "Write Multiple Registers" (código 16 ou 0x10 hexa)
Nesta parte você deverá acrescentar ao programa do kit a habilidade de responder ao comando de escrita em registradores. A ideia é que possamos, via o Modbus Poll, setar o período de amostragem dos sensores (default 1Hz ou 1000ms).
Comando " Escrita em Registradores" ou "Write Multiple Registers" (código16 ou 0x10 hexa)
Escreve o valor de variáveis ou registradores do escravo. A mensagem de pergunta especifica a variável pelo campo de "endereço" e a quantidade de variáveis/registradores a serem escritas pelo campo de "dados". As entradas são endereçadas no protocolo iniciando em zero. Broadcast não é suportado. Neste comando também é necessário dizer quanto bytes de dados serão enviados além dos valor que será escrito nos registradores.
Para o nosso kit serão especificadas os seguintes registradores da tabela a seguir: Endereço(Dec) Endereço(Hex) Descrição
5 05H Periodo (ms)
Por exemplo, para escrever no registrador do kit 2 o período de 2000 ms (0x7D0 em hexa) mestre deve gerar a seguinte pergunta:
CAMPO CONTEÚDO(HEX) Endereço do Escravo 02H Código da Função 10H Endereço inicial (MSB) 00H Endereço inicial (LSB) 05H Número de pontos(MSB) 00H Número de pontos(LSB) 01H Tamanho(Bytes) 02H Dados (periodo)(MSB) 07H Dados (periodo)(LSB) D0H Checagem de erro (LSB) -H
Checagem de erro (MSB) -H
Na resposta o escravo só irá dizer que executou o comando 10H, com o valor do endereço inicial solicitado e com o número de pontos pedido, além do CRC. Observe o exemplo da resposta correspondente abaixo: CAMPO CONTEÚDO(HEX) Endereço do Escravo 02H Código da Função 10H Endereço inicial (MSB) 00H Endereço inicial (LSB) 00H Número de pontos(MSB) 00H Número de pontos(LSB) 01H Checagem de erro (LSB) -H Checagem de erro (MSB) -H
Observe que na resposta o campo CRC não é mostrada neste exemplo, mas na prática precisa ser calculada e enviada.