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.

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.

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.

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.

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.

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.

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