Red inalámbrica Arduino con múltiples módulos NRF24L01
En este tutorial aprenderemos a construir una red inalámbrica Arduino, compuesta por múltiples módulos transceptores NR24L01. Puede ver el siguiente video o leer el tutorial escrito a continuación.
Como ejemplo hice una red de 5 nodos y cada uno de ellos puede comunicarse con cualquier nodo de la red y al mismo tiempo pueden funcionar como transmisores y receptores. En realidad, este ejemplo está configurado de una manera que explica cómo hacer una red mucho más grande o, para ser precisos, podemos tener un total de 3125 módulos comunicándose entre sí en un solo canal de RF. Así que echemos un vistazo a cómo funciona.
En mis tutoriales anteriores ya aprendimos cómo hacer una comunicación inalámbrica entre dos placas Arduino utilizando los módulos NRF24L01 y la biblioteca RF24. Ahora, además de esta biblioteca, usaremos la biblioteca RF24Network, que permite de una manera fácil construir una red inalámbrica Arduino con muchas placas que se comunican entre sí. Así es como funciona la topología de la red.
Un solo módulo NRF24L01 puede escuchar activamente hasta otros 6 módulos al mismo tiempo.
La biblioteca RF24Network utiliza esta capacidad para generar una red dispuesta en una topología de árbol, donde un nodo es la base y todos los demás nodos son hijos de ese nodo o de otro. Cada nodo puede tener hasta 5 hijos, y esto puede tener 5 niveles de profundidad, lo que significa que podemos crear una red de 3125 nodos en total. Cada nodo debe definirse con una dirección de 15 bits, que describe con precisión la posición del nodo dentro del árbol.
De hecho, podemos definir las direcciones de los nodos en formato octal. Entonces, la dirección del maestro o la base es 00, las direcciones de los hijos de la base son de 01 a 05, las direcciones de los hijos de 01 nodos son de 011 a 051 y así sucesivamente.
Tenga en cuenta que si el nodo 011 quiere hablar con el nodo 02, la comunicación deberá pasar por el nodo 01 y el nodo base 00, por lo que estos dos nodos deben estar activos todo el tiempo para que la comunicación sea exitosa.
Antes de explicar el ejemplo principal de este tutorial, para comprender mejor cómo funciona la biblioteca, hagamos un ejemplo más simple de dos placas Arduino que se comunican entre sí. Aquí está el diagrama del circuito para este ejemplo.
Puede obtener los componentes necesarios para este tutorial de Arduino desde los siguientes enlaces:
Entonces, usando el potenciómetro en el primer Arduino, controlaremos el servomotor en el segundo Arduino. Echemos un vistazo a los códigos fuente ahora.
Aquí está el código en el lado del potenciómetro:
Primero, debemos incluir las bibliotecas RF24 y RF24Network, así como la biblioteca SPI. Luego, debemos crear el objeto RF24 e incluirlo en el objeto RF24Network. Aquí necesitamos definir las direcciones de los nodos en formato octal, o 00 para este nodo y 01 para el otro nodo en el lado del servo.
En la sección de configuración necesitamos inicializar la red, configurando el canal y la dirección de este nodo.
En la sección de bucle necesitamos llamar constantemente a la función update() a través de la cual ocurre toda la acción en la red. Luego leemos el valor del potenciómetro y lo convertimos en un valor de 0 a 180 que sea adecuado para el control del servo. Luego creamos un encabezado de red donde asignamos la dirección del nodo donde van los datos. Al final, usando la función write() enviamos los datos al otro nodo. Así que aquí el primer parámetro contiene la información de las direcciones, el segundo parámetro indica qué datos se enviarán y el tercer parámetro es el tamaño de los datos.
Aquí está el código en el lado del servo:
Por otro lado, en el servomotor, necesitamos definir las bibliotecas y los objetos de la misma manera que se explicó anteriormente. Aquí, la dirección de este nodo en formato octal es 01. Después de definir el servomotor, en la sección de bucle, usando el bucle while() y la función available() comprobamos constantemente si hay datos entrantes. Si es verdadero, creamos un encabezado de red a través del cual se aceptarán los datos y también una variable donde se almacenarán los datos. Luego, usando la función read(), leemos los datos y los almacenamos en la variable incomingData. Al final, usamos estos datos para mover el servomotor de acuerdo con el potenciómetro del otro nodo.
Después de comprender este ejemplo, podemos continuar con el ejemplo principal de este tutorial y construir una red inalámbrica de 5 Arduinos comunicándose entre sí. Aquí hay un diagrama de bloques del ejemplo.
Entonces desde la base, usando un potenciómetro controlaremos el servomotor en el nodo 01, con el segundo potenciómetro controlaremos los LED en el nodo 022, usando el botón controlaremos el LED en el nodo 012, y el LED aquí en la base será controlada usando el potenciómetro en el nodo 02. También usando el sensor infrarrojo en el nodo 012 controlaremos el LED en el nodo 01. Entonces podemos notar que este ejemplo explica cómo transmitir y recibir datos al mismo tiempo, así como también cómo comunicarse con nodos de diferentes ramas. Echemos un vistazo a los códigos de Arduino ahora.
Relacionado: Transmisor DIY Arduino RC
Entonces, en el nodo base o maestro, debemos definir las bibliotecas y los objetos como se explicó anteriormente, y también definir todos los demás nodos a los que el maestro enviará datos. En la sección de bucle, comenzamos comprobando constantemente si hay datos entrantes. Si es así, leemos los datos, los almacenamos en la variable incomingData y los usamos para controlar el brillo del LED. Estos datos en realidad provienen del potenciómetro del nodo 02. Si echamos un vistazo a su código, podemos notar que la configuración es prácticamente la misma. Lo importante es asignar la dirección correcta a donde queremos enviar los datos. En este caso, ese es el maestro 00. Entonces, después de leer el valor del potenciómetro y convertirlo en un valor PWM adecuado de 0 a 255, enviamos estos datos al maestro. Podemos notar aquí que utilicé la función millis() para enviar los datos a intervalos de 10 milisegundos.
A continuación, desde el maestro, enviamos los datos del potenciómetro al nodo 01 para controlar el servomotor.
El nodo 01 en realidad está recibiendo datos de dos nodos diferentes, uno para el control del servo y otro para el control del LED que proviene del sensor infrarrojo del nodo 012.
En tal caso, usamos el atributo header.from_node para obtener información de qué nodo provienen los datos. En caso de que los datos entrantes provengan del maestro, los usamos para controlar el servo, y en caso de que los datos entrantes provengan del nodo 012, los usamos para controlar el LED.
En el nodo 012 tenemos tanto la transmisión como la recepción. El sensor de infrarrojos controla el LED mencionado anteriormente en el nodo 01 y el LED aquí se controla desde el botón en el maestro.
Finalmente, los LED en el nodo 022 se controlan utilizando los datos provenientes del otro potenciómetro en el maestro.
Entonces, para resumir, si todo está conectado correctamente y todos los nodos están activos todo el tiempo, nuestro trabajo se reduce a abordar con precisión los nodos y todo el trabajo pesado detrás lo lleva a cabo la increíble biblioteca RF24Network.
Eso sería todo, espero que hayas disfrutado este proyecto Arduino y hayas aprendido algo nuevo. No dude en hacer cualquier pregunta en la sección de comentarios a continuación.Resumen
Comunicación de múltiples módulos NRF24L01
Arduino Wireless Servomotor Control usando RF24Network Library
/*
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); // Include the radio in the network
const uint16_t this_node = 00; // Address of this node in Octal format ( 04,031, etc)
const uint16_t node01 = 01;
void setup() {
SPI.begin();
radio.begin();
network.begin(90, this_node); //(channel, node address)
}
void loop() {
network.update();
unsigned long potValue = analogRead(A0); // Read the potentiometer value
unsigned long angleValue = map(potValue, 0, 1023, 0, 180); // Convert the value to 0-180
RF24NetworkHeader header(node01); // (Address where the data is going)
bool ok = network.write(header, &angleValue, sizeof(angleValue)); // Send the data
}
Code language: Arduino (arduino)/*
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); // Include the radio in the network
const uint16_t this_node = 01; // Address of our node in Octal format ( 04,031, etc)
Servo myservo; // create servo object to control a servo
void setup() {
SPI.begin();
radio.begin();
network.begin(90, this_node); //(channel, node address)
myservo.attach(3); // (servo pin)
}
void loop() {
network.update();
while ( network.available() ) { // Is there any incoming data?
RF24NetworkHeader header;
unsigned long incomingData;
network.read(header, &incomingData, sizeof(incomingData)); // Read the incoming data
myservo.write(incomingData); // tell servo to go to a particular angle
}
}
Code language: Arduino (arduino)Red inalámbrica Arduino con múltiples módulos NRF24L01
Código fuente 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); // Include the radio in the network
const uint16_t this_node = 00; // Address of this node in Octal format ( 04,031, etc)
const uint16_t node01 = 01; // Address of the other node in Octal format
const uint16_t node012 = 012;
const uint16_t node022 = 022;
void setup() {
SPI.begin();
radio.begin();
network.begin(90, this_node); //(channel, node address)
radio.setDataRate(RF24_2MBPS);
pinMode(button, INPUT_PULLUP);
pinMode(led, OUTPUT);
}
void loop() {
network.update();
//===== Receiving =====//
while ( network.available() ) { // Is there any incoming data?
RF24NetworkHeader header;
unsigned long incomingData;
network.read(header, &incomingData, sizeof(incomingData)); // Read the incoming data
analogWrite(led, incomingData); // PWM output to LED 01 (dimming)
}
//===== Sending =====//
// Servo control at Node 01
unsigned long potValue = analogRead(A0);
unsigned long angleValue = map(potValue, 0, 1023, 0, 180); // Suitable for servo control
RF24NetworkHeader header2(node01); // (Address where the data is going)
bool ok = network.write(header2, &angleValue, sizeof(angleValue)); // Send the data
// LED Control at Node 012
unsigned long buttonState = digitalRead(button);
RF24NetworkHeader header4(node012); // (Address where the data is going)
bool ok3 = network.write(header4, &buttonState, sizeof(buttonState)); // Send the data
// LEDs control at Node 022
unsigned long pot2Value = analogRead(A1);
RF24NetworkHeader header3(node022); // (Address where the data is going)
bool ok2 = network.write(header3, &pot2Value, sizeof(pot2Value)); // Send the data
}
Code language: Arduino (arduino)Código fuente del nodo 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); // Include the radio in the network
const uint16_t this_node = 02; // Address of our node in Octal format ( 04,031, etc)
const uint16_t master00 = 00; // Address of the other node in Octal format
const unsigned long interval = 10; //ms // How often to send data to the other unit
unsigned long last_sent; // When did we last send?
void setup() {
SPI.begin();
radio.begin();
network.begin(90, this_node); //(channel, node address)
radio.setDataRate(RF24_2MBPS);
}
void loop() {
network.update();
//===== Sending =====//
unsigned long now = millis();
if (now - last_sent >= interval) { // If it's time to send a data, send it!
last_sent = now;
unsigned long potValue = analogRead(A0);
unsigned long ledBrightness = map(potValue, 0, 1023, 0, 255);
RF24NetworkHeader header(master00); // (Address where the data is going)
bool ok = network.write(header, &ledBrightness, sizeof(ledBrightness)); // Send the data
}
}
Code language: Arduino (arduino)Código fuente del nodo 01
/*
Arduino Wireless Network - Multiple NRF24L01 Tutorial
== Node 02 (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); // Include the radio in the network
const uint16_t this_node = 01; // Address of our node in Octal format ( 04,031, etc)
const uint16_t master00 = 00; // Address of the other node in Octal format
Servo myservo; // create servo object to control a servo
void setup() {
SPI.begin();
radio.begin();
network.begin(90, this_node); //(channel, node address)
radio.setDataRate(RF24_2MBPS);
myservo.attach(3); // (servo pin)
pinMode(led, OUTPUT);
}
void loop() {
network.update();
//===== Receiving =====//
while ( network.available() ) { // Is there any incoming data?
RF24NetworkHeader header;
unsigned long incomingData;
network.read(header, &incomingData, sizeof(incomingData)); // Read the incoming data
if (header.from_node == 0) { // If data comes from Node 02
myservo.write(incomingData); // tell servo to go to a particular angle
}
if (header.from_node == 10) { // If data comes from Node 012
digitalWrite(led, !incomingData); // Turn on or off the LED 02
}
}
}
Code language: Arduino (arduino)Código fuente del nodo 012
/*
Arduino Wireless Network - Multiple NRF24L01 Tutorial
== Node 012 (child of Node 02)==
*/
#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); // Include the radio in the network
const uint16_t this_node = 012; // Address of our node in Octal format ( 04,031, etc)
const uint16_t node01 = 01; // Address of the other node in Octal format
void setup() {
SPI.begin();
radio.begin();
network.begin(90, this_node); //(channel, node address)
radio.setDataRate(RF24_2MBPS);
pinMode(led, OUTPUT);
pinMode(IR, INPUT);
}
void loop() {
network.update();
//===== Receiving =====//
while ( network.available() ) { // Is there any incoming data?
RF24NetworkHeader header;
unsigned long buttonState;
network.read(header, &buttonState, sizeof(buttonState)); // Read the incoming data
digitalWrite(led, !buttonState); // Turn on or off the LED
}
//===== Sending =====//
unsigned long irV = digitalRead(IR); // Read IR sensor
RF24NetworkHeader header8(node01);
bool ok = network.write(header8, &irV, sizeof(irV)); // Send the data
}
Code language: Arduino (arduino)Código fuente del nodo 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); // Include the radio in the network
const uint16_t this_node = 022; // Address of our node in Octal format ( 04,031, etc)
const uint16_t master00 = 00; // Address of the other node in Octal format
void setup() {
SPI.begin();
radio.begin();
network.begin(90, this_node); //(channel, node address)
radio.setDataRate(RF24_2MBPS);
pinMode(led1, OUTPUT);
pinMode(led2, OUTPUT);
pinMode(led3, OUTPUT);
pinMode(led4, OUTPUT);
}
void loop() {
network.update();
//===== Receiving =====//
while ( network.available() ) { // Is there any incoming data?
RF24NetworkHeader header;
unsigned long potValue;
network.read(header, &potValue, sizeof(potValue)); // Read the incoming data
// Turn on the LEDs as depending on the incoming value from the potentiometer
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);
}
}
}
Code language: Arduino (arduino)
Proceso de manufactura
- Creación de una red de sensores inalámbricos en su hogar
- Reconocimiento de dígitos AI con PiCamera
- Transferencia de datos magnética inalámbrica
- Monitoreo de CO2 con sensor K30
- Comunicación para personas sordociegas con 1Sheeld / Arduino
- Controlar el aceptador de monedas con Arduino
- ¡Arduino con Bluetooth para controlar un LED!
- Sensor capacitivo de huellas dactilares con Arduino o ESP8266
- Adaptadores MIDI inalámbricos USB-BLE
- Jugando con Nextion Display
- Brazo robótico controlado por Nunchuk (con Arduino)