Manufaturação industrial
Internet das coisas industrial | Materiais industriais | Manutenção e reparo de equipamentos | Programação industrial |
home  MfgRobots >> Manufaturação industrial >  >> Manufacturing Technology >> Processo de manufatura

Construa uma Rede Mesh Wireless Robusta com Arduino e Módulos NRF24L01

Neste tutorial, aprenderemos a construir uma rede wireless Arduino composta por múltiplos módulos transceptores NRF24L01. Você pode assistir ao vídeo a seguir ou ler o tutorial escrito abaixo.

Visão Geral

Como exemplo, criei uma rede de 5 nós onde cada um pode se comunicar com qualquer outro nó da rede, funcionando simultaneamente como transmissores e receptores. Este exemplo está configurado de forma a explicar como criar uma rede muito maior — precisamente, podemos ter um total de 3125 módulos se comunicando entre si em um único canal RF. Vamos ver como funciona.

Construa uma Rede Mesh Wireless Robusta com Arduino e Módulos NRF24L01

Em tutoriais anteriores, já aprendemos a fazer comunicação wireless entre duas placas Arduino usando os módulos NRF24L01 e a biblioteca RF24. Agora, além desta biblioteca, usaremos a biblioteca RF24Network, que permite de forma fácil construir uma rede wireless Arduino com várias placas se comunicando entre si. Veja como funciona a topologia da rede.

Comunicação entre Múltiplos Módulos NRF24L01

Um único módulo NRF24L01 pode ouvir ativamente até 6 outros módulos ao mesmo tempo.

Construa uma Rede Mesh Wireless Robusta com Arduino e Módulos NRF24L01

Esta capacidade é utilizada pela biblioteca RF24Network para gerar uma rede organizada em topologia de árvore, onde um nó é a base (master) e todos os outros nós são filhos desse nó ou de outro. Cada nó pode ter até 5 filhos, e isso pode ir até 5 níveis de profundidade, o que significa que podemos criar uma rede de até 3125 nós no total. Cada nó deve ser definido com um endereço de 15 bits, que descreve precisamente a posição do nó dentro da árvore.

Construa uma Rede Mesh Wireless Robusta com Arduino e Módulos NRF24L01

Podemos definir os endereços dos nós em formato octal. O endereço do mestre (base) é 00, os filhos da base têm endereços 01 a 05, os filhos do nó 01 têm endereços 011 a 051, e assim por diante.

Note que se o nó 011 quiser falar com o nó 02, a comunicação terá que passar pelo nó 01 e pelo nó base 00, então esses dois nós devem estar ativos o tempo todo para que a comunicação seja bem-sucedida.

Construa uma Rede Mesh Wireless Robusta com Arduino e Módulos NRF24L01

Controle Wireless de Servomotor com a Biblioteca RF24Network

Antes de explicar o exemplo principal deste tutorial, para melhor entender como a biblioteca funciona, vamos fazer um exemplo mais simples de duas placas Arduino se comunicando. Aqui está o diagrama de circuito para este exemplo.

Construa uma Rede Mesh Wireless Robusta com Arduino e Módulos NRF24L01

Você pode obter os componentes necessários para este tutorial nos links abaixo:

  • Módulo Transceptor NRF24L01
  • Servomotor
  • Potenciômetro
  • Arduino Nano

Usando o potenciômetro no primeiro Arduino, controlaremos o servomotor no segundo Arduino. Vamos analisar os códigos-fonte agora.

Código do lado do potenciômetro (Nó 00)

/* Arduino Wireless Network - Multiple NRF24L01 Tutorial
== Example 01 - Servo Control / Node 00 - Potentiometer
== by Dejan, www.HowToMechatronics.com
Libraries: nRF24/RF24, https://github.com/nRF24/RF24
nRF24/RF24Network, https://github.com/nRF24/RF24Network */
#include <RF24.h>
#include <RF24Network.h>
#include <SPI.h>

