Componentes · 18 min de lectura

nRF24L01 Arduino: comunicación inalámbrica, código y alcance

Guía del nRF24L01 con Arduino: conexión, 3,3 V y condensador de 10 µF, código RF24 de emisor y receptor, PA+LNA hasta 1 km, mando con joystick, ESP32 y Pico.

La pareja nRF24L01 y Arduino es la forma más barata y práctica de enviar datos entre dos placas sin tender un cable. Este módulo del tamaño de una uña trabaja en la banda de 2,4 GHz, transmite hasta 2 megabits por segundo y puede funcionar tanto de emisor como de receptor. Es ideal para coches teledirigidos, joysticks inalámbricos, una estación que envía datos de un sensor del jardín a casa o nodos de alarma que se avisan entre sí. La versión estándar llega a unos 100 metros en campo abierto, y la versión nRF24L01+PA+LNA con antena externa puede alcanzar hasta 1 kilómetro en buenas condiciones.

En esta guía aprenderás cómo funciona el módulo, qué pines SPI usa, por qué debe alimentarse siempre a 3,3 V y cómo un condensador de 10 µF resuelve el problema más habitual. Después escribirás el código de emisor y receptor con la librería RF24, entenderás las direcciones y los canales, montarás un mando con joystick, conectarás el módulo a un ESP32 y a una Raspberry Pi Pico y, por último, resolverás paso a paso los problemas "radio.begin() false" y "no llegan datos".

Módulo de comunicación inalámbrica nRF24L01 de 2,4 GHz
Módulo nRF24L01+ estándar: la pista en zigzag del extremo de la placa es la antena impresa; se conecta por SPI a través del conector de 8 pines.

¿Qué es el nRF24L01 y cómo funciona?

El nRF24L01 es un chip transceptor de radio de 2,4 GHz fabricado por Nordic Semiconductor; casi todos los módulos que se venden hoy llevan la versión mejorada nRF24L01+ o un clon compatible. El módulo se comunica con Arduino por SPI: Arduino escribe por SPI la configuración y los datos a enviar, y el chip se encarga del resto. El protocolo por hardware de Nordic, llamado Enhanced ShockBurst, envuelve cada paquete con una dirección y un CRC (control de errores). Cuando el receptor recibe un paquete correctamente, devuelve automáticamente una confirmación (ACK) al emisor; si no llega, el emisor reintenta por sí solo. Así que tu código solo dice "envía", y los reintentos y el control de errores ocurren en el hardware.

Un paquete transporta como máximo 32 bytes de datos. Puede parecer poco, pero caben de sobra los dos ejes de un joystick, unos cuantos botones y varios valores de sensores. El módulo usa uno de 126 canales, y la frecuencia del canal se calcula con 2400 + número de canal (MHz); por ejemplo, el canal 76 está en 2476 MHz. Un receptor puede escuchar 6 direcciones distintas (llamadas pipes, o tuberías) a la vez, así que un nodo central puede reunir datos de seis emisores.

CaracterísticaValor
Frecuencia2,400–2,525 GHz (126 canales, separación de 1 MHz)
Velocidad de datos250 kbps, 1 Mbps, 2 Mbps
Tensión de alimentación1,9–3,6 V (en la práctica, 3,3 V)
Pines de entradaTolerantes a 5 V (CE, CSN, SCK, MOSI)
Potencia de salida0, −6, −12, −18 dBm
Consumo (transmitiendo, 0 dBm)Unos 11,3 mA
Consumo (recibiendo, 2 Mbps)Unos 13,5 mA
Modo apagado (power down)Unos 900 nA
Sensibilidad del receptor−94 dBm (250 kbps), −85 dBm (1 Mbps), −82 dBm (2 Mbps)
Tamaño de paquete1–32 bytes
InterfazSPI, hasta 10 MHz
Número de pipes6

Diferencias entre nRF24L01 y nRF24L01+PA+LNA

En el mercado verás dos tipos de módulo. En el estándar, la antena es una pista de cobre en zigzag impresa en la placa. La versión nRF24L01+PA+LNA añade delante del mismo chip un circuito de radiofrecuencia: el PA (Power Amplifier, amplificador de potencia) refuerza la señal que sale y el LNA (Low Noise Amplifier, amplificador de bajo ruido) amplifica las señales débiles que llegan antes de pasarlas al chip. Además lleva una antena externa enroscada en un conector SMA. Los dos módulos tienen el mismo pinout y el mismo código y se comunican entre sí sin problemas; la diferencia está en el alcance y en el consumo. Los valores siguientes son aproximados y dependen del entorno.

Módulo RF nRF24L01+PA+LNA con antena
nRF24L01+PA+LNA: la versión con amplificadores de emisión y recepción y antena SMA. Funciona con el mismo código, pero consume mucha más corriente.
CaracterísticanRF24L01+ (antena impresa)nRF24L01+PA+LNA
AntenaImpresa en la placaAntena SMA externa
Potencia de salidaHasta 0 dBm (1 mW)Hasta +20 dBm (100 mW), según el modelo
Pico de corriente al transmitirUnos 12 mAHasta 115 mA
Pico de corriente al recibirUnos 13,5 mAHasta 45 mA
Alcance en campo abierto (250 kbps)50–100 m800–1100 m
Alcance en interiores10–30 m, 1–2 paredesVarias plantas y decenas de metros
Alimentación recomendadaPin de 3,3 V + condensador de 10 µFRegulador de 3,3 V aparte + condensador

