Los módulos de radio frecuencia NRF24L01 son una opción bastante económica y compacta para conectar dos microcontroladores por medio de un enlace de radiofrecuencia.
El NRF24L01 es un chip bastante completo para implementar comunicaciones inalámbricas, ya que se encarga de varios aspectos de la transmisión de forma completamente automática. Por ejemplo: dispone de verificación de la integridad de datos mediante CRC, retransmisión automática y direccionamiento de los nodos inalámbricos.
En este artículo no pretendemos aburrirte con detalles técnicos y enseñarte todos los modos de funcionamiento del radio. Lo que se busca es que puedas comenzar a realizar tus propias transmisiones de la manera más rápida posible.
En esta entrada presentamos un ejemplo completo para comunicar dos arduinos utilizando los radios NRF24L01+ de Nordic Semiconductor. Para realizar este ejemplo utilizaremos 2 radios y dos tarjetas Arduino.
Materiales necesarios para las prácticas
Para completar los ejercicios propuestos en esta página recomendamos adquirir los siguiente materiales:
- 2 Tarjetas Arduino Uno R3 o similares.
- 2 módulos de radiofrecuencia.
- Cables tipo dupont macho – hembra.
- Pulsadores o push button de acuerdo a nuestro gusto.
Pinout del módulo NRF24L01+
La siguiente imagen nos muestra como se distribuyen las señales del módulo, pueden existir variantes distintas de este modulo, pero la que se muestra abajo es muy popular.
Conexión del módulo NRF24L01 con el Arduino Uno R3
Para la conexión del NRF24 L01+ se requieren 5 señales básicas, además de la alimentación, la conexión de IRQ es opcional:
- VCC – Alimentación de 3.3 volts.
- GND – Tierra o común.
- MOSI – Señal del bus SPI, lleva datos del maestro al esclavo.
- MISO – Señal del bus SPI, lleva datos del esclavo al maestro.
- SCK – Señal de reloj del bus SPI.
- CE – Señal de habilitación del chip.
- CSN – Señal de selección del chip.
- IRQ – De manera opcional se puede emplear la señal de interrupción.
Librería para la comunicación con el NRF24L01
La librería que preferimos es llamada RF24, podemos descargarla desde el enlace correspondiente que se muestra más abajo. También dejamos el enlace correspondiente para el repositorio del proyecto.
Podemos también realizar la instalación de la librería correspondiente desde el gestor de librerías de arduino.
Código para la comunicación de dos arduino por radiofrecuencia con NRF24L01+.
El objetivo del programa es transmitir vía inalámbrica el estado de los pines de un arduino a otro, de manera constante.
En una de las tarjetas arduino conectaremos entonces botones o dipswitches (transmisor) que nos permitan ingresar un estado lógico alto o bajo a los pines del microcontrolador y en la otra (receptor), montaremos leds que podemos utilizar para visualizar los datos recibidos.
Hay que recordar que estos radios tienen la capacidad para funcionar como receptor y emisor (pero no ambos al mismo tiempo, son half-duplex), por lo que podemos intercambiar información en el sentido opuesto si así lo quisiéramos.
Transmisor con NRF24L01+
El sketch que debemos cargar en el arduino que actúa como transmisor es el siguiente:
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 | /** GeekFactory - "INNOVATING TOGETHER" Distribucion de materiales para el desarrollo e innovacion tecnologica www.geekfactory.mx Ejemplo de transmisor utilizando el radio NRF24L01+ en conjunto con una tarjeta Arduino Uno R3. Requiere la conexión como se muestra en los diagramas del tutorial para el transmisor. */ #include <Arduino.h> #include <RF24.h> // direccion de transmision byte address[] = {"1Node"}; // constructor del objeto RF24 para la comunicacion del arduino con el NRF24L01+ // configuracion de los pines de control del radio en el constructor: // el primer parametro es el pin CE (chip enable), el segundo es CS (chip select) RF24 radio(A0, A1); /** * Lee los pines de entrada digitales del 2 al 9 y almacena los valores presentes en * estos 8 pines en una variable de tipo byte. * * @return Retorna una mascara de bits que representa el estado de los pines. */ byte digitalReadPins() { // variable tipo byte que contiene el estado de 8 pines byte retval = 0; // leer en un ciclo los pines, sus numeros son continuos // asi que se puede hacer de esta forma for (int i = 7; i >= 0; i--) { retval |= (digitalRead(i + 2) == HIGH) ? 1 : 0; if(i != 0)retval <<= 1; } // retornar estado return retval; } /** * Funcion setup de arduino, se ejecuta una vez al inicio del programa. */ void setup() { // preparar serial Serial.begin(115200); while (!Serial) ; Serial.println(F("----------------------------------------------------")); Serial.println(F(" EJEMPLO DE TRANSMISOR CON NRF24L01+ ")); Serial.println(F(" https://www.geekfactory.mx ")); Serial.println(F("----------------------------------------------------")); // configurar los pines como entrada del transmisor // aplica para los pines de 2 al 9 for (size_t i = 2; i <= 9; i++) { pinMode(i, INPUT_PULLUP); } // preparar el radio radio.begin(); // configurar la direccion a donde transmitiremos los datos radio.openWritingPipe(address); // configuramos este radio para comportarse como transmisor radio.stopListening(); } /** * Funcion loop de arduino, se ejecuta continuamente despues de setup. */ void loop() { // obtener el estado de los pines e imprimirlo byte estadoPines = digitalReadPins(); Serial.print(F("Transmitiendo estado de pines (")); Serial.print(estadoPines, BIN); Serial.print(F(") ... ")); // enviar los datos a traves del radio, utilizamos el acuse de recibo // automático para saber si se entregaron o no los datos al nodo remoto if (radio.write(&estadoPines, sizeof(estadoPines))) { Serial.println(F("OK")); } else { Serial.println(F("FALLO")); } // esperar 100 milisegundos entre transmisiones delay(100); } |
Receptor con NRF24L01+
Y para el receptor el código es como sigue:
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 | /** GeekFactory - "INNOVATING TOGETHER" Distribucion de materiales para el desarrollo e innovacion tecnologica www.geekfactory.mx Ejemplo de receptor utilizando el radio NRF24L01+ en conjunto con una tarjeta Arduino Uno R3. Requiere la conexión como se muestra en los diagramas del tutorial para el receptor. */ #include <Arduino.h> #include <RF24.h> // direccion de recepcion byte address[] = {"1Node"}; // constructor del objeto RF24 para la comunicacion del arduino con el NRF24L01+ // configuracion de los pines de control del radio en el constructor: // el primer parametro es el pin CE (chip enable), el segundo es CS (chip select) RF24 radio(A0, A1); /** * Escribe los pines digitales del 2 al 9 de acuerdo a la mascara de bits * que se le proporcione a esta funcion. * * @param value El estado de los pines almacenado en una variable tipo byte */ void digitalWritePins(byte value) { for (int i = 7; i >= 0; i--) { digitalWrite(i + 2, (value & (1 << i)) ? HIGH : LOW); } } /** * Funcion setup de arduino, se ejecuta una vez al inicio del programa. */ void setup() { // preparar serial Serial.begin(115200); while (!Serial) ; Serial.println(F("----------------------------------------------------")); Serial.println(F(" EJEMPLO DE RECEPTOR CON NRF24L01+ ")); Serial.println(F(" https://www.geekfactory.mx ")); Serial.println(F("----------------------------------------------------")); // configurar los pines como salida del receptor // aplica para los pines de 2 al 9 for (size_t i = 2; i <= 9; i++) { pinMode(i, OUTPUT); } // preparar el radio radio.begin(); // configurar la direccion para recepcion de datos radio.openReadingPipe(1, address); // configuramos este radio para comportarse como receptor radio.startListening(); } /** * Funcion loop de arduino, se ejecuta continuamente despues de setup. */ void loop() { // variable para recibir el estado de los pines byte estadoPines; // verificamos si el radio ha recibido algo if (radio.available()) { // leemos lo que ha recibido en la variable estadoPines radio.read(&estadoPines, sizeof(estadoPines)); // imprimir al monitor serial Serial.print(F("Recibido estado de pines: ")); Serial.println(estadoPines, BIN); // enviar a los pines de salida digitalWritePins(estadoPines); } } |
Precauciones a tener en cuenta.
Debemos tener en cuenta algunas precauciones antes de intentar armar el circuito y durante su puesta en marcha:
- Recordar que el NRF24L01 es una pieza que funciona con 3.3 volts, por lo que jamás debemos conectarlo a los pines de alimentación de 5 volts.
- Podemos alimentarlo con la salida de 3.3 volts de la placa arduino o con un regulador independiente.
- En cuanto a la parte de RF recordar que los radios NRF24L01 deben tener una configuración compatible entre ellos para poder comunicarse.
- El sketch que elaboramos se encarga de la configuración de bajo nivel y configura el transmisor y receptor para poder comunicarse.
Conclusión
En esta entrada hemos visto como realizar la comunicación de dos arduinos utilizando radios NRF24L01. Realizamos los ejemplos de conexión eléctrica con un Arduino uno y mostramos el pinout (patillaje) más popular para los radios NRF24L01+.
Mediante sencillos ejemplos hemos explorado el uso de la librería RF24, que permite acceder a funcionalidades básicas del módulo, pero también es una librería bastante completa que permite el uso avanzado del radio.
Las funcionalidades avanzadas del radio podrán explorarse en otros tutoriales o bien quedar en manos del lector indagar en estas. Mientras tanto, el código presentado en esta página deja un precedente para comenzar a utilizar los radios de forma sencilla, así como para realizar pruebas de funcionamiento o diagnósticos.