Baixe o app para aproveitar ainda mais
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
Compartilhar