Pines del nRF24L01 y conexión con Arduino

El módulo tiene 8 pines dispuestos en un conector de 2×4. El pin con el pad de soldadura cuadrado es el 1 y corresponde a GND; justo al lado está VCC. CE (Chip Enable) pone el módulo en modo escucha o transmisión, y CSN (Chip Select Not) se pone en LOW para decir "ahora hablo contigo" en el bus SPI. SCK, MOSI y MISO son las líneas SPI estándar y deben ir a los pines SPI fijos de tu placa, mientras que CE y CSN pueden ir a cualquier pin digital. El pin IRQ es opcional: pasa a LOW cuando llega un paquete o termina un envío y se usa si quieres trabajar con interrupciones. Para entender SPI, consulta Qué es SPI, y para ver el mapa completo de pines de tu placa, la herramienta Pinout.

Pin del nRF24L01FunciónArduino Uno / NanoArduino MegaESP32Raspberry Pi Pico
1 GNDTierraGNDGNDGNDGND
2 VCCAlimentación (3,3 V)3.3V3.3V3V33V3(OUT)
3 CESelección de modoD9D9GPIO 4GP6
4 CSNSelección SPID10D10GPIO 5GP5
5 SCKReloj SPID13D52GPIO 18GP2
6 MOSIDatos de la placa al móduloD11D51GPIO 23GP3
7 MISODatos del módulo a la placaD12D50GPIO 19GP4
8 IRQInterrupción (opcional)Sin conectarSin conectarSin conectarSin conectar
Nunca conectes VCC a 5 V. El chip aguanta como máximo 3,6 V, y 5 V pueden dañarlo para siempre. Los pines de señal toleran 5 V, así que pueden ir directamente a los pines SPI del Uno, pero la alimentación siempre debe ser de 3,3 V. Tampoco pinches el módulo directamente en la protoboard: por el conector de 2×4, los pines enfrentados caen en la misma tira y quedan en cortocircuito. Usa cables jumper hembra-macho.

El error más común: la alimentación y el condensador de 10 µF

La mayoría de los problemas con el nRF24L01 no vienen del código, sino de la alimentación. El módulo pide picos de corriente cortos y bruscos en el momento de transmitir. Los cables jumper largos y una fuente de 3,3 V débil no dan abasto: la tensión cae un instante y el chip envía un paquete corrupto, pierde confirmaciones o se reinicia. Según la documentación oficial, el pin de 3,3 V del Arduino Uno da como máximo 50 mA; basta para el módulo estándar, pero no para la versión PA+LNA, que llega a 115 mA. En algunos clones del Nano, los 3,3 V salen del chip USB-serie y son todavía más débiles. Los síntomas te sonarán: write() a veces funciona y a veces no, el módulo va mejor cuando lo tocas o el alcance se queda en unos pocos metros.

  • Condensador de 10 µF: Coloca un condensador electrolítico de 10 µF entre los pines VCC y GND del módulo, lo más cerca posible. La pata larga (+) va a VCC y el lado con la franja (−) a GND. También sirven valores de 10 a 100 µF; en Qué es un condensador puedes leer por qué funciona.
  • Condensador cerámico de 100 nF: Un pequeño condensador cerámico (marcado 104) en paralelo con el electrolítico filtra el ruido de alta frecuencia. Puedes descifrar los códigos de los condensadores con la herramienta Código de condensador.
  • Adaptador de zócalo: Las placas adaptadoras de 8 pines que se venden para el nRF24L01 ya traen un regulador AMS1117-3.3 y condensadores. Le das 5 V al VCC del adaptador y el módulo recibe 3,3 V limpios.
  • Regulador aparte: Alimenta la versión PA+LNA no desde el pin de 3,3 V de Arduino, sino desde un regulador AMS1117-3.3 independiente conectado a 5 V, y une todas las tierras.
  • Cables cortos: Mantén los cables jumper por debajo de 10 cm si puedes; los cables largos y flojos estropean tanto la alimentación como las señales SPI.
Regulador de voltaje AMS1117 de 3,3 V
Regulador AMS1117-3.3: baja 5 V a 3,3 V y soporta sin problemas la corriente alta que pide el módulo PA+LNA al transmitir.

Instalar la librería RF24

  1. En el IDE de Arduino, abre Herramientas > Administrar bibliotecas o haz clic en el icono de librerías de la izquierda.
  2. Escribe RF24 en el buscador e instala la librería RF24 de TMRh20. RF24Network, RF24Mesh y RF24Ethernet son librerías aparte y no hacen falta para empezar.
  3. Tras instalarla, encontrarás el ejemplo GettingStarted en Archivo > Ejemplos > RF24. El código de este artículo usa la sintaxis de RF24 a partir de la versión 1.5.
  4. Si es la primera vez que instalas una librería, sigue los pasos de Cómo añadir una librería en Arduino.
En ejemplos antiguos de internet verás radio.openWritingPipe(address) seguido de radio.stopListening(). Desde la versión 1.5 de RF24 se recomienda una sola línea: radio.stopListening(address). La forma antigua sigue compilando, pero puede mostrar un aviso "deprecated" (obsoleto). Si el código de este artículo no compila, actualiza tu librería RF24.

