Neste projeto, vamos construir um sistema de comunicação Half–Duplex utilizando o padrão RS-485 entre dois Arduinos. Neste sistema, ao manusear um potenciômetro no Arduino 1, o LED no Arduino 2 acende com o brilho proporcional ao nível do potenciômetro. A mesma coisa acontece no sentido inverso, entre o potenciômetro do Arduino 2 e o LED do Arduino 1. Esse projeto tem como intuído demonstrar o uso do padrão RS-485 de uma maneira rápida e fácil.
Half-duplex é uma forma de direção do fluxo de dados. Uma comunicação entre dois dispositivos pode acontecer de três maneiras diferentes: simplex, half-duplex ou full-duplex. Na comunicação Half-duplex, temos um dispositivo Transmissor e outro Receptor, sendo que ambos podem transmitir e receber dados, porém não simultaneamente, a transmissão tem sentido bidirecional. Durante uma transmissão half-duplex, em determinado instante um dispositivo A será transmissor e o outro B será receptor, em outro instante os papéis podem se inverter. Por exemplo, o dispositivo A transmitir dados para B:
Em seguida, o sentido da transmissão seria invertido e B transmitiria para A:
A operação de troca de sentido de transmissão entre os dispositivos é chamada de turn-around e o tempo necessário para os dispositivos chavearem entre as funções de transmissor e receptor é chamado de turn-around time.
O padrão RS-485 é bastante utilizado em comunicação entre dispositivos, principalmente em aplicações de aquisição e controle de dados por exemplo CLPs. Uma de suas principais vantagens é que esse padrão permite a utilização de vários dispositivos RS-485 no mesmo barramento, com isso é possível a conexão de vários nós entre si.
O RS-485 é uma interface padrão da camada física de comunicação, um método de transmissão de sinal. Esse método se realiza utilizando um cabo de dois ou três fios: um fio de dados, um fio com dados invertidos e, muitas vezes, um fio terra(GND, 0V), desta forma, transmissores e receptores podem trocar dados através de um único cabo. Tal método de transmissão oferece alta resistência à interferência do modo comum.
O padrão RS-485 define a velocidade máxima da rede em 10Mb/s e distância máxima da rede de 4000 pés, o equivalente a 1.219 metros. Esse padrão é utilizado em diferentes tipo de protocolos, como os protocolos Profibus, OPTOmux, DH-485 e do protocolo Modbus que é bastante utilizado nas indústrias, e entre outros protocolos.
A comunicação Half-duplex com o RS-485 entre os dois Arduinos se dá pelo uso do módulo conversor TTL para RS485 que utiliza o chip MAX485 (datasheet) que é um transceptor de baixa potência e taxa de variação limitada que trabalha em uma única fonte de alimentação de +5 V e de corrente nominal de 300 mA. O módulo pode atingir uma taxa de transmissão máxima de 2.5Mbps.
Os pinos do módulos são:
O mesmo módulo pode ser usado tanto para transmissão como para recepção, bastando habilitar ou desabilitar os pinos RE e DE.
Todos os materiais podem ser comprados em nossa loja.
No firmware desenvolvido nesse tutorial para iniciar a comunicação o Arduino A envia via RS-485 o caractere ‘I’ em seguida o valor do ADC (pino 0) ligado ao potenciômetro e por fim o caractere ‘F’. O valor será recebido no outro o Arduino B que por sua ver ler o valor e escrever no LED, fazendo assim o LED mudar de brilho e vice-versa do Arduino B para o A.
/** * @file Arduino_RS485_1.ino * Criado por: Saulo Aislan * @brief Firmware para receber e enviar dados via RS485 (Arduino Uno). * @version 1.0 * * @copyright Copyright (c) 2022 * */ #include <SoftwareSerial.h> #define ANALOG_PIN 0 // Pino do potenciomentro #define ENB_PIN 4 // HIGH = Transmitindo, LOW = Recebendo #define LED_PIN 10 // Pino do LED SoftwareSerial serialRS(2, 3); // RO, DI /** * @brief setup */ void setup() { Serial.begin(9600); serialRS.begin(9600); pinMode(LED_PIN, OUTPUT); pinMode(ENB_PIN, OUTPUT); digitalWrite(LED_PIN, 0); digitalWrite(ENB_PIN, HIGH); Serial.println("\nComunicação Iniciada!"); } /** * @brief loop */ void loop() { int analogValue = analogRead(ANALOG_PIN); // Leitura do potenciomentro int analogData = map(analogValue, 0, 1023, 0, 200); // Mapeamento do valor // Iniciando transmissão serialRS.print('I'); // Inicio do pacote de transmissão serialRS.print(analogData); // Valor do potenciomento serialRS.print('F'); // Fim do pacote de transmissão serialRS.flush(); delay(5); // Iniciando recebimento digitalWrite(ENB_PIN, LOW); // Habilitar o recebimento do RS485 if(serialRS.available() > 0) { if(serialRS.find('I')) // Inicializando a leitura { int LedValue = 0; LedValue = serialRS.parseInt(); // Transforma em inteiro o valor lido if(serialRS.read() == 'F') // Finalizando a leitura { ledFunc(LedValue); } } } digitalWrite(ENB_PIN, HIGH); // Habilita a transmissão do RS485 } /** * @brief Função para acender o led e aumentar ou * diminuir o brilho de acordo com o valor recebido * @params int lValue valor recebido via RS485 */ void ledFunc(int lValue) { if(lValue >= 10) { analogWrite(LED_PIN, lValue); } else { analogWrite(LED_PIN, 0); } }
/** * @file Arduino_RS485_2.ino * Criado por: Saulo Aislan * @brief Firmware para receber e enviar dados via RS485 (Arduino Mega). * @version 1.0 * * @copyright Copyright (c) 2022 * */ #include <SoftwareSerial.h> #define ANALOG_PIN 0 // Pino do potenciomentro #define ENB_PIN 12 // HIGH = Transmitindo, LOW = Recebendo #define LED_PIN 13 // Pino do LED SoftwareSerial serialRS(10, 11); //RO, DI /** * @brief setup */ void setup () { Serial.begin (9600); serialRS.begin(9600); pinMode(LED_PIN, OUTPUT); pinMode(ENB_PIN, OUTPUT); digitalWrite(LED_PIN, 0); digitalWrite(ENB_PIN, HIGH); Serial.println("\nComunicação Iniciada!"); } /** * @brief loop */ void loop (){ int analogValue = analogRead(ANALOG_PIN); // Leitura do potenciomentro int analogData = map(analogValue, 0, 1023, 0, 200); // Mapeamento do valor // Iniciando transmissão serialRS.print('I'); // Inicio do pacote de transmissão serialRS.print(analogData); // Valor do potenciomento serialRS.print('F'); // Fim do pacote de transmissão serialRS.flush(); delay(5); // Iniciando recebimento digitalWrite(ENB_PIN, LOW); // Habilitar o recebimento do RS485 if(serialRS.available() > 0) { if(serialRS.find('I')) // Inicializando a leitura { int LedValue = 0; LedValue = serialRS.parseInt(); // Transforma em inteiro o valor lido if(serialRS.read() == 'F') // Finalizando a leitura { ledFunc(LedValue); } } } digitalWrite(ENB_PIN, HIGH); // Habilita a transmissão do RS485 } /** * @brief Função para acender o led e aumentar ou * diminuir o brilho de acordo com o valor recebido * @params int lValue valor recebido via RS485 */ void ledFunc(int lValue) { if(lValue >= 10) { analogWrite(LED_PIN, lValue); } else { analogWrite(LED_PIN, 0); } }
Nesse projeto, aprendemos mais sobre comunicação entre dispositivos utilizando o padrão RS-485 e comunicação Half-duplex. Esse projeto é só um pedaço do que é a comunicação entre dispositivos, existe uma vastidão de protocolos e padrões utilizados em diversos cenários, se deseja conhecer mais continue nos seguindo para mais tutoriais e projetos interessantes. Continue acompanhando as postagens semanais do blog e não deixe de visitar nossa loja. Lá, você encontra todos os componentes necessários para desenvolver esse e muitos outros projetos! Que a força estejam com vocês e até mais!
Referências utilizadas no artigo:
|
A Eletrogate é uma loja virtual de componentes eletrônicos do Brasil e possui diversos produtos relacionados à Arduino, Automação, Robótica e Eletrônica em geral.
Tenha a Metodologia Eletrogate dentro da sua Escola! Conheça nosso Programa de Robótica nas Escolas!