Xbee – Comunicação entre dois Arduinos

A comunicação entre dois ou mais Arduinos é uma prática muito utilizada em eletrônica por permitir a troca de informações e comandos, o que possibilita o monitoramento remoto de variáveis importantes em um sistema de controle utilizando estes equipamentos. Essa comunicação possui grande autonomia e é capaz de otimizar vários sistemas e projetos. Esse tutorial tem como objetivo ensinar como são feitos os processos necessários, os componentes utilizados, as aplicações e algumas informações a respeito do desenvolvimento destes sistemas, para que você possa desenvolver sua aplicação de transmissão de dados utilizando dois Arduinos e Xbee com eficiência.

[toc]

kit robotica educacional com Arduino ESP ou Microbit

Módulo Xbee

O Xbee é um módulo de rádio frequência que realiza comunicação serial entre dois pontos para estabelecer conexões wireless. As redes utilizam o protocolo ZigBee, contando com taxas de transferência de dados que variam entre 20kbps e 250kbps e são capazes de hospedar milhares de dispositivos. O protocolo ZigBee que é baseado no IEEE 802.15.4 permite uma grande fidelidade de conexão, tornando-se assim ideal para projetos robustos.

Exemplo de módulo Xbee.

Algumas aplicações

A comunicação robusta e segura entre dois ou mais Arduinos pode ser aplicada em diversos projetos que utilizam do monitoramento remoto. Alguns deles são listados a seguir:

  • Acompanhamento de atividades de alto risco;
  • Automação residencial, comercial e industrial;
  • Telemetria em veículos Baja e Fórmula SAE;
  • Controle de processos à longa distância;

Mãos à obra – Realizando a comunicação entre dois Arduinos utilizando o Xbee

Componentes necessários

Neste tutorial, é necessário que se tenha em mãos os seguintes componentes:

Configurando o Xbee utilizando o software XCTU

Para mais informações sobre o módulo XBee e como configurá-lo, basta seguir o tutorial “Configurando o XBee utilizando o software XCTU”, que pode ser consultado no seguinte link. Feito isso, siga as instruções a seguir para realizar a comunicação entre dois Arduinos.

Comunicação entre os dois arduinos

Uma vez configurados os módulos Xbee utilizando o XCTU, faça as ligações elétricas conforme os diagramas das figuras a seguir. Nesse tutorial temos dois hardware a serem montados, vamos chama-los de conjunto transmissor e conjunto receptor.

 

Diagrama de ligação do conjunto transmissor.

 

Diagrama de ligação do conjunto receptor.

Programando

Nesse tutorial vamos utilizar dois Arduinos comunicando entre si por meio dos módulos Xbee, a intenção é pressionar botões conectados a um microcontrolador e por sua vez transmitir tal informação para o conjunto receptor que analisará o comando e aturá em suas saídas, representadas por leds. Como a aplicação é composta por dois Arduino, a seguir é apresentado o código do conjunto transmissor:

#include<SoftwareSerial.h>
SoftwareSerial XBEE1(3, 2);

#define btn1 10
#define btn2 9
#define btn3 8

void setup() {

  Serial.begin(9600);
  XBEE1.begin(9600);

  pinMode(btn1, INPUT_PULLUP);
  pinMode(btn2, INPUT_PULLUP);
  pinMode(btn3, INPUT_PULLUP);

  Serial.println("Iniciando...");
}

void loop() {

  if (digitalRead(btn1) == LOW) {
    while (digitalRead(btn1) == LOW) {}
    XBEE1.print(1);
    XBEE1.println("");
    Serial.println("LED 1");
  }

  if (digitalRead(btn2) == LOW) {
    while (digitalRead(btn2) == LOW) {}
    XBEE1.print("2");
    XBEE1.println("");
    Serial.println("LED 2");
  }

  if (digitalRead(btn3) == LOW) {
    while (digitalRead(btn3) == LOW) {}
    XBEE1.print('3');
    XBEE1.println("");
    Serial.println("LED 3");
  }
}

Do mesmo modo, é necessário programar o segundo Arduino com o código do conjunto receptor, como pode ser visualizado a seguir:

#include<SoftwareSerial.h>
SoftwareSerial XBEE2(3, 2);

#define LED1 10
#define LED2 9
#define LED3 8

int c = 0;

void setup() {

  Serial.begin(9600);
  XBEE2.begin(9600);

  pinMode(LED1, OUTPUT);
  pinMode(LED2, OUTPUT);
  pinMode(LED3, OUTPUT);
  pinMode(13, OUTPUT);
}