Dirección, canal y velocidad: cómo se ponen de acuerdo dos módulos

Para que dos módulos se oigan, algunos ajustes deben ser exactamente iguales en ambos lados. Piensa en una conversación por walkie-talkie: si no estáis en la misma frecuencia (canal), al mismo ritmo (velocidad de datos) y con el mismo indicativo (dirección), no oirás al otro. La dirección es un array de 5 bytes, y lo más sencillo es escribirla en el código como un texto de 5 caracteres, por ejemplo "00001". No veas la dirección como la identidad de un dispositivo, sino como un camino compartido entre dos dispositivos: el emisor deja paquetes en ese camino y el receptor que lo escucha los recoge. El tamaño del paquete también importa: RF24 usa por defecto paquetes de tamaño fijo, y si el receptor no espera el mismo tamaño que el emisor, nunca verá el paquete.

AjusteFunción de RF24Valor en este artículoNota
CanalsetChannel(76)76 (2476 MHz)0–125; igual en ambos lados
Velocidad de datossetDataRate(RF24_250KBPS)250 kbpsA menor velocidad, más alcance
DirecciónstopListening(dirección) / openReadingPipe(1, dirección)"00001"Destino del emisor = pipe del receptor
Tamaño de paquetesetPayloadSize(sizeof(datos))32 bytes (5 en el ejemplo del joystick)Con tamaño fijo, igual en ambos lados
Potencia de salidasetPALevel(RF24_PA_LOW)BajaNo tiene que coincidir; define el alcance
ACK automático y CRCActivados por defectoCRC de 16 bitsSi los desactivas, hazlo en ambos lados

Código del emisor (TX)

Para la primera prueba, conecta los dos Arduino a dos puertos USB y deja 1–2 metros entre los módulos. Carga en uno de ellos el siguiente código de emisor. Cada segundo envía un mensaje numerado y muestra en el Monitor Serie si el receptor lo ha confirmado. No olvides poner el Monitor Serie a 115200 baudios.

C++ (Arduino IDE)
1#include <SPI.h>
2#include <RF24.h>
3
4RF24 radio(9, 10);                        // CE, CSN pinleri / CE, CSN pins
5const uint8_t address[6] = "00001";       // iki tarafta aynı adres / same address on both sides
6char message[32];                         // en fazla 32 bayt / 32 bytes max
7uint16_t counter = 0;
8
9void setup() {
10  Serial.begin(115200);
11  if (!radio.begin()) {                   // modül cevap vermiyor / module not responding
12    Serial.println(F("nRF24L01 bulunamadi, kablolari kontrol et!"));
13    while (true) {}
14  }
15  radio.setChannel(76);                   // kanal 76 = 2476 MHz / channel 76 = 2476 MHz
16  radio.setDataRate(RF24_250KBPS);        // en uzun menzil / longest range
17  radio.setPALevel(RF24_PA_LOW);          // masa testi için düşük güç / low power for desk tests
18  radio.setPayloadSize(sizeof(message));  // paket boyu 32 bayt / 32-byte payload
19  radio.stopListening(address);           // verici modu + hedef adres / TX mode + target address
20}
21
22void loop() {
23  snprintf(message, sizeof(message), "Merhaba BlueGrays #%u", counter++);
24  bool ok = radio.write(message, sizeof(message));   // onay (ACK) geldi mi? / was it acknowledged?
25  if (ok) {
26    Serial.print(F("Gonderildi: "));
27    Serial.println(message);
28  } else {
29    Serial.println(F("Onay gelmedi"));
30  }
31  delay(1000);
32}

Código del receptor (RX)

C++ (Arduino IDE)
1#include <SPI.h>
2#include <RF24.h>
3
4RF24 radio(9, 10);                        // CE, CSN pinleri / CE, CSN pins
5const uint8_t address[6] = "00001";       // vericiyle aynı adres / same address as the transmitter
6char message[32];
7
8void setup() {
9  Serial.begin(115200);
10  if (!radio.begin()) {
11    Serial.println(F("nRF24L01 bulunamadi, kablolari kontrol et!"));
12    while (true) {}
13  }
14  radio.setChannel(76);                   // ayarlar vericiyle aynı / settings match the transmitter
15  radio.setDataRate(RF24_250KBPS);
16  radio.setPALevel(RF24_PA_LOW);
17  radio.setPayloadSize(sizeof(message));
18  radio.openReadingPipe(1, address);      // 1 numaralı boruyu aç / open pipe 1
19  radio.startListening();                 // alıcı modu / RX mode
20}
21
22void loop() {
23  if (radio.available()) {                // paket geldi mi? / has a packet arrived?
24    radio.read(message, sizeof(message));
25    Serial.print(F("Gelen: "));
26    Serial.println(message);
27  }
28}

radio.write() envía el paquete y devuelve true si el receptor lo confirma; si no hay confirmación, con la configuración por defecto lo reintenta 15 veces con unos 1,5 ms de separación y después devuelve false. En el receptor, openReadingPipe(1, address) asigna la dirección del emisor a la pipe 1, startListening() pone el módulo en modo escucha, available() indica si hay un paquete esperando y read() lo copia en tu variable. Si en el Monitor Serie del receptor ves líneas que van subiendo como "Gelen: Merhaba BlueGrays #0", "#1", "#2", tu enlace funciona.