RF24 radio(10, 9); // nRF24L01 (CE,CSN)
RF24Network network(radio); // Inclui o rádio na rede

const uint16_t this_node = 00; // Endereço deste nó em Octal (04, 031, etc)
const uint16_t node01 = 01;

void setup() {
  SPI.begin();
  radio.begin();
  network.begin(90, this_node); // (canal, endereço do nó)
}

void loop() {
  network.update();
  unsigned long potValue = analogRead(A0); // Lê o valor do potenciômetro
  unsigned long angleValue = map(potValue, 0, 1023, 0, 180); // Converte para 0-180
  RF24NetworkHeader header(node01); // (Endereço para onde os dados vão)
  bool ok = network.write(header, &angleValue, sizeof(angleValue)); // Envia os dados
}

Primeiro, precisamos incluir as bibliotecas RF24 e RF24Network, bem como a biblioteca SPI. Em seguida, criamos o objeto RF24 e o incluímos no objeto RF24Network. Aqui definimos os endereços dos nós em formato octal: 00 para este nó e 01 para o outro nó no lado do servo.

Na seção setup(), inicializamos a rede definindo o canal e o endereço deste nó.

No loop(), precisamos chamar constantemente a função update(), através da qual toda a ação na rede acontece. Então lemos o valor do potenciômetro e o convertemos em um valor de 0 a 180, adequado para controle de servo. Criamos um cabeçalho de rede onde atribuímos o endereço do nó para onde os dados vão. No final, usando a função write(), enviamos os dados para o outro nó. O primeiro parâmetro contém as informações de endereço, o segundo aponta para quais dados serão enviados e o terceiro é o tamanho dos dados.

Código do lado do servo (Nó 01)

/* Arduino Wireless Network - Multiple NRF24L01 Tutorial
== Example 01 - Servo Control / Node 01 - Servo motor == */
#include <RF24.h>
#include <RF24Network.h>
#include <SPI.h>
#include <Servo.h>

RF24 radio(10, 9); // nRF24L01 (CE,CSN)
RF24Network network(radio); // Inclui o rádio na rede
const uint16_t this_node = 01; // Endereço do nosso nó em Octal
Servo myservo; // cria objeto servo para controlar um servo

void setup() {
  SPI.begin();
  radio.begin();
  network.begin(90, this_node); // (canal, endereço do nó)
  myservo.attach(3); // (pino do servo)
}

void loop() {
  network.update();
  while ( network.available() ) { // Há dados de entrada?
    RF24NetworkHeader header;
    unsigned long incomingData;
    network.read(header, &incomingData, sizeof(incomingData)); // Lê os dados de entrada
    myservo.write(incomingData); // move o servo para o ângulo específico
  }
}

Do outro lado, no servomotor, precisamos definir as bibliotecas e objetos da mesma forma explicada anteriormente. Aqui o endereço deste nó em formato octal é 01. Após definir o servomotor, na seção loop(), usando o loop while() e a função available(), verificamos constantemente se há dados de entrada. Se verdadeiro, criamos um cabeçalho de rede através do qual os dados serão aceitos e também uma variável onde os dados serão armazenados. Então, usando a função read(), lemos os dados e os armazenamos na variável incomingData. No final, usamos esses dados para mover o servomotor de acordo com o potenciômetro do outro nó.

Rede Wireless Arduino com Múltiplos Módulos NRF24L01

Após entender este exemplo, podemos passar para o exemplo principal deste tutorial e construir uma rede wireless de 5 Arduinos se comunicando entre si. Aqui está um diagrama de blocos do exemplo.

Construa uma Rede Mesh Wireless Robusta com Arduino e Módulos NRF24L01

