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.
Conheça a Metodologia Eletrogate e Lecione um Curso de Robótica nas Escolas da sua Região!