No pongas los módulos pegados mientras pruebas y mantén baja la potencia. Sobre todo los módulos PA+LNA saturan el receptor del otro cuando transmiten a plena potencia a pocos centímetros, y se pierden paquetes, lo que parece una avería. Usa RF24_PA_LOW o RF24_PA_MIN a corta distancia y sube la potencia a la distancia real.

Alcance: de 100 metros a 1 kilómetro

Tres cosas determinan el alcance: la potencia de salida, la sensibilidad del receptor y el entorno. Cuanto menor es la velocidad de datos, más débiles son las señales que el receptor puede descifrar; la sensibilidad es de −94 dBm a 250 kbps, pero de −82 dBm a 2 Mbps. Esos 12 dB de diferencia equivalen, en campo abierto, a aproximadamente 4 veces más alcance. Las paredes, los árboles, el cuerpo humano y las superficies metálicas atenúan mucho la señal de 2,4 GHz, y los routers Wi-Fi, los dispositivos Bluetooth y los microondas comparten la misma banda.

VelocidadSensibilidadAlcance relativo¿Cuándo usarla?
250 kbps−94 dBmEl mayorMandos, sensores lejanos
1 Mbps−85 dBmMedioUso general (valor por defecto de RF24)
2 Mbps−82 dBmEl menorAlta velocidad, poca distancia

La elección del canal también cuenta. Los canales Wi-Fi más usados, 1, 6 y 11, ocupan aproximadamente de 2401 a 2473 MHz; los canales 74–83 del nRF24L01 quedan por encima y son más tranquilos si no hay cerca ningún router en los canales Wi-Fi 12 o 13. En Europa la banda libre de 2,4 GHz va de 2400 a 2483,5 MHz, así que no uses canales por encima del 83; los canales de 100 en adelante que recomiendan algunos ejemplos de internet quedan fuera de esta banda, y los límites exactos dependen de la normativa de cada país. Para ganar alcance, prueba lo siguiente:

  • Usa 250 kbps: Un mando o los datos de un sensor no necesitan velocidad, y con la tasa baja ganas alcance.
  • Arregla primero la alimentación y luego sube la potencia: RF24_PA_MAX solo tiene sentido con 3,3 V estables y un condensador; con una alimentación débil, subir la potencia empeora las cosas.
  • Coloca las antenas en alto y con la misma orientación: 1–2 metros sobre el suelo y las dos antenas en vertical en la misma dirección mejoran claramente el alcance.
  • Aléjalo del metal: No metas el módulo dentro de una caja metálica ni justo al lado de un pack de baterías grande.
  • Envuelve el PA+LNA sin blindaje: Envolver un módulo PA+LNA sin tapa metálica con cinta aislante y luego con papel de aluminio reduce las interferencias que se causa a sí mismo; el aluminio no debe tocar ningún pin ni el conector de la antena.
  • No transmitas sin antena: Hacer funcionar un módulo PA+LNA a plena potencia sin la antena puesta fuerza el amplificador de potencia.

Mando a distancia inalámbrico con joystick

Ahora vamos con un proyecto real: con un joystick conectado a un Arduino controlaremos sin cables un servomotor y un LED en un segundo Arduino. En el emisor, el pin VRx del joystick va a A0, VRy a A1 y el pulsador (SW) a D2; tienes los detalles en Módulo joystick. En el receptor, el cable de señal del servo va a D3 y el LED a D4 con una resistencia de 220 Ω. El nRF24L01 se conecta en ambos lados igual que en la tabla anterior.

La forma más limpia de enviar varios valores en un solo paquete es un struct (estructura). Aquí hay un detalle importante: usa tipos de tamaño fijo como int16_t y uint8_t. En el Arduino Uno un int ocupa 2 bytes y en el ESP32, 4; además, el compilador del ESP32 añade bytes de relleno al final de la estructura para alinearla. Si la misma estructura ocupa 5 bytes en el Uno y 6 en el ESP32, los tamaños de paquete no coinciden y no llega ningún dato. __attribute__((packed)) elimina ese relleno y deja la estructura en 5 bytes en cualquier placa. Primero, el emisor:

C++ (Arduino IDE)
1#include <SPI.h>
2#include <RF24.h>
3
4struct __attribute__((packed)) JoystickData {   // her kartta 5 bayt / 5 bytes on every board
5  int16_t x;
6  int16_t y;
7  uint8_t button;
8};
9
10RF24 radio(9, 10);                        // CE, CSN pinleri / CE, CSN pins
11const uint8_t address[6] = "JOY01";       // kumanda adresi / remote address
12JoystickData data;
13
14void setup() {
15  pinMode(2, INPUT_PULLUP);               // joystick butonu (SW) / joystick button (SW)
16  if (!radio.begin()) {
17    while (true) {}                       // modül yok / no module
18  }
19  radio.setChannel(76);
20  radio.setDataRate(RF24_250KBPS);
21  radio.setPALevel(RF24_PA_HIGH);         // orta-yüksek güç / medium-high power
22  radio.setPayloadSize(sizeof(data));
23  radio.stopListening(address);           // verici modu / TX mode
24}
25
26void loop() {
27  data.x = analogRead(A0);                // VRx ekseni 0-1023 / VRx axis 0-1023
28  data.y = analogRead(A1);                // VRy ekseni 0-1023 / VRy axis 0-1023
29  data.button = (digitalRead(2) == LOW);  // basılıysa 1 / 1 when pressed
30  radio.write(&data, sizeof(data));
31  delay(50);                              // saniyede 20 paket / 20 packets per second
32}