void loop() {

  if (XBEE2.available() > 0) {

    c = XBEE2.read();

    if (c == "1") {
      digitalWrite(LED1, !digitalRead(LED1));
      Serial.print("LED1 - ");
      Serial.println(digitalRead(LED1));
    }

    if (c == "2") {
      digitalWrite(LED2, !digitalRead(LED2));
      Serial.print("LED2 - ");
      Serial.println(digitalRead(LED2));
    }

    if (c == "3") {
      digitalWrite(LED3, !digitalRead(LED3));
      Serial.print("LED3 - ");
      Serial.println(digitalRead(LED3));
    }

    Serial.flush();
  }

}

Colocando para funcionar

A seguir, um pequeno vídeo do funcionamento da comunicação entre os Arduinos:

Testando a comunicação.

Monitor Serial.

Entendendo a fundo

Software – Conjunto transmissor

– Incluindo a biblioteca que será utilizada

Primeiramente para que a aplicação funcione de forma adequada é necessário adcionar a biblioteca SoftwareSerial.h, isso permitirá normear dois pinos digitais do Arduino para realizarem comunicação serial com o módulo Xbee transmissor.

#include<SoftwareSerial.h>

Na linha seguinte, o comando SoftwareSerial XBEE1(3, 2) é um construtor da biblioteca SoftwareSerial.h, esse permite criar um objeto que poderá acessar todas as funções da biblioteca, denominado de XBEE1. Os dois parâmetros dentro dos parênteses informam quais seram os pinos de comunicação serial. Sendo assim o pino 3 é o Rx e o pino 2 o Tx.

SoftwareSerial XBEE1(3, 2);

– Declarando as variáveis do projeto

Posteriormente, para receber os sinais dos botões é necessário a criação ou definição das variáveis de entrada do Arduino. A variável btn1 é responsável por definir o pino de entrada do sinal do botão 1 no microcontrolador, e o mesmo acontece para o botão 2 botão 3.

#define btn1 10
#define btn2 9
#define btn3 8

– Estabelecendo as configurações iniciais

Na função setup(), primeiro inicializamos a comunicação serial com a função Serial.begin(9600), onde definimos o baudrate para 9600. Na próxima linha iniciamos a porta serial responsável por enviar as informações para o módulo Xbee e definimos o baudrate para 9600. Continuando, a linha seguinte é composta pela definição das I/O, ou seja, com a função pinMode(btn1, INPUT_PULLUP) definimos que a variável btn1 é um pino de entrada do microcontrolador e habilitamos os resistores de PULLUP internos do Arduino, eliminando a necesidade de montar a configuração externamente. Da mesma forma repetimos o comando para os demais botões. A última linha a ser executada dentro do setup() é a função Serial.println(“Iniciando…”) que exibe no monitor serial a string dentro dos parênteses.

void setup() {

  Serial.begin(9600);
  XBEE1.begin(9600);

  pinMode(btn1, INPUT_PULLUP);
  pinMode(btn2, INPUT_PULLUP);
  pinMode(btn3, INPUT_PULLUP);

  Serial.println("Iniciando...");
}

– Enviando dados para o outro Arduino

A função void loop() é a parte responsável por identificar se algum dos três botões foram pressionados. A condicional if(digitalRead(btn1) == LOW)  avalia o caso em que o primeiro botão seja pressionado, levando a entrada do Arduino a nível lógico baixo (LOW).

if (digitalRead(btn1) == LOW) {

Se o botão 1 se mantiver pressionado as condições dentro das chaves do if() não são executadas, pois a instrução while(digitalRead(btnt1) == LOW){} também é verdadeira e não possui nenhuma instrução dentro de suas chaves. Esse procedimento também conhecido como intertravamento elétrico é utilizado para evitar que ao pressionar os botões o Arduino execute as instruções diversas veses enquanto o botão esta pressionado.

while (digitalRead(btn1) == LOW) {}

Após soltar o botão o while é interrompido e a função XBEE1.print(“1”) envia o valor 1 para o conjunto receptor por meio do Xbee e comando Serial.println(“LED 1”) exibe no monitor serial a string LED 1. O mesmo procedimento explicado acima acontece para todos os demais botões com excessão do valor a ser enviando para acionar os led do conjunto receptor e a mensagem no monitor serial.

  XBEE1.print("1");
  XBEE1.println("");
  Serial.println("LED 1");
}

A seguir exibimos a função void loop()  do conjunto transmissor por completo:

  if (digitalRead(btn1) == LOW) {
    while (digitalRead(btn1) == LOW) {}
    XBEE1.print("1");
    XBEE1.println("");
    Serial.println("LED 1");
  }

  if (digitalRead(btn2) == LOW) {
    while (digitalRead(btn2) == LOW) {}
    XBEE1.print("2");
    XBEE1.println("");
    Serial.println("LED 2");
  }

  if (digitalRead(btn3) == LOW) {
    while (digitalRead(btn3) == LOW) {}
    XBEE1.print("3");
    XBEE1.println("");
    Serial.println("LED 3");
  }

Software – Conjunto receptor

– Incluindo a biblioteca que será utilizada

