Buscar

MODBUS

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 3, do total de 10 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 6, do total de 10 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 9, do total de 10 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Prévia do material em texto

UNIVERSIDADE FEDERAL DE SANTA CATARINA (UFSC) 1
Implementação serial via protocolo Modbus
Lucas Jorjan Alves∗
Prof. Wyllian Bezerra da Silva
Universidade Federal de Santa Catarina (UFSC)
EMB5609 Sistemas de Comunicação
Resumo—O presente artigo descreve as principais caracterís-
ticas do Protocolo de Comunicação Modbus, apresentando os
passos para transmissão serial entre dois microcontroladores
Arduino Uno, usando um como escravo e outro como mestre
, a partir de conversores MAX485. Como objetivo incluem-se a
familiarização com o protocolo Modbus RTU, inserção de ruídos
em sua transmissão e a detecção de erros pelos métodos CRC e
Checksum.
I. INTRODUÇÃO
N este trabalho apresentarei a pesquisa e implementação deuma transmissão serial baseada no protocolo Modbus sob
camada fısica RS-485. No campo das Redes Industriais, este
é, talvez, o protocolo de mais larga utilização, já que diversos
controladores e ferramentas para desenvolvimento de sistemas
supervisórios utilizam este protocolo, isto se deve a sua grande
simplicidade e facilidade de implementação.
O restante do artigo está dividido da seguinte forma: A
primeira seção apresenta o protocolo Modbus, explicando os
tópicos necessários para o entendimento do projeto. Posteri-
ormente, será explicada a montagem do trabalho, mostrando
os materiais utilizados e os passos para obter o experimento.
Em seguida serão expostos os resultados obtidos. Por fim, a
conclusão encerra o artigo, apresentando o ponto de vista do
autor em relação ao desenvolvimento do projeto.
II. FUNDAMENTAÇÃO TEÓRICA
A. Protocolo Modbus
Desenvolvido pela MODICON em 1979 e popularizado no
meio da automação pela Modbus-IDA o protocolo de comu-
nicação MODBUS tem como características a comunicação
mestre-escravo, comum entre os Plcs e os IEDs (instrumento
eletrônicos inteligentes) como módulos input/output. Atuadores
de válvulas, relés, entre outros. Também é característico neste
protocolo o formato da mensagem, funções disponíveis, o
tratamento de erro de comunicação ser fixo e haver dois modos
de comunicação (o RTU e ASCII). O Modbus utiliza como
meio físico o RS-232, RS485 ou Ethernet [1].
Segundo Moraes [2] a tecnologia de comunicação no
protocolo Modbus é o mestre-escravo, sendo que somente
um mestre e, no máximo, 247 escravos podem ser conectados
à rede. Cada escravo pode ter um número variado de entradas e
saídas, não fixo. A comunicação é sempre iniciada pelo mestre
e os nós escravos não se comunicam entre si.
Correspondência ao autor: lucasjalves@gmail.com matrícula UFSC:
16205041
A comunicação via protocolo Modbus se inicia com o mestre
solicitando que os escravos enviem seus dados. Os escravos,
por sua vez, recebem a requisição do mestre e retornam os
dados solicitados. Os dados transmitidos podem ser discretos
ou numéricos. Na figura a seguir podemos observar como é
constituído o quadro de mensagens no protocolo Modbus.
Figura 1. Quadro de mensagens para Modbus
Fonte: autor:Carlos Márcio, link: https:
//www.embarcados.com.br/protocolo-modbus/ [2]
Existem dois modos de transmissão no protocolo Modbus.
Os modos definem a forma como são transmitidos os bytes da
mensagem, e como a informação da mensagem será empacotada
e descompactada. No modo ASC-II os bytes enviados são
convertidos para caracteres compreendidos entre 0-9 e A-F.
No modo RTU(remote terminal unit) os bytes enviados são
compreendidos entre 0x00 e 0xFF, tanto o início do frame
quanto o fim são determinados por um silêncio de transmissão
conforme sera explicado a frente. Como o modo RTU é o
utilizado no projeto, este será detalhado a seguir.
B. Modbus-RTU
Uma mensagem Modbus-RTU é colocada pelo dispositivo
transmissor em um quadro, que tem seu início e fim conhecidos.
Isto permite aos dispositivos que recebem um novo quadro
descobrir quando uma mensagem começa e quando ela é
completada. No modo RTU, os quadros de mensagem são
separados por um silêncio pré-determinado.
Toda mensagem no modo RTU deve ser transmitida conti-
nuiamente, pois se um intervalo de 1,5x tamanho da palavra
UNIVERSIDADE FEDERAL DE SANTA CATARINA (UFSC) 2
for detectado pelo escravo, ele descarta todos os dados que
já recebeu e assume que o novo caracter que recebeu é o
campo de endereço de uma nova mensagem, da mesma forma
se uma mensagem for recebida em um tempo menor que o
silent ocorrerá um erro.[3]
Na rede Modbus, o modo de transmissão definido deve
ser o mesmo para todos os dispositivos. Dessa maneira todos
os dispositivos da comunicação do presente trabalho devem
implementar o modo RTU. A Tabela 6.2 mostra as principais
características dos modos de transmissão.
Figura 2. Comparação entre modos de transmissão RTU e ASCII
Fonte: Moraes,2007 [2]
O campo de checagem de erros é baseado no método CRC
(Redundancy Checking). A partir deste método é verificada se
a mensagem é valida ou não.
C. Camada Física RS-485 para Modbus
O RS-485(conhecido como EIA/TIA-485) é uma interface
padrão da camada física de comunicação. É um tipo de proto-
loco de comunicação serial assíncrona, a qual não necessita
de um clock.
Modbus RTU e ASCII e foram projetados para serem usados
com dispositivos serial que suportam os protocolos RS232,
RS485 e RS422. Para transmissão do experimento foi escolhido
como camada física o RS485, com o uso do conversor TTL
MAX485, possibilitando a comunicação das placas do Arduino.
D. CRC
No modo RTU, o cálculo de checksum adotado é o CRC
(Cyclical Redundandcy Chceck) que calcula o conteúdo de
toda a mensagem. De acordo com Rochol [4], o algoritmo de
CRC é baseado em códigos polinomi- ais, ou seja, as cadeias
de bits são tratadas como polinômios. formados por potências
de x com coeficientes 0 e 1.
O algoritmo de detecção de erros CRC utiliza uma divisão
polinomial, tanto no receptor como no transmissor, em que o
divisor é um polinômio gerador G(x) predefinido, e o dividendo
é um bloco de bits de dados. É gerado um valor de 16 bits
sendo que na composição final desde campo, os 8 bits menos
significativos são enviados primeiro. Este é o último campo da
mensagem sendo que os 8 bits mais significativos representam
o último byte da mensagem.
O dispositivo transmissor calcula o valor do CRC e o integra
à mensagem, transmitindo-a em seguida ao dispositivo receptor,
que por sua vez, recalcula o CRC de toda a mensagem após a
sua total recepção e o compara ao campo CRC da mensagem
enviada, sinalizando erro caso não sejam iguais.
Durante a geração do CRC, cada caracter é submetido a uma
lógica XOR (OU exclusivo) com os bits menos significativos do
CRC, seria a divisão de polinômios , cujo resultado é retornado
a ele mesmo e deslocado uma posição (1 bit) à direita, em
direção ao bit menos significativo, sendo que a posição do bit
mais significativo é preenchida com valor 0 (zero). Após esta
operação, o bit menos significativo é examinado, ocorrendo o
seguinte processamento:
1) Se o valor deste bit for igual a 0, nada ocorre e a rotina
de cálculo do CRC continua normalmente;
2) Se o valor do bit for igual a 1, o conteúdo de todo o CRC
é submetido a uma lógica XOR com um valor constante
e o resultado é retornado ao CRC.
Este processo se repete até que ocorram 8 deslocamentos para
cada caracter da mensagem que é submetido à lógica XOR
com o CRC portanto, o processo só terminará após todos os
caracteres da mensagem terem sido submetidos à lógica XOR
com o CRC, gerando o valor do CRC que será colocado no
Campo Checksum da mensagem.
E. Checksum
Segundo Forouzan [5], assim como o CRC, o checksum
também se baseia no conceito de redundância. O exemplo
da figura 4 será utilizado para uma melhor compreensão do
método.
È possível definir a probabilidade de erro de pacote (ou de
quadro, bloco, célula, etc.) pela formúla abaixo:
Figura 3. taxa de erro por pacote
Fonte: Rochol,2017 [4]
Analisando como é feita as operações no emissor, considera-
se a princípio que queremos transmitir o pacote de dados (7,
11, 12, 0, 6). Para isso, soma-se todos os dados presente no
pacote, resultando no valor 36, entretanto, esse resultadonão
pode ser representado com a mesma quantidade de bits que os
dados. Para isso, são utilizadas as técnicas de deslocamento
cíclico e complemento de 2, nessa ordem. Os dois bits extras
são deslocados ciclicamente (do inglês, wrapped, somando-os
junto com os bits menos significados e fazendo o complemento
da soma. O número obtido é chamado de checksum. Assim, o
pacote a ser transmitido será (7, 11, 12, 0, 6, 9), onde "9"é o
dado correspondente ao checksum.
Para verificar a integridade do pacote recebido, é feita a
soma de todos os dados recebidos, e por fim, é realizado o
deslocamento cíclico seguido do complemento de 2, caso o re-
sultado obtido seja zero, não houve erro durante a transmissão
e a integridade dos dados foi mantido. Caso o resultado não
seja zero, significa que a integridade do sinal não foi mantida
e que houve algo de errado durante a transmissão dos dados.
UNIVERSIDADE FEDERAL DE SANTA CATARINA (UFSC) 3
Figura 4. Exemplo do método de detecção checksum
Fonte: Forouzan,2010 [5]
III. MONTAGEM DO EXPERIMENTO
A. Materiais Utilizados
Para a realização do presente projeto foram utilizados os
seguintes componentes:
• Dois Arduinos Uno
• Computador com sistema operacional Linux
• Dois conversores TTL MAX485
• Jumpers
• Resistores de 220 Ohms
• Diodo emissor de luz (LED)
• protoboard
B. Montagem do experimento
A montagem para transmissão é vista na figura abaixo:
Figura 5. Montagem do experimento na protoboard
Fonte: foto do autor
C. Resultados experimentais
Para transmissão foi escolhido o modbus RTU via RS-485,
a escolha do conversor MAX485 foi devido a seu preço e
simplicidade para comunicação. O modo de comunicação para
o projeto foi simplex. Sua transmissão é em sentido único
ou uniderecional, caracteriza-se em uma ligação na qual os
dados circulam num só um sentido, ou seja do emissor para o
receptor.
Foi possível transmitir e receber os dados implementados,
pelo monitor serial da IDE do arduino foi validado as
informações enviadas. Foram feitas checagens de erros como
o crc e checksum, e também a opção de inserir ruídos no
programa. A adição do LED foi para mostrar quando o arduino
receptor estava recebendo os dados.
O algoritimo foi feito somente para entradas aleatórias de
5 bits, que são enviadas de acordo com a escolha do erro
implementada. Da mesma forma o ruído ao enviar é escolhido
de forma opcional. No arduino receptor é impresso todas
as informações necessárias para ver se há ou não erro na
transmissão, assim como a porcentagem desse possível erro a
partir da fórmula da figura 3.
IV. CONCLUSÃO
Conclui-se que o projeto proposto foi desenvolvido com
sucesso, apesar dos desafios deste período de ensino a distância.
Durante o processo de desenvolvimento do trabalho buscou-se
diferentes ferramentas e recursos para aquisição dos materiais
necessários para realização do mesmo.
Resultou na aplicação da transmissão serial feita entre ar-
duinos com conversores MAX485 usando o protocolo modbus.
Posteriormente testando exemplos práticos para checagem de
possíveis erros, a partir de ruídos gerados pelo programa. O
resultado do trabalho foi enriquecedor, promovendo o desen-
volvimento de novas habilidades que poderão ser utilizadas
em futuros projetos.
Código 1. Código do arduino atuando como master� �
#include <ModbusMaster.h>
#include <SoftwareSerial.h>
SoftwareSerial RS485Serial(10, 11); // RX, TX
#define MAX485_DE 2 //// habilita a ⤦
Ç comunicação
bool gerador0[]={0,0,0,0};
bool crc [4];
int cont=0;
bool entrada_crc=0;
bool ruido=1;
uint8_t pacote[5];
uint8_t checkSum=0;
// objeto intanciado ModbusMaster
ModbusMaster node;
void preTransmission()
{
digitalWrite(MAX485_DE, 1);
}
void postTransmission()
{
digitalWrite(MAX485_DE, 0);
}
void setup()
{
pinMode(MAX485_DE, OUTPUT);
UNIVERSIDADE FEDERAL DE SANTA CATARINA (UFSC) 4
// Modbus communication runs at 115200 baud
Serial.begin(9600);
RS485Serial.begin(4800);
node.begin(1, RS485Serial);
node.preTransmission(preTransmission);
node.postTransmission(postTransmission);
digitalWrite(MAX485_DE, 1); ////habilita ⤦
Ç comunicação com conversor MAX485
}
int led = LOW;
///////////////////////////////// FUNÇÃO DE⤦
Ç EXEMPLO PARA CHECKSUM ⤦
Ç ////////////////////////////
void checksum(){
int i,cont_check=0;
for(i=0;i<5;i++)
{
int aleatorio=random(20);
pacote[i]=aleatorio;
}
for(i=0;i<5;i++)
{
Serial.print("pacote de dados:");
Serial.print("[");Serial.print(i);⤦
Ç Serial.print("] = ");
Serial.println(pacote[i]);
}
////////////////geração de ruido//////////
if(ruido){
int aleatorio_ruido=random(20);
int aleatorio2=random(4);
pacote[aleatorio2]=aleatorio_ruido;
for(i=0;i<5;i++)
{
Serial.print("pacote de dados com ruido⤦
Ç :");
Serial.print("[");Serial.print(i);⤦
Ç Serial.print("] = ");
Serial.println(pacote[i]);
}
}
checkSum=0;
for(i=0;i<5;i++)
{
checkSum =checkSum+pacote[i];
}
Serial.print("Valor da soma:");
Serial.println(checkSum);
uint8_t n=checkSum;
uint8_t a=n;
while(n!=0)
{
n=n/2;
cont_check++;
}
bool binario[cont_check];
for(i=0;i<cont_check;i++)
{
binario[i]=a%2;
a=a/2;
}
for(i=cont_check-1;i≥0;i--)
{
Serial.print("valor da soma em ⤦
Ç binario: ");
Serial.print("[");Serial.print(i);⤦
Ç Serial.print("] = ");
Serial.println(binario[i]);
}
///binario invertido
for(i=cont_check-1;i≥0;i--)
{
if(binario[i]==1){
binario[i]=0;
}else{
binario[i]=1;
}
}
for(i=cont_check-1;i≥0;i--)
{
Serial.print("binario invertido: ");
Serial.print("[");Serial.print(i);⤦
Ç Serial.print("] = ");
Serial.println(binario[i]);
}
bool aux = 1;
for(i=0;i<cont_check;i++)
{
if(binario[i]==aux){
if(binario[i]==1)
aux=1;
binario[i]=0;
}else
{
binario[i]=1;
aux=0;
}
}
Serial.println("soma em binario:");
for(i=cont_check-1;i≥0;i--)
{
Serial.println(binario[i]);
}
for(i=0;i<5;i++)
{
RS485Serial.write(pacote[i]);
}
RS485Serial.write(cont_check);
for(i=0;i<cont_check;i++)
{
RS485Serial.write(binario[i]);
}
int auxiliar;
for(i=0;i<5;i++)
{
auxiliar=pow(2,i)*binario[i]+auxiliar;
}
pacote[4]=auxiliar;
for(i=0;i<5;i++)
UNIVERSIDADE FEDERAL DE SANTA CATARINA (UFSC) 5
{
Serial.print("pacote enviado para o ⤦
Ç receptor:");
Serial.println(pacote[i]);
}
delay(5000);
}
void crc_teste(bool msg[],bool gerador[]){
int i;
/////////////impressao do gerador⤦
Ç ///////////////////////
for(i=0;i<4;i++)
{
Serial.print("gerador");
Serial.print("[");Serial.print(i);⤦
Ç Serial.print("] = ");
Serial.println(gerador[i]);
}
////////////função que gera CRC⤦
Ç ////////////////
for(i=1;i<5;i++)
{
int aleatorio=random(100);
if(aleatorio<30){
msg[i]= 0;
}else{
msg[i]= 1;
}
}
msg[5]=0;msg[6]=0;msg[7]=0;
/////////////impressao da mensagem⤦
Ç ///////////////////////
for(i=0;i<8;i++)
{
Serial.print("mensagem");
Serial.print("[");Serial.print(i);⤦
Ç Serial.print("] = ");
Serial.println(msg[i]);
}
for(i=0;i<4;i++)
{
if(msg[i]==gerador[i])
{
crc[i]=0;
}
else
{
crc[i]=1;
}
}
crc[0]=crc[1];
crc[1]=crc[2];
crc[2]=crc[3];
crc[3]=msg[4];
if(crc[0]==1)
{
for(i=0;i<4;i++)
{
if(crc[i]==gerador[i])
{
crc[i]=0;
}
else
{
crc[i]=1;
}
}
}else
{
for(i=0;i<4;i++)
{
if(crc[i]==gerador0[i])
{
crc[i]=0;
}
else
{
crc[i]=1;
}
}
}
crc[0]=crc[1];
crc[1]=crc[2];
crc[2]=crc[3];
crc[3]=msg[5];
if(crc[0]==1)
{
for(i=0;i<4;i++)
{
if(crc[i]==gerador[i])
{
crc[i]=0;
}
else
{
crc[i]=1;
}
}
}else
{
for(i=0;i<4;i++)
{
if(crc[i]==gerador0[i])
{
crc[i]=0;
}
else
{
crc[i]=1;
}
}
}
crc[0]=crc[1];
crc[1]=crc[2];
crc[2]=crc[3];
crc[3]=msg[6];
if(crc[0]==1)
{
for(i=0;i<4;i++)
{
if(crc[i]==gerador[i])
{
crc[i]=0;
}
else
{
crc[i]=1;
}
}
}else
{
UNIVERSIDADE FEDERAL DE SANTA CATARINA (UFSC) 6
for(i=0;i<4;i++)
{
if(crc[i]==gerador0[i])
{
crc[i]=0;
}
else
{
crc[i]=1;
}
}
}
crc[0]=crc[1];
crc[1]=crc[2];
crc[2]=crc[3];
crc[3]=msg[7];
if(crc[0]==1)
{
for(i=0;i<4;i++)
{
if(crc[i]==gerador[i])
{
crc[i]=0;
}
else
{
crc[i]=1;
}
}
}else
{
for(i=0;i<4;i++)
{
if(crc[i]==gerador0[i])
{
crc[i]=0;
}
else
{
crc[i]=1;
}
}
}
msg[5]=crc[1];
msg[6]=crc[2];
msg[7]=crc[3];
///////impressao crc/////////
for(i=0;i<8;i++)
{
Serial.print("crc");Serial.print("[");Serial.print(i);⤦
Ç Serial.print("] = ");
Serial.println(msg[i]);
}
///////enviando os dados para escravo⤦
Ç /////////
RS485Serial.write(gerador[0]);
RS485Serial.write(gerador[1]);
RS485Serial.write(gerador[2]);
RS485Serial.write(gerador[3]);
for(i=0;i<8;i++)
{
RS485Serial.write(msg[i]);
}
delay(5000);
}
void loop() {
/* atraves da biblioteca ModbusMaster pode-⤦
Ç se enviar para o slave um SingleCoil ⤦
Ç que habilita o led
int result = node.writeSingleCoil(0x000C, led⤦
Ç );
led = !led;
*/
if(entrada_crc){
bool mensagem[8]={1,0,1,0,0,0,0,0};
bool gera[4]={1,0,1,1};
int i;
/////////////impressao do gerador⤦
Ç ///////////////////////
for(i=0;i<4;i++)
{
Serial.print("gerador");
Serial.print("[");Serial.print(i);⤦
Ç Serial.print("] = ");
Serial.println(gera[i]);
}
////////////função que gera CRC⤦
Ç ////////////////
for(i=1;i<5;i++)
{
int aleatorio=random(100);
if(aleatorio<30){
mensagem[i]= 0;
}else{
mensagem[i]= 1;
}
}
mensagem[5]=0;mensagem[6]=0;mensagem⤦
Ç [7]=0;
/////////////impressao da mensagem⤦
Ç ///////////////////////
for(i=0;i<8;i++)
{
Serial.print("mensagem");
Serial.print("[");Serial.print(i);⤦
Ç Serial.print("] = ");
Serial.println(mensagem[i]);
}
/////////////geração de ruído⤦
Ç ///////////////////////
if(ruido){
int aleatorio=random(4);
if(mensagem[aleatorio]== 0){
mensagem[aleatorio]= 1;
}else{
mensagem[aleatorio]= 0;
}
/////////////impressao da mensagem com ⤦
Ç ruído///////////////////////
for(i=0;i<8;i++)
{
Serial.print("mensagem com ruido");
Serial.print("[");Serial.print(i);⤦
Ç Serial.print("] = ");
Serial.println(mensagem[i]);
}
}
UNIVERSIDADE FEDERAL DE SANTA CATARINA (UFSC) 7
crc_teste(mensagem,gera);
}
else{
checksum();
}
delay(5000);
}
 	
Código 2. Código do arduino atuando como slave� �
#include <ModbusSlave.h>
#include <SoftwareSerial.h>
SoftwareSerial RS485Serial(10, 11); // RX, TX
int contador=0;
bool gerador[4];
bool gerador0[]={0,0,0,0};
bool msg[8];
bool crc[4];
int entrada_crc=0;
int contador_check=0;
uint8_t recebe[5];
bool checkSum[10];
int aux;
uint8_t somaPack=0;
uint8_t verificaPack=0;
Modbus slave(RS485Serial, 1, 2);
void setup() {
//pino para habilitar comunicação com ⤦
Ç conversor MAX485
pinMode(2, OUTPUT);
//pino para led
pinMode(12, OUTPUT);
// slave.cbVector[CB_WRITE_COILS] = ⤦
Ç writeDigitalOut;
// set Serial and slave a taxa de 9600.
Serial.begin( 9600 );
RS485Serial.begin(4800);
slave.begin( 9600 );
}
void func_crc();
void loop() {
//slave.poll();
///////////////////////////////// MENSAGEM⤦
Ç COM CRC ⤦
Ç ////////////////////////////
if(entrada_crc){
func_crc();
}
///////////////////////////////// MENSAGEM⤦
Ç COM CHECKSUM ⤦
Ç ////////////////////////////
else{
bool add=1;
verificaPack=0;
somaPack=0;
int i;
if(RS485Serial.available() > 0)
{
/////acende o led ao receber um dado⤦
Ç ////////
digitalWrite(12, HIGH);
if(contador_check<5){
recebe[contador_check]=⤦
Ç RS485Serial.read();
contador_check++;
}
else if(contador_check==5){
aux=RS485Serial.read();
contador_check++;
}
else if(contador_check>5 && ⤦
Ç contador_check≤5+aux ){
checkSum[contador_check-6]=⤦
Ç RS485Serial.read();
contador_check++;
}else{
for(i=0;i<5;i++){
somaPack=somaPack + recebe[i⤦
Ç ];
Serial.print("Pack");
Serial.print("[");⤦
Ç Serial.print(i);⤦
Ç Serial.print("] = ")⤦
Ç ;
Serial.println(recebe[i]);
}
Serial.print("soma dos packs:⤦
Ç ");
Serial.println(somaPack);
for(i=aux-1;i≥0;i--)
{
Serial.print("checkSum");
Serial.print("[");⤦
Ç Serial.print(i);⤦
Ç Serial.print("] = ");
Serial.println(checkSum[i]);
}
///checkSum invertido
for(i=aux-1;i≥0;i--)
{
if(checkSum[i]==1){
checkSum[i]=0;
}else{
checkSum[i]=1;
}
}
for(i=0;i<aux;i++)
{
if(checkSum[i]==add){
if(checkSum[i⤦
Ç ]==1)
add=1;
checkSum[i]=0;
}else
UNIVERSIDADE FEDERAL DE SANTA CATARINA (UFSC) 8
{
checkSum[i]=1;
add=0;
}
}
for(i=0;i<aux;i++)
{
verificaPack = ⤦
Ç verificaPack + ⤦
Ç pow(2,i)*⤦
Ç checkSum[i];
}
verificaPack=⤦
Ç verificaPack - ⤦
Ç somaPack;
if verificaPack == 0{
Serial.print("nao tem ⤦
Ç erros ");
}
else{
Serial.print("erro no⤦
Ç pacote ");
}
//taxa de erro/////
contador_check=0;
}
}
////No final da checagem de erro o led é ⤦
Ç desligado
digitalWrite(12, LOW);
}
delay(50);
}
void func_crc(){
int i;
if(RS485Serial.available()>0){
/////acende o led ao receber um dado⤦
Ç ////////
digitalWrite(12, HIGH);
/*//////lógica CRC /////////
1. se o valor deste bit for igual a 0, ⤦
Ç nada ocorre e a rotina de cálculo ⤦
Ç do CRC continua normalmente;
2. se o valor do bit for igual a 1, o conteú⤦
Ç do de todo o CRC é submetido a uma ló⤦
Ç gica XOR com um valor constante e o ⤦
Ç resultado é retornado ao CRC
*///////////
if(contador<4){
////recebe o mesmo gerador do ⤦
Ç master/////
gerador[contador]=⤦
Ç RS485Serial.read();
contador++;
}
else if(contador>3 && contador<12)
{
//// recebe a mensagem com crc /////
msg[contador-4]=RS485Serial.read⤦
Ç ();
contador++;
}
if(contador==12){
for(i=0;i<4;i++)
{ Serial.print("gerador");
Serial.println(gerador[i]);
}
for(i=0;i<8;i++)
{
Serial.print("Mensagem");
Serial.println(msg[i]);
}
for(i=0;i<4;i++)
{
if(msg[i]==gerador[i])
{
crc[i]=0;
}
else
{
crc[i]=1;
}
}
crc[0]=crc[1];
crc[1]=crc[2];
crc[2]=crc[3];
crc[3]=msg[4];
if(crc[0]==1)
{
for(i=0;i<4;i++)
{
if(crc[i]==gerador[i])
{
crc[i]=0;
}
else
{
crc[i]=1;
}
}
}else
{
for(i=0;i<4;i++)
{
if(crc[i]==gerador0[i])
{
crc[i]=0;
}
else
{
crc[i]=1;
}
}
}
crc[0]=crc[1];
crc[1]=crc[2];
crc[2]=crc[3];
crc[3]=msg[5];
if(crc[0]==1)
{
for(i=0;i<4;i++)
{
if(crc[i]==gerador[i])
UNIVERSIDADE FEDERAL DE SANTA CATARINA (UFSC) 9
{
crc[i]=0;
}
else
{
crc[i]=1;
}
}
}else
{
for(i=0;i<4;i++)
{
if(crc[i]==gerador0[i])
{
crc[i]=0;
}
else
{
crc[i]=1;
}
}
}
crc[0]=crc[1];
crc[1]=crc[2];
crc[2]=crc[3];
crc[3]=msg[6];
if(crc[0]==1)
{
for(i=0;i<4;i++)
{
if(crc[i]==gerador[i])
{
crc[i]=0;
}
else
{
crc[i]=1;
}
}
}else
{
for(i=0;i<4;i++)
{
if(crc[i]==gerador0[i])
{
crc[i]=0;
}
else
{
crc[i]=1;
}
}
}
crc[0]=crc[1];
crc[1]=crc[2];
crc[2]=crc[3];
crc[3]=msg[7];
if(crc[0]==1)
{
for(i=0;i<4;i++)
{
if(crc[i]==gerador[i])
{
crc[i]=0;
}
else
{
crc[i]=1;
}
}
}else
{
for(i=0;i<4;i++)
{
if(crc[i]==gerador0[i])
{
crc[i]=0;
}
else
{
crc[i]=1;
}
}
}
crc[0]=crc[1];
crc[1]=crc[2];
crc[2]=crc[3];
crc[3]=0;
if(crc[0]==1)
{
for(i=0;i<4;i++)
{
if(crc[i]==gerador[i])
{
crc[i]=0;
}
else
{
crc[i]=1;
}
}
}
}
}
}
//recebimento de coil a partir da ⤦
Ç biblioteca modbus
uint8_t writeDigitalOut(uint8_t fc, uint16_t ⤦
Ç address, uint16_t length) {
//Serial.println(fc);
//Serial.println(address);
//Serial.println(length);
if (address == 12) {
digitalWrite(12, slave.readCoilFromBuffer⤦
Ç (0));
}
return STATUS_OK;
}
 	
REFERÊNCIAS
[1] C. d. M. Moraes and P. d. L. Castrucci, Engenharia de
Automação Industrial, 2nd ed. Campinas, SP: Editora
S.A, 2007.
[2] C. marcio. (2014) Protocolo modbus: Fundamentos e
aplicações. [Online]. Available: https://www.embarcados.
com.br/protocolo-modbus
[3] Protocolo de Comunicação Mod-bus RTU/ASCII, ALFA
INSTRUMENTOS, Rio de Janeiro, 2000.
https://www.embarcados.com.br/protocolo-modbus
https://www.embarcados.com.br/protocolo-modbus
UNIVERSIDADE FEDERAL DE SANTA CATARINA (UFSC) 10
[4] J. Rochol, Comunicação de Dados, 22nd ed., São Paulo,
2012.
[5] B. A. Forouzan, Comunicação de Dados e Redes de
Computadores, 4th ed. Porto Alegre: AMGH, 2010.
	Introdução
	FUNDAMENTAÇÃO TEÓRICA
	Protocolo Modbus
	Modbus-RTU
	Camada Física RS-485 para Modbus
	CRC
	Checksum
	MONTAGEM DO EXPERIMENTO
	Materiais Utilizados
	Montagem do experimento
	Resultados experimentais
	CONCLUSÃO

Continue navegando