Después, el receptor que mueve el servo y enciende el LED:

C++ (Arduino IDE)
1#include <SPI.h>
2#include <RF24.h>
3#include <Servo.h>
4
5struct __attribute__((packed)) JoystickData {   // vericiyle birebir aynı / identical to the transmitter
6  int16_t x;
7  int16_t y;
8  uint8_t button;
9};
10
11RF24 radio(9, 10);                        // CE, CSN pinleri / CE, CSN pins
12const uint8_t address[6] = "JOY01";       // vericiyle aynı / same as the transmitter
13JoystickData data;
14Servo servo;
15unsigned long lastPacket = 0;
16
17void setup() {
18  pinMode(4, OUTPUT);                     // LED çıkışı / LED output
19  servo.attach(3);                        // servo sinyal pini / servo signal pin
20  if (!radio.begin()) {
21    while (true) {}
22  }
23  radio.setChannel(76);
24  radio.setDataRate(RF24_250KBPS);
25  radio.setPALevel(RF24_PA_HIGH);
26  radio.setPayloadSize(sizeof(data));
27  radio.openReadingPipe(1, address);
28  radio.startListening();                 // alıcı modu / RX mode
29}
30
31void loop() {
32  if (radio.available()) {
33    radio.read(&data, sizeof(data));
34    servo.write(map(data.x, 0, 1023, 0, 180));   // X ekseni -> servo açısı / X axis -> servo angle
35    digitalWrite(4, data.button ? HIGH : LOW);   // buton LED'i yakar / button lights the LED
36    lastPacket = millis();
37  }
38  if (millis() - lastPacket > 500) {      // 0,5 sn paket yok: güvenli konum / no packet for 0.5 s: failsafe
39    servo.write(90);
40    digitalWrite(4, LOW);
41  }
42}

El emisor envía 20 paquetes por segundo; con cada paquete, el receptor convierte el eje X a 0–180 grados y se lo pasa al servo. La parte de posición segura (failsafe) del receptor es muy importante: si se agota la batería del mando o te sales del alcance, la última orden no se queda aplicada para siempre; si durante 0,5 segundos no llega ningún paquete, el servo se centra y el LED se apaga. Si estás haciendo un coche robot, detén los motores en ese mismo punto. Alimentar el servo con una fuente de 5 V aparte, en lugar del pin de 5 V de Arduino, evita además que sus picos de corriente molesten al nRF24L01. Si conectas el eje Y a un driver de motores L298N, tendrás un coche robot inalámbrico; para más detalles sobre el servo, mira Qué es un servomotor.

Comunicación bidireccional y varios emisores

El nRF24L01 no puede transmitir y escuchar a la vez, pero hay una forma sencilla de lograr comunicación bidireccional: el ACK payload, es decir, enviar datos dentro del paquete de confirmación. El receptor prepara de antemano con writeAckPayload() los datos que añadirá a la siguiente confirmación (por ejemplo, la tensión de la batería o el valor de un sensor), y el emisor, tras un write() correcto, lee esa respuesta con available() y read(). Para ello, ambos lados deben llamar a enableDynamicPayloads() y enableAckPayload(). Para varios emisores, el receptor tiene 6 pipes: la 0 y la 1 usan una dirección completa de 5 bytes, y las pipes 2–5 comparten el resto de la dirección de la pipe 1 y solo se diferencian en un byte. En RF24 ese byte es el primer carácter del array de dirección; por eso se usan direcciones como "1Node", "2Node" y "3Node", que solo cambian en el primer carácter. Para redes más grandes existen las librerías RF24Network y RF24Mesh.

Conectar el nRF24L01 a un ESP32

En el ESP32 la librería RF24 funciona igual, y radio.begin() usa el bus VSPI por defecto: SCK = GPIO 18, MISO = GPIO 19, MOSI = GPIO 23. GPIO 5 es una buena opción para CSN y GPIO 4 para CE. El regulador de 3,3 V de las placas ESP32 DevKit es más potente que el del Uno, pero aun así no te saltes el condensador de 10 µF. En modelos como el ESP32-C3 o el ESP32-S3 los pines SPI por defecto son otros, así que revisa el mapa de pines de tu placa. Como el Wi-Fi del ESP32 también trabaja a 2,4 GHz, si usas los dos a la vez elige un canal del nRF24L01 alejado del canal Wi-Fi de tu router. El siguiente código lee en el ESP32 los paquetes del emisor con joystick; con la misma estructura puedes usar el ESP32 como pasarela que envía a internet los datos de los nodos nRF24L01. Si es tu primera vez con esta placa, empieza por Qué es el ESP32.

