En este post, aprenderemos a configurar y utilizar módulos NRF24L01 para la comunicación bidireccional inalámbrica entre dos Arduinos. A través del uso del protocolo SPI, conectaremos los módulos NRF24L01 a cada Arduino y utilizaremos un pulsador y un LED para enviar y recibir señales entre los dispositivos.
Para este proyecto, utilizaremos dos Arduinos y módulos NRF24L01 para comunicación bidireccional inalámbrica por radiofrecuencia. Los módulos NRF24L01 tienen la capacidad de ser configurados como emisores o receptores, o para realizar ambas funciones (transceptores). Estos módulos se conectan a los Arduinos a través del protocolo SPI.
Para distinguir entre los dos Arduinos en nuestro código, los llamaremos «Arduino A» y «Arduino B». Además, cada Arduino tendrá un pulsador conectado al pin digital 7 y un LED al pin digital 6.
A la hora de programar los dos Arduino, al ser una comunicación bidireccional, tenemos que declarar esta vez dos canales (const uint64_t canal[2] = {0xF0F0F0F0E1LL,0xF0F0F0F0D2LL};). Por el canal “0” que es por el que escribe el Arduino “A” tiene que leer el Arduino “B”, y en contraposición, por el canal “1” que es por donde escribe el Arduino “B” tiene que leer el Arduino “A” como se muestra a continuación.
Es importante dar tiempo a los módulos NRF24L01 para que puedan recibir y transmitir información, para lo cual se utiliza un pequeño retraso (delay) en el código. Los programas para cada Arduino escucharán a través de un canal específico para ver si están recibiendo información mediante radiofrecuencia (RF) del otro Arduino, y en función del valor recibido encenderán o apagarán el LED conectado.
Luego de verificar esto, dejarán de escuchar por el canal y enviarán el valor del pulsador al otro Arduino. Este proceso se repite continuamente en la función «loop». Si deseas obtener más información sobre el funcionamiento de los programas, recomendamos leer los comentarios incluidos en el código.
Lista de Materiales
- 2 Arduinos UNO Rev.3
- Cable USB tipo A-B
- 2 módulos NRF24L01
- 2 Condensadores electrolíticos de 10µF y más de 5V
- 2 Pulsadores
- 2 Resistencias de 10KΩ
- 2 LED 5mm (de cualquier color)
- 2 Resistencias de 220Ω
- Fuente de alimentación de 12VDC/3000mA (DC12300)
- Protoboard
- Cables de conexión
Código del programa
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 |
/* TITULO: Comunicación bidireccional entre Arduinos con módulos NRF24L01 >> Programa Arduino "A" AUTOR: MARIANO DEL CAMPO GARCÍA (@2016) --> INGENIERO TÉCNICO INDUSTRIAL ESPECIALIDAD ELECTRÓNICA - FACEBOOK: https://www.facebook.com/mariano.delcampogarcia - TWITTER: https://twitter.com/MarianoCampoGa - CORREO: [email protected] DESCRIPCIÓN DEL PROGRAMA Con este programa controlamos el encendido y apagado de un LED con un solo pulsador, mediante una conexión por radiofrecuencia (RF) bidireccional entre dos Arduinos, a través de módulos NRF24L01. Vamos a recibir el valor de la variable estado_pulsador_B[0] vía RF desde el Arduino "B", cada vez que se presione el pulsador conectado a él, si esta variable tiene el valor de "1" se enciende el LED conectado a este Arduino ("A") y si vale "0" el LED se apaga. En el supuesto de que nunca recibamos ningún valor de la variable estado_pulsador_B[0], el LED permanecerá apagado (no se ha presionado todavía el pulsador del Arduino "B"). Por otro lado, cada vez que presionamos el pulsador conectado a este Arduino, se envía mediante RF el valor de la variable estado_pulsador_A[0], si es la primera vez que lo presionamos se envía un "1" y si es la segunda vez un "0", repitiéndose el proceso contínuamente, para que se encienda o apage el LED conectado al Arduino "B", que es el que obtiene, a través de RF, el valor de la variable estado_pulsador_A[0]. En el supuesto de que nunca presionemos el pulsador, no se envía ningún valor mediante RF y como consecuencia el LED permanecerá apagado. ESQUEMA DE CONEXION +-----+ +----[PWR]-------------------| USB |--+ | +-----+ | | GND/RST2 [ ][ ] | | MOSI2/SCK2 [ ][ ] A5/SCL[ ] | | 5V/MISO2 [ ][ ] A4/SDA[ ] | | AREF[ ] | | GND[ ] | | [ ]N/C SCK/13[ ] | Pin "SCK" del módulo NRF24L01 | [ ]IOREF MISO/12[ ] | Pin "MISO" del módulo NRF24L01 | [ ]RST MOSI/11[ ]~| Pin "MOSI" del módulo NRF24L01 | [ ]3V3 +---+ 10[ ]~| Pin "CSN" del módulo NRF24L01 | [ ]5v -| A |- 9[ ]~| Pin "CE" del módulo NRF24L01 | [ ]GND -| R |- 8[ ] | | [ ]GND -| D |- | | [ ]Vin -| U |- 7[ ] | PA | -| I |- 6[ ]~| LED(+) | [ ]A0 -| N |- 5[ ]~| | [ ]A1 -| O |- 4[ ] | | [ ]A2 +---+ INT1/3[ ]~| | [ ]A3 INT0/2[ ] | | [ ]A4/SDA RST SCK MISO TX>1[ ] | | [ ]A5/SCL [ ] [ ] [ ] RX<0[ ] | | [ ] [ ] [ ] | | UNO_R3 GND MOSI 5V ____________/ \_______________________/ NOTAS: - Alimentación del módulo NRF24L01: - GND del módulo NRF24L01--> GND de Arduino. - VCC del módulo NRF24L01--> +3.3V de Arduino. - El pin "IRQ" del modulo NRF24L01 no se conecta a nuestro Arduino. - Los pulsadores suelen tener dos pines, que vamos a denominar PA y PB (si es de 4 sólo usamos 2 de ellos) - Conexión PULL-DOWN del pulsador. - PB conectado a VCC. - PA conectado a GND a través de una R=10K ohms. - Cátodo(-) del LED (pata más corta) a GND a través de una R=220 ohms. */ // Incluimos las librerías necesarias #include <SPI.h> // Librería para la comunicación SPI // Librerías para el funcionamiento del módulo NRF24L01 #include <nRF24L01.h> #include <RF24.h> // Declaramos los pines de control del módulo NRF24L01 #define CE 9 #define CSN 10 // Se crea el objeto tipo RF24 RF24 radio(CE, CSN); // Se declaran los canales (64 bits en hexadecimal) para transmisión RF const uint64_t canal[2] = {0xF0F0F0F0E1LL,0xF0F0F0F0D2LL}; // Variable que enviamos mediante RF (de tipo string siempre) unsigned int estado_pulsador_A[1]; // Variable que recibimos mediante RF (de tipo string siempre) unsigned int estado_pulsador_B[1]; int pulsador = 7; // Pin digital 7 para el pulsador int LED = 6; // Pin digital 6 para el LED // Inicializamos las variables internas para el pulsador int encender = 0; int anterior = 0; int estado = 0; void setup() { pinMode(LED, OUTPUT); // Pin digital 6 como salida pinMode(pulsador, INPUT); // Pin digital 7 como entrada pinMode(CSN, OUTPUT); // Pin digital 10 como salida digitalWrite(LED, LOW); // Inicialmente el LED se apaga radio.begin(); // Inicialización de la comunicación RF // Establece el retardo y el número de reintentos tras fallo en la comunicación RF radio.setRetries(15,15); radio.openWritingPipe(canal[0]); // Abro el canal "0" para escribir radio.openReadingPipe(1,canal[1]); // Abro el canal "1" para leer } void loop() { // ************************ PARTE CORRESPONDIENTE A LA RECEPCIÓN A **************************** radio.startListening(); // Comienzo a escuchar por el canal "1" // Siempre que haya información disponible vía RF... while(radio.available()) { // Se recibe el valor de la variable estado_pulsador_B[0] a través de RF radio.read(estado_pulsador_B, sizeof(estado_pulsador_B)); // Si el valor de la variable estado_pulsador_B[0] es igual a "1" se enciende el LED if (estado_pulsador_B[0] == 1) { digitalWrite(LED, HIGH); } // Si el valor de la variable estado_pulsador_B[0] es igual a "0" se apaga el LED if (estado_pulsador_B[0] == 0) { digitalWrite(LED, LOW); } } delay(20); // Doy tiempo de lectura al receptor A radio.stopListening(); // Paro de escuchar por el canal "1" // ************************ PARTE CORRESPONDIENTE A LA EMISIÓN A **************************** estado = digitalRead(pulsador); // Guardamos el estado actual del pulsador if(estado && anterior == 0) // Comparamos el estado actual y el anterior del pulsador A { encender = 1 - encender; } anterior = estado; // Actualizamos el estado del pulsador A. if(encender) // Si el estado interno del pulsador A pasa de "LOW" a "HIGH". { estado_pulsador_A[0] = 1; // La variable vale 1 } else // Si el estado interno del pulsador A pasa de "HIGH" a "LOW". { estado_pulsador_A[0] = 0; // La variable vale 0 } // Se envía el valor de la variable estado_pulsador_A[0] a través de RF radio.write(estado_pulsador_A, sizeof(estado_pulsador_A)); delay(20); // Doy tiempo de escritura al emisor A } |
NRF24L01_Bidireccional_B
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 |
/* TITULO: Comunicación bidireccional entre Arduinos con módulos NRF24L01 >> Programa Arduino "B" AUTOR: MARIANO DEL CAMPO GARCÍA (@2016) --> INGENIERO TÉCNICO INDUSTRIAL ESPECIALIDAD ELECTRÓNICA - FACEBOOK: https://www.facebook.com/mariano.delcampogarcia - TWITTER: https://twitter.com/MarianoCampoGa - CORREO: [email protected] DESCRIPCIÓN DEL PROGRAMA Con este programa controlamos el encendido y apagado de un LED con un solo pulsador, mediante una conexión por radiofrecuencia (RF) bidireccional entre dos Arduinos, a través de módulos NRF24L01. Vamos a recibir el valor de la variable estado_pulsador_A[0] vía RF desde el Arduino "A", cada vez que se presione el pulsador conectado a él, si esta variable tiene el valor de "1" se enciende el LED conectado a este Arduino ("B") y si vale "0" el LED se apaga. En el supuesto de que nunca recibamos ningún valor de la variable estado_pulsador_A[0], el LED permanecerá apagado (no se ha presionado todavía el pulsador del Arduino "A"). Por otro lado, cada vez que presionamos el pulsador conectado a este Arduino, se envía mediante RF el valor de la variable estado_pulsador_B[0], si es la primera vez que lo presionamos se envía un "1" y si es la segunda vez un "0", repitiéndose el proceso contínuamente, para que se encienda o apage el LED conectado al Arduino "A", que es el que obtiene, a través de RF, el valor de la variable estado_pulsador_B[0]. En el supuesto de que nunca presionemos el pulsador, no se envía ningún valor mediante RF y como consecuencia el LED permanecerá apagado. ESQUEMA DE CONEXION +-----+ +----[PWR]-------------------| USB |--+ | +-----+ | | GND/RST2 [ ][ ] | | MOSI2/SCK2 [ ][ ] A5/SCL[ ] | | 5V/MISO2 [ ][ ] A4/SDA[ ] | | AREF[ ] | | GND[ ] | | [ ]N/C SCK/13[ ] | Pin "SCK" del módulo NRF24L01 | [ ]IOREF MISO/12[ ] | Pin "MISO" del módulo NRF24L01 | [ ]RST MOSI/11[ ]~| Pin "MOSI" del módulo NRF24L01 | [ ]3V3 +---+ 10[ ]~| Pin "CSN" del módulo NRF24L01 | [ ]5v -| A |- 9[ ]~| Pin "CE" del módulo NRF24L01 | [ ]GND -| R |- 8[ ] | | [ ]GND -| D |- | | [ ]Vin -| U |- 7[ ] | PA | -| I |- 6[ ]~| LED(+) | [ ]A0 -| N |- 5[ ]~| | [ ]A1 -| O |- 4[ ] | | [ ]A2 +---+ INT1/3[ ]~| | [ ]A3 INT0/2[ ] | | [ ]A4/SDA RST SCK MISO TX>1[ ] | | [ ]A5/SCL [ ] [ ] [ ] RX<0[ ] | | [ ] [ ] [ ] | | UNO_R3 GND MOSI 5V ____________/ \_______________________/ NOTAS: - Alimentación del módulo NRF24L01: - GND del módulo NRF24L01--> GND de Arduino. - VCC del módulo NRF24L01--> +3.3V de Arduino. - El pin "IRQ" del modulo NRF24L01 no se conecta a nuestro Arduino. - Los pulsadores suelen tener dos pines, que vamos a denominar PA y PB (si es de 4 sólo usamos 2 de ellos) - Conexión PULL-DOWN del pulsador. - PB conectado a VCC. - PA conectado a GND a través de una R=10K ohms. - Cátodo(-) del LED (pata más corta) a GND a través de una R=220 ohms. */ // Incluimos las librerías necesarias #include <SPI.h> // Librería para la comunicación SPI // Librerías para el funcionamiento del módulo NRF24L01 #include <nRF24L01.h> #include <RF24.h> // Declaramos los pines de control del módulo NRF24L01 #define CE 9 #define CSN 10 // Se crea el objeto tipo RF24 RF24 radio(CE, CSN); // Se declaran los canales (64 bits en hexadecimal) para transmisión RF const uint64_t canal[2] = {0xF0F0F0F0E1LL,0xF0F0F0F0D2LL}; // Variable que enviamos mediante RF (de tipo string siempre) unsigned int estado_pulsador_B[1]; // Variable que recibimos mediante RF (de tipo string siempre) unsigned int estado_pulsador_A[1]; int pulsador = 7; // Pin digital 7 para el pulsador int LED = 6; // Pin digital 6 para el LED // Inicializamos las variables internas para el pulsador int encender = 0; int anterior = 0; int estado = 0; void setup() { pinMode(LED, OUTPUT); // Pin digital 6 como salida pinMode(pulsador, INPUT); // Pin digital 7 como entrada pinMode(CSN, OUTPUT); // Pin digital 10 como salida digitalWrite(LED, LOW); // Inicialmente el LED se apaga radio.begin(); // Inicialización de la comunicación RF // Establece el retardo y el número de reintentos tras fallo en la comunicación RF radio.setRetries(15,15); radio.openWritingPipe(canal[1]); // Abro el canal "1" para escribir radio.openReadingPipe(1,canal[0]); // Abro el canal "0" para leer } void loop() { // ************************ PARTE CORRESPONDIENTE A LA RECEPCIÓN B **************************** radio.startListening(); // Comienzo a escuchar por el canal "0" // Siempre que haya información disponible vía RF... while(radio.available()) { // Se recibe el valor de la variable estado_pulsador_A[0] a través de RF radio.read(estado_pulsador_A, sizeof(estado_pulsador_A)); // Si el valor de la variable estado_pulsador_A[0] es igual a "1" se enciende el LED if (estado_pulsador_A[0] == 1) { digitalWrite(LED, HIGH); } // Si el valor de la variable estado_pulsador_A[0] es igual a "0" se apaga el LED if (estado_pulsador_A[0] == 0) { digitalWrite(LED, LOW); } } delay(20); // Doy tiempo de lectura al receptor B radio.stopListening(); // Paro de escuchar por el canal "0" // ************************ PARTE CORRESPONDIENTE A LA EMISIÓN B **************************** estado = digitalRead(pulsador); // Guardamos el estado actual del pulsador B if(estado && anterior == 0) // Comparamos el estado actual y el anterior del pulsador B { encender = 1 - encender; } anterior = estado; // Actualizamos el estado del pulsador B. if(encender) // Si el estado interno del pulsador B pasa de "LOW" a "HIGH". { estado_pulsador_B[0] = 1; // La variable vale 1 } else // Si el estado interno del pulsador B pasa de "HIGH" a "LOW". { estado_pulsador_B[0] = 0; // La variable vale 0 } // Se envía el valor de la variable estado_pulsador_B[0] a través de RF radio.write(estado_pulsador_B, sizeof(estado_pulsador_B)); delay(20); // Doy tiempo de escritura al emisor B } |
Video
En este post, hemos aprendido a utilizar módulos NRF24L01 para la comunicación bidireccional inalámbrica entre dos Arduinos. Hemos visto cómo conectarlos a cada Arduino a través del protocolo SPI y cómo utilizar un pulsador y un LED para enviar y recibir señales.
También hemos visto cómo programar los Arduinos para que escuchen y transmitan a través de canales específicos y cómo utilizar un retraso (delay) para dar tiempo a los módulos para que puedan recibir y transmitir información.
Gracias por leer este post. Espero que hayas aprendido algo nuevo sobre la configuración y uso de módulos NRF24L01 para la comunicación bidireccional inalámbrica entre Arduinos. Si tienes alguna pregunta o comentario, no dudes en dejármelo a continuación.