Da mesma forma que no primeiro Arduino é necessário incluir a biblioteca SoftwareSerial.h, isso permitirá normear dois pinos digitais do Arduino para realizarem comunicação serial com o módulo Xbee receptor.

#include<SoftwareSerial.h>

Na linha seguinte, o comando SoftwareSerial XBEE2(3, 2) é um construtor da biblioteca SoftwareSerial.h, esse permite criar um objeto que poderá acessar todas as funções da biblioteca, denominado de XBEE2. Os dois parâmetros dentro dos parênteses informam quais seram os pinos de comunicação serial. Sendo assim o pino 3 é o Rx e o pino 2 o Tx.

SoftwareSerial XBEE2(3, 2);

– Declarando as variáveis do projeto

Subsequentemente para acionar os leds no conjunto receptor é necessário a criação ou definição das variáveis de saída do Arduino. A variável LED1 é responsável por definir o pino de saída do primeiro led do microcontrolador, e o mesmo acontece para os leds 2 e 3. Já a variável C (do tipo inteiro) é criada para armazenar os comandos recebido por radiofrequência do Xbee receptor.

#define LED1 10
#define LED2 9
#define LED3 8

int c = 0;

– Estabelecendo as configurações iniciais

Na função setup() repetimos o procedimento do primeiro Arduino,  inicializamos a comunicação serial com a função Serial.begin(9600), onde definimos o baudrate para 9600. Na próxima linha iniciamos a porta serial responsável por enviar as informações para o módulo Xbee e definimos o baudrate para 9600. Posteriormente com as função pinMode(LED1, OUTPUT) definimos a variável LED1 como saída de dados, o mesmo é realizado para as variáveis LED2 LED3 que controlam o estados dos leds 2 e  3 respectivamente.

void setup() {

  Serial.begin(9600);
  XBEE2.begin(9600);

  pinMode(LED1, OUTPUT);
  pinMode(LED2, OUTPUT);
  pinMode(LED3, OUTPUT);
}

– Recebendo os dados do transmissor

Na função void loop() do segundo Arduino o objetivo é receber os dados transmitidos e verificar se existe algum comando ou instrução a ser executada para o respectivo comando. A primeira linha a ser executada é if(XBEE2.available()> 0), essa condicional verifica se existe algum dado disponível na porta de comunicação serial do Xbee receptor.

if (XBEE2.available() > 0)

Caso exista alguma informação, a condicional é aceita e a segunda linha é executada, com a instrução c = XBEE2.read(), a variável armazena as informações disponível na porta serial.

c = XBEE2.read();

Em seguida, a próxima linha executada pelo Arduino é uma nova condicional que verifica se o valor de corresponde a 1, caso esse if() seja verdadeiro, a função digitalWrite(LED1, !digitalRead(LED1)) é executada. Uma observação importante a ser feita é sobre o segundo parâmetro da função digitalWrite(), a instrução !digitalRead(LED1), lê o estado atual da saída do led e o inverte, ou seja, com apenas um botão conseguimos ligar e desligar o led 1.

if (c == '1') {
  digitalWrite(LED1, !digitalRead(LED1));

As duas próximas linhas dento do primeiro if() exibem no monitor serial o nome do led e o valor do estado atual (0 – desligado, 1 – ligado). O mesmo procedimento é avaliado para os demais leds, alterando apenas o valor da variável e a saída a ser acionada.

  Serial.print("LED1 - ");
  Serial.println(digitalRead(LED1));
}

A última linha do loop() é composta pela expressão Serial.flush(), essa instrução permite a conclusão da transmissão de dados da porta serial.

Serial.flush();

A seguir exibimos a função void loop() por completo:

  if (XBEE2.available() > 0) {

    c = XBEE2.read();

    if (c == 1) {
      digitalWrite(LED1, !digitalRead(LED1));
      Serial.print("LED1 - ");
      Serial.println(digitalRead(LED1));
    }

    if (c == 2) {
      digitalWrite(LED2, !digitalRead(LED2));
      Serial.print("LED2 - ");
      Serial.println(digitalRead(LED2));
    }

    if (c == 3) {
      digitalWrite(LED3, !digitalRead(LED3));
      Serial.print("LED3 - ");
      Serial.println(digitalRead(LED3));
    }

    Serial.flush();
  }

Desafio

Desenvolva um projeto que seja possível medir a temperatura de um determinado ambiente, utilize por o exemplo o sensor de temperatura LM35, e envie o valor da variável para um tela de LCD para monitoramento. Se o valor da temperatura exceder um determinado valor, envie uma informação para acionar um cooler ou ventilador e resfriar o ambiente.

Considerações Finais

Espera-se que este tutorial possa ter ajudado no desenvolvimento de seu projeto. A equipe responsável agradece pela sua leitura e, em caso de dúvidas e sugestões, deixe seu comentário para que possamos sanar suas dúvidas! Obrigado!

Privacy Preference Center