C++ (Arduino IDE)
1#include <SPI.h>
2#include <RF24.h>
3
4struct __attribute__((packed)) JoystickData {   // packed olmasa 6 bayt olurdu / 6 bytes without packed
5  int16_t x;
6  int16_t y;
7  uint8_t button;
8};
9
10RF24 radio(4, 5);                         // CE = GPIO 4, CSN = GPIO 5 pinleri / CE = GPIO 4, CSN = GPIO 5 pins
11const uint8_t address[6] = "JOY01";
12JoystickData data;
13
14void setup() {
15  Serial.begin(115200);
16  if (!radio.begin()) {                   // varsayılan VSPI: SCK 18, MISO 19, MOSI 23 / default VSPI pins
17    Serial.println("nRF24L01 bulunamadi!");
18    while (true) delay(1000);
19  }
20  radio.setChannel(76);
21  radio.setDataRate(RF24_250KBPS);
22  radio.setPALevel(RF24_PA_HIGH);
23  radio.setPayloadSize(sizeof(data));     // packed sayesinde 5 bayt / 5 bytes thanks to packed
24  radio.openReadingPipe(1, address);
25  radio.startListening();
26}
27
28void loop() {
29  if (radio.available()) {
30    radio.read(&data, sizeof(data));
31    Serial.printf("X=%d  Y=%d  Buton=%d\n", data.x, data.y, data.button);
32  }
33}

Si solo vas a comunicar placas ESP32 entre sí, ESP-NOW, que no necesita módulos extra, también es una buena opción; la ventaja del nRF24L01 es que funciona además con placas baratas y de bajo consumo como el Uno, el Nano o el Pro Mini.

nRF24L01 con Raspberry Pi Pico y MicroPython

Para MicroPython en la Pico se usa el driver nrf24l01.py del repositorio oficial micropython-lib. Puedes copiar el archivo a la Pico con Thonny o instalarlo desde tu ordenador con mpremote mip install nrf24l01. La conexión va por SPI0: SCK = GP2, MOSI = GP3, MISO = GP4, CSN = GP5, CE = GP6 y VCC = 3V3(OUT). Los valores por defecto del driver son distintos de los de RF24 (canal 46, paquete de 16 bytes), así que para hablar con Arduino fijamos de forma explícita el canal, la velocidad y el tamaño de paquete en el código. El siguiente código decodifica en la Pico los paquetes del emisor con joystick:

MicroPython
1from machine import Pin, SPI
2import struct
3import utime
4from nrf24l01 import NRF24L01, POWER_2, SPEED_250K
5
6spi = SPI(0, sck=Pin(2), mosi=Pin(3), miso=Pin(4))   # SPI0 pinleri / SPI0 pins
7csn = Pin(5, mode=Pin.OUT, value=1)                  # CSN pini GP5 / CSN pin GP5
8ce = Pin(6, mode=Pin.OUT, value=0)                   # CE pini GP6 / CE pin GP6
9
10nrf = NRF24L01(spi, csn, ce, channel=76, payload_size=5)   # Arduino ile aynı / same as the Arduino
11nrf.set_power_speed(POWER_2, SPEED_250K)             # -6 dBm güç, 250 kbps / -6 dBm power, 250 kbps
12nrf.open_rx_pipe(1, b"JOY01")                        # vericinin adresi / transmitter address
13nrf.start_listening()                                # alıcı modu / RX mode
14print("Dinleniyor... / Listening...")
15
16while True:
17    if nrf.any():                                    # paket geldi mi? / packet waiting?
18        x, y, button = struct.unpack("<hhB", nrf.recv())   # 2 + 2 + 1 bayt / 2 + 2 + 1 bytes
19        print("X:", x, "Y:", y, "Buton:", button)
20    utime.sleep_ms(5)

struct.unpack("<hhB") convierte los 5 bytes recibidos en dos números con signo de 16 bits y un byte; el "<" inicial indica el orden de bytes little-endian, el mismo que usan AVR y ESP32. Si no encuentra el módulo, el driver lanza "nRF24L01+ Hardware not responding", el equivalente en MicroPython a que begin() devuelva false en Arduino. Si estás empezando con la Pico, lee antes Qué es la Raspberry Pi Pico.

radio.begin() devuelve false: solución paso a paso

Si el Monitor Serie muestra "nRF24L01 bulunamadi" o el mensaje "radio hardware is not responding!!" de los ejemplos de RF24, Arduino no consigue hablar con el módulo por SPI. En ese caso el problema está casi siempre en el cableado o en la alimentación, no en el código. Carga primero el siguiente sketch de diagnóstico; imprime toda la configuración del módulo de forma legible.