Da base, usando um potenciômetro, controlaremos o servomotor no nó 01; com o segundo potenciômetro, controlaremos os LEDs no nó 022; usando o botão, controlaremos o LED no nó 012; e o LED aqui na base será controlado usando o potenciômetro no nó 02. Também, usando o sensor infravermelho no nó 012, controlaremos o LED no nó 01. Podemos notar que este exemplo explica como transmitir e receber dados ao mesmo tempo, bem como como se comunicar com nós de diferentes ramos. Vamos ver os códigos Arduino agora.

Relacionado: DIY Arduino RC Transmitter

Código Fonte da Base 00

/* Arduino Wireless Network - Multiple NRF24L01 Tutorial
== Base/ Master Node 00==
by Dejan, www.HowToMechatronics.com
Libraries: nRF24/RF24, https://github.com/nRF24/RF24
nRF24/RF24Network, https://github.com/nRF24/RF24Network */
#include <RF24Network.h>
#include <RF24.h>
#include <SPI.h>

#define button 2
#define led 3

RF24 radio(10, 9); // nRF24L01 (CE,CSN)
RF24Network network(radio); // Inclui o rádio na rede
const uint16_t this_node = 00; // Endereço deste nó em Octal
const uint16_t node01 = 01; // Endereço do outro nó em Octal
const uint16_t node012 = 012;
const uint16_t node022 = 022;

void setup() {
  SPI.begin();
  radio.begin();
  network.begin(90, this_node); // (canal, endereço do nó)
  radio.setDataRate(RF24_2MBPS);
  pinMode(button, INPUT_PULLUP);
  pinMode(led, OUTPUT);
}

void loop() {
  network.update();
  //===== Recebendo =====//
  while ( network.available() ) { // Há dados de entrada?
    RF24NetworkHeader header;
    unsigned long incomingData;
    network.read(header, &incomingData, sizeof(incomingData)); // Lê os dados de entrada
    analogWrite(led, incomingData); // Saída PWM para LED 01 (dimmer)
  }
  //===== Enviando =====//
  // Controle do Servo no Nó 01
  unsigned long potValue = analogRead(A0);
  unsigned long angleValue = map(potValue, 0, 1023, 0, 180); // Adequado para controle de servo
  RF24NetworkHeader header2(node01); // (Endereço para onde os dados vão)
  bool ok = network.write(header2, &angleValue, sizeof(angleValue)); // Envia os dados
  // Controle do LED no Nó 012
  unsigned long buttonState = digitalRead(button);
  RF24NetworkHeader header4(node012); // (Endereço para onde os dados vão)
  bool ok3 = network.write(header4, &buttonState, sizeof(buttonState)); // Envia os dados
  // Controle dos LEDs no Nó 022
  unsigned long pot2Value = analogRead(A1);
  RF24NetworkHeader header3(node022); // (Endereço para onde os dados vão)
  bool ok2 = network.write(header3, &pot2Value, sizeof(pot2Value)); // Envia os dados
}

Na base ou nó mestre, precisamos definir as bibliotecas e objetos como explicado anteriormente, e também definir todos os outros nós para os quais o mestre enviará dados. No loop(), começamos verificando constantemente se há dados de entrada. Se houver, lemos os dados, armazenamos na variável incomingData e usamos para controlar o brilho do LED. Estes dados vêm do potenciômetro do nó 02. Se olharmos seu código, veremos que o setup é praticamente o mesmo. O importante é atribuir o endereço correto para onde queremos enviar os dados. Neste caso, é o mestre 00. Após ler o valor do potenciômetro e convertê-lo em um valor PWM adequado de 0 a 255, enviamos esses dados para o mestre. Podemos notar aqui que usei a função millis() para enviar os dados em intervalos de 10 milissegundos.

Código Fonte do Nó 02

/* Arduino Wireless Network - Multiple NRF24L01 Tutorial
== Node 02 (Child of Master node 00) == */
#include <RF24Network.h>
#include <RF24.h>
#include <SPI.h>