C++ (Arduino IDE)
1#include <SPI.h>
2#include <RF24.h>
3#include "printf.h"                       // RF24 ile gelir / ships with RF24
4
5RF24 radio(9, 10);                        // kendi CE, CSN pinlerin / your CE, CSN pins
6
7void setup() {
8  Serial.begin(115200);
9  printf_begin();                         // printPrettyDetails için / needed for printPrettyDetails
10  bool ok = radio.begin();
11  Serial.print(F("begin(): "));
12  Serial.println(ok ? "true" : "false");
13  Serial.print(F("isChipConnected(): "));
14  Serial.println(radio.isChipConnected() ? "true" : "false");
15  radio.printPrettyDetails();             // tüm ayarları yazdır / print every setting
16}
17
18void loop() {
19}
  1. Revisa MOSI y MISO: Son los dos cables que más se confunden. En el Uno y el Nano, MOSI = D11, MISO = D12 y SCK = D13; en el Mega son 51, 50 y 52.
  2. ¿CE y CSN coinciden con el código?: Si escribiste RF24 radio(9, 10), CE va a D9 y CSN a D10. El ejemplo GettingStarted de RF24 usa los pines 7 y 8; si lo pruebas sin cambiarlo, cablea en consecuencia.
  3. ¿Llegan 3,3 V?: Mide con el multímetro entre VCC y GND; deberías ver 3,0–3,6 V. Si el módulo se conectó alguna vez a 5 V, puede estar dañado.
  4. Mira la salida de printPrettyDetails: Si las direcciones y los registros salen todos a 0x00 o 0xff, el bus SPI no funciona. Si los valores parecen razonables pero no hay comunicación, el problema está en el pin CE, en la configuración o en la alimentación.
  5. Acorta los cables y baja la velocidad SPI: Con cables largos o flojos, escribe RF24 radio(9, 10, 4000000) para bajar el SPI de los 10 MHz por defecto a 4 MHz.
  6. Cambia el módulo: Si todo lo demás está bien, prueba con un módulo de repuesto; en los packs baratos puede venir alguno defectuoso.

No llegan datos o llegan a ratos: errores frecuentes

SíntomaCausa probableSolución
begin() da true, pero al receptor no llega nadaCanal, velocidad, dirección o tamaño de paquete distintos en cada ladoCompara los cuatro ajustes en ambos códigos
No llegan datos del Uno al ESP32Tamaño de struct distinto (5 y 6 bytes)Usa tipos de tamaño fijo y __attribute__((packed))
write() da false, pero el receptor recibe los datosLa confirmación del receptor no llega al emisor, casi siempre por la alimentación del receptorPon también un condensador de 10 µF en el módulo receptor
Datos vacíos o sin sentido todo el ratoCable SPI flojo o MISO desconectadoCambia los cables y baja el SPI a 4 MHz
No funciona con los módulos juntos, pero sí al separarlosEl receptor se satura a plena potenciaUsa setPALevel(RF24_PA_LOW) o RF24_PA_MIN
Funciona mejor al tocarloAlimentación inestable o PA+LNA sin blindajeCondensador, regulador aparte y blindaje de aluminio
El enlace se corta a pocos metros2 Mbps, alimentación débil o interferencias Wi-Fi250 kbps, alimentación limpia y un canal entre 74 y 83
Cuando busques el fallo, vuelve siempre al montaje más simple: dos módulos a 1–2 metros, RF24_PA_LOW, 250 kbps, cables cortos y un condensador de 10 µF. Una vez que funcione así, aumenta paso a paso la distancia, la potencia y la complejidad del código; así verás enseguida en qué paso empieza el problema.

Ideas de proyectos con el nRF24L01

  • Mando inalámbrico para coche robot: Conduce un coche robot desde decenas de metros con un mando de dos joysticks.
  • Estación de sensores para el jardín: Envía los datos de un sensor de humedad del suelo y la temperatura desde un emisor a pilas hasta una pantalla en casa. Con radio.powerDown() el módulo consume unos 900 nA en reposo; puedes calcular la duración de la batería con la herramienta Duración de la batería.
  • Alarma inalámbrica de puerta y movimiento: Haz sonar un zumbador en la central cuando se active un sensor PIR o un interruptor reed.
  • Red de temperatura para varias habitaciones: Reúne en un único receptor los datos de los sensores de seis habitaciones a través de seis pipes.
  • Pasarela con ESP32: Reenvía con un ESP32 los datos de los nodos nRF24L01 a internet, al móvil o a un panel de control.
  • Marcador inalámbrico: Actualiza un marcador de 7 segmentos en un polideportivo con mandos de botones.

Pese a su bajo precio, el nRF24L01 ofrece más alcance, menos latencia y soporte para varios dispositivos que el Bluetooth; solo pide una alimentación limpia de 3,3 V y la misma configuración en ambos lados. Si quieres controlar desde el móvil, el módulo Bluetooth HC-05 puede encajar mejor, y para kilómetros de alcance, LoRa; tienes una comparación de las opciones en Módulos de comunicación inalámbrica para Arduino. En la app BlueGrays encontrarás proyectos como la comunicación entre dos Arduino, el control de un servo y un LED con joystick o un coche teledirigido, paso a paso, con esquemas y código listo para usar.

Preguntas frecuentes

¿Qué alcance tiene el nRF24L01?

El nRF24L01+ estándar con antena impresa llega a unos 50–100 metros en campo abierto a 250 kbps, y a 10–30 metros en interiores según las paredes. La versión nRF24L01+PA+LNA con antena externa puede alcanzar 800–1100 metros en espacio abierto y sin obstáculos. Para lograrlo necesitas una alimentación limpia de 3,3 V, un condensador de 10 µF y una velocidad de datos baja.

¿El nRF24L01 funciona con 5V?

No: el pin VCC trabaja entre 1,9 y 3,6 V, y 5 V pueden quemar el chip. En cambio, los pines de entrada CE, CSN, SCK y MOSI toleran 5 V, así que se pueden conectar a los pines SPI de un Arduino Uno sin conversor de niveles. Si quieres alimentar el módulo desde 5 V, usa un adaptador de zócalo con regulador AMS1117-3.3.

¿Por qué aparece el error "radio hardware is not responding"?

Este mensaje se imprime cuando radio.begin() devuelve false e indica que Arduino no puede comunicarse con el módulo por SPI. Las causas más comunes son MOSI y MISO intercambiados, pines CE y CSN distintos de los del código, una alimentación débil o de 5 V y cables jumper flojos. Revisa el cableado y consulta la salida de printPrettyDetails() para acotar el problema.

¿nRF24L01 o Bluetooth HC-05: cuál elegir?

Si entre varios Arduino necesitas mucho alcance, poca latencia y varios dispositivos, el nRF24L01 es mejor opción. Si quieres controlar desde el móvil, elige un módulo Bluetooth como el HC-05 o un ESP32, porque los teléfonos no hablan el protocolo del nRF24L01. El HC-05 suele llegar a unos 10 metros, mientras que el nRF24L01 llega mucho más lejos por un precio parecido.

¿Cuántos emisores puede escuchar un receptor nRF24L01?

Un receptor puede escuchar 6 pipes a la vez, es decir, reunir datos directamente de 6 emisores. Las pipes 2–5 comparten el cuerpo de la dirección de la pipe 1 y solo se diferencian en un byte. Para más nodos puedes consultar a los emisores por turnos o montar redes mucho más grandes con las librerías RF24Network y RF24Mesh.

¿Se puede conectar el nRF24L01 al móvil?

No directamente: aunque trabaja en la misma banda de 2,4 GHz, el nRF24L01 no usa los protocolos Wi-Fi ni Bluetooth. Si quieres controlarlo desde el móvil, pon un ESP32 en el centro de tu red nRF24L01 y pasa los datos al teléfono por Wi-Fi o Bluetooth. Así los nodos remotos hablan nRF24L01 y el móvil habla con el ESP32.

Ver todos los proyectos
Comunicación unidireccional entre 2 Arduino
#57Intermedio
Premium

Comunicación unidireccional entre 2 Arduino

Haces que dos Arduino hablen por un solo cable: pulsas el botón de uno y se enciende el LED del otro, vuelves a pulsar y se apaga. La placa que envía avisa del botón con un mensaje corto, y la que rec

4.4(37)
50
Comunicación bidireccional entre 2 Arduino
#58Intermedio
Premium

Comunicación bidireccional entre 2 Arduino

Dos Arduino se conectan con cables y hablan entre sí: pulsas el botón de uno y se enciende la luz del otro, lo pulsas otra vez y se apaga. Las dos placas llevan el mismo programa, así que cada una env

4.5(20)
26
Control Led con Joystick
#59Intermedio
Premium

Control Led con Joystick

Empuja hasta el fondo la palanquita del joystick en cualquier dirección y se enciende el LED de esa dirección: hay cuatro colores distintos para derecha, izquierda, arriba y abajo. Cuando sueltas la p

4.7(50)
67
Servocontrol con joystick
#60Intermedio
Premium

Servocontrol con joystick

Controla dos motores con un joystick, igual que si giraras una cámara de seguridad. Si empujas la palanca a izquierda o derecha, el servomotor de abajo gira despacio; si la empujas arriba o abajo, el

4.7(42)
58
Coche controlado por Bluetooth con L298N
#80Avanzado
Premium

Coche controlado por Bluetooth con L298N

Convierte tu móvil en un mando y conduce tu propio coche robot. El Arduino recibe por un módulo Bluetooth las órdenes de una app de control remoto en el móvil y mueve las ruedas con un controlador de

5.0(38)
65
Controlar un LED desde el móvil por Bluetooth
#34Principiante
Premium

Controlar un LED desde el móvil por Bluetooth

Un pequeño ensayo para encender y apagar las luces de tu habitación desde el móvil. El módulo Bluetooth pasa al Arduino las letras que envías desde el teléfono; una letra enciende el LED rojo, otra en

4.8(68)
89
Encendido y apagado de leds con receptor de infrarrojos y mando a distancia
#17Intermedio
Premium

Encendido y apagado de leds con receptor de infrarrojos y mando a distancia

Como manejar tres lámparas distintas sin levantarte del sillón: las teclas 1, 2 y 3 del mando encienden los LED azul, rojo y verde, y las teclas 4, 5 y 6 los apagan en el mismo orden. La tecla de ence

4.7(45)
66
Mando a distancia universal ESP32 IR (receptor de infrarrojos + mando + 3 LED + zumbador + pantalla OLED)
#143Avanzado
Premium

Mando a distancia universal ESP32 IR (receptor de infrarrojos + mando + 3 LED + zumbador + pantalla OLED)

¡Con el ESP32 puedes leer un mando a distancia por infrarrojos ya preparado y controlar tu propio dispositivo! En este proyecto capturamos las señales de un mando a distancia por infrarrojos de 20 teclas mediante un receptor de infrarrojos (protocolo NEC a 38 kHz). Hemos definido una acción diferente para cada tecla: las teclas 1, 2 y 3 activan o desactivan tres LED distintos; la tecla PWR apaga todos los LED; y los números del 4 al 9 muestran un mensaje específico en la pantalla OLED. En la pan

4.5(9)
16