RF24 radio(10, 9); // nRF24L01 (CE,CSN)
RF24Network network(radio); // Inclui o rádio na rede
const uint16_t this_node = 02; // Endereço do nosso nó em Octal
const uint16_t master00 = 00; // Endereço do outro nó em Octal
const unsigned long interval = 10; //ms - Com que frequência enviar dados
unsigned long last_sent; // Quando enviamos pela última vez?

void setup() {
  SPI.begin();
  radio.begin();
  network.begin(90, this_node); // (canal, endereço do nó)
  radio.setDataRate(RF24_2MBPS);
}

void loop() {
  network.update();
  //===== Enviando =====//
  unsigned long now = millis();
  if (now - last_sent >= interval) { // Se é hora de enviar dados, envie!
    last_sent = now;
    unsigned long potValue = analogRead(A0);
    unsigned long ledBrightness = map(potValue, 0, 1023, 0, 255);
    RF24NetworkHeader header(master00); // (Endereço para onde os dados vão)
    bool ok = network.write(header, &ledBrightness, sizeof(ledBrightness)); // Envia os dados
  }
}

Em seguida, a partir do mestre, enviamos os dados do potenciômetro para o nó 01 para controlar o servomotor.

Código Fonte do Nó 01

/* Arduino Wireless Network - Multiple NRF24L01 Tutorial
== Node 01 (Child of Master node 00) == */
#include <RF24Network.h>
#include <RF24.h>
#include <SPI.h>
#include <Servo.h>

#define led 2

RF24 radio(10, 9); // nRF24L01 (CE,CSN)
RF24Network network(radio); // Inclui o rádio na rede
const uint16_t this_node = 01; // Endereço do nosso nó em Octal
const uint16_t master00 = 00; // Endereço do outro nó em Octal
Servo myservo; // cria objeto servo para controlar um servo

void setup() {
  SPI.begin();
  radio.begin();
  network.begin(90, this_node); // (canal, endereço do nó)
  radio.setDataRate(RF24_2MBPS);
  myservo.attach(3); // (pino do servo)
  pinMode(led, OUTPUT);
}

void loop() {
  network.update();
  //===== Recebendo =====//
  while ( network.available() ) { // Há dados de entrada?
    RF24NetworkHeader header;
    unsigned long incomingData;
    network.read(header, &incomingData, sizeof(incomingData)); // Lê os dados de entrada
    if (header.from_node == 0) { // Se dados vêm do Nó 00 (mestre)
      myservo.write(incomingData); // move o servo para o ângulo específico
    }
    if (header.from_node == 10) { // Se dados vêm do Nó 012 (octal 012 = decimal 10)
      digitalWrite(led, !incomingData); // Liga ou desliga o LED 02
    }
  }
}

O nó 01 está recebendo dados de dois nós diferentes: um para controle do servo e outro para controle do LED, que vem do sensor infravermelho do nó 012.

Neste caso, usamos o atributo header.from_node para obter informações de qual nó os dados vêm. Se os dados de entrada são do mestre, usamos para controlar o servo; se são do nó 012, usamos para controlar o LED.

Código Fonte do Nó 012

/* Arduino Wireless Network - Multiple NRF24L01 Tutorial
== Node 012 (child of Node 01)== */
#include <RF24Network.h>
#include <RF24.h>
#include <SPI.h>

#define led 2
#define IR 3

RF24 radio(10, 9); // nRF24L01 (CE,CSN)
RF24Network network(radio); // Inclui o rádio na rede
const uint16_t this_node = 012; // Endereço do nosso nó em Octal
const uint16_t node01 = 01; // Endereço do outro nó em Octal

void setup() {
  SPI.begin();
  radio.begin();
  network.begin(90, this_node); // (canal, endereço do nó)
  radio.setDataRate(RF24_2MBPS);
  pinMode(led, OUTPUT);
  pinMode(IR, INPUT);
}

void loop() {
  network.update();
  //===== Recebendo =====//
  while ( network.available() ) { // Há dados de entrada?
    RF24NetworkHeader header;
    unsigned long buttonState;
    network.read(header, &buttonState, sizeof(buttonState)); // Lê os dados de entrada
    digitalWrite(led, !buttonState); // Liga ou desliga o LED
  }
  //===== Enviando =====//
  unsigned long irV = digitalRead(IR); // Lê sensor IR
  RF24NetworkHeader header8(node01);
  bool ok = network.write(header8, &irV, sizeof(irV)); // Envia os dados
}

No nó 012, temos tanto transmissão quanto recepção. O sensor infravermelho controla o LED mencionado anteriormente no nó 01, e o LED aqui é controlado pelo botão no mestre.

Código Fonte do Nó 022

/* Arduino Wireless Network - Multiple NRF24L01 Tutorial
== Node 022 (child of Node 02)== */
#include <RF24Network.h>
#include <RF24.h>
#include <SPI.h>

#define led1 2
#define led2 3
#define led3 4
#define led4 5

RF24 radio(10, 9); // nRF24L01 (CE,CSN)
RF24Network network(radio); // Inclui o rádio na rede
const uint16_t this_node = 022; // Endereço do nosso nó em Octal
const uint16_t master00 = 00; // Endereço do outro nó em Octal

void setup() {
  SPI.begin();
  radio.begin();
  network.begin(90, this_node); // (canal, endereço do nó)
  radio.setDataRate(RF24_2MBPS);
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(led3, OUTPUT);
  pinMode(led4, OUTPUT);
}

void loop() {
  network.update();
  //===== Recebendo =====//
  while ( network.available() ) { // Há dados de entrada?
    RF24NetworkHeader header;
    unsigned long potValue;
    network.read(header, &potValue, sizeof(potValue)); // Lê os dados de entrada
    // Acende os LEDs dependendo do valor de entrada do potenciômetro
    if (potValue > 240) { digitalWrite(led1, HIGH); } else { digitalWrite(led1, LOW); }
    if (potValue > 480) { digitalWrite(led2, HIGH); } else { digitalWrite(led2, LOW); }
    if (potValue > 720) { digitalWrite(led3, HIGH); } else { digitalWrite(led3, LOW); }
    if (potValue > 960) { digitalWrite(led4, HIGH); } else { digitalWrite(led4, LOW); }
  }
}

Finalmente, os LEDs no nó 022 são controlados usando os dados vindos do outro potenciômetro no mestre.

Resumindo, se tudo estiver conectado corretamente e todos os nós estiverem ativos o tempo todo, nosso trabalho se resume a endereçar precisamente os nós e todo o trabalho pesado por trás é realizado pela incrível biblioteca RF24Network.

Espero que você tenha gostado deste projeto Arduino e aprendido algo novo. Sinta-se à vontade para fazer qualquer pergunta na seção de comentários abaixo.


Processo de manufatura

  1. Construa uma Rede de Sensores Sem Fio Acessível para Sua Casa
  2. Construa um Reconhecedor de Dígitos no Raspberry Pi com TensorFlow e OpenCV
  3. Transferência de Dados Magnética Sem Fio com Arduino e Sensor 3D Infineon
  4. Sensor K30 CO₂: Monitoramento de Qualidade do Ar Interno em Tempo Real
  5. Facilitando Comunicação Surdo-Cego com 1Sheeld e Arduino
  6. Mealheiro Inteligente: Controlar Aceitador de Moedas com Arduino Nano
  7. Controlar um LED via Bluetooth com Arduino – Guia DIY Simples
  8. Integrando Sensor de Impressão Digital Capacitivo DFRobot com Arduino ou ESP8266
  9. Adaptadores USB-BLE MIDI Sem Fio – Conectividade Perfeita para Músicos
  10. Projeto HMI Interativo com Nextion, Arduino Mega e Sensores