How Much Distance You Can Actually Get From an nRF24L01

I tested the real-world range of two nRF24L01 modules, from indoor walls to open-field distances, to see how far they can actually communicate.
Dec 08, 2025 — 14 mins read — Electronics

How Much Distance You Can Actually Get From an nRF24L01

When I started this project, I wanted to see how far I could push a pair of nRF24L01 modules in real conditions instead of relying on the numbers written in the datasheet. I brought everything out to an empty road near my place so I could walk as far as needed without anything blocking the signal. My goal was simple. I wanted to send a small piece of data from one module to the other and see how the link behaved as I moved farther away.

This video is sponsored by Altium Develop


A Quick Look at the nRF24L01 Modules

When I first picked up the nRF24L01 modules, I noticed right away that they look a bit like the small ESP-01 boards, but they behave very differently. Each one has a single main chip and a large crystal on top, which makes them easy to recognize. They talk to the microcontroller through SPI, so once they’re wired, the only thing they really do is send and receive small packets of data over 2.4 GHz.

There are two versions of the module. One has only the tiny PCB antenna printed on the board, and the other comes with a built-in amplifier, a noise filter, and a long external antenna for more range. Both versions have the same pins and use the same wiring. The only real difference is how far they can reach. The small one is rated for around a hundred meters, while the bigger one can get close to a kilometer in ideal conditions. I wanted to see how close I could get to those claims once I started testing.


Building the Test Circuits

To keep the test fair, I built two identical circuits, one for sending and one for receiving. I used ESP8266 boards because they’re easy to power and program, and the nRF24L01 modules connect to them over SPI without much effort. Both modules run on 3.3 volts, so I powered the modules from the onboard power regulator of the NodeMCU boards. Once I had the wiring done, each setup looked almost the same, which helped me compare the results later on.

The only tricky part was mounting the nRF24L01 modules on a breadboard. Their pins are too close together, so I made simple adapters out of a piece of prototyping board. I soldered two rows of pins inside to match the module, then added another two rows on the outside so the adapter would fit the breadboard spacing. I even pushed the header pins farther through with pliers so they would sit deep enough to hold firmly. After that, I could plug any module into the adapter and swap between the small antenna and the large antenna whenever I needed.

Once both circuits were built, I plugged in the modules and checked that everything powered up as expected. With the adapters in place and the wiring clean, I was ready to start loading code on both boards and begin testing.


How the Code Works

I wrote two small sketches in the Arduino IDE, one for the transmitter and one for the receiver. On the transmitter, all I do is create a little data packet that holds a random number and a simple counter. Every second I send that packet through the nRF24L01 module. The RF24 library makes this easy because it handles all the low-level work, so my loop ends up being just a few lines of code.

On the receiver side, the sketch waits for any incoming packet. As soon as something arrives, I flash the onboard LED so I can see it working without looking at the screen. I also print the data in the serial monitor so I can follow the count and check if anything goes missing. When the transmitter is unplugged or too far away, the receiver prints a short warning after a few seconds so I know the link has dropped.

Both sketches share the same pin setup and radio settings. I kept the data rate low and used a specific channel so I could squeeze as much range out of the modules as possible. I could push the power level even higher, but from what I’ve read, the modules sometimes become unstable without extra capacitors. So I left it at a level that worked well during my bench tests.

The code for both of the modules is available below.


nRF24L01 Transmitter

/*
 nRF24L01 Range Test - Transmitter (NodeMCU ESP8266)

 Sends an incrementing counter value once per second.
 The receiver will display the value and track packet loss.

 Wiring (NodeMCU ESP8266):
  nRF24L01  ESP8266
  VCC     3.3V
  GND     GND
  CE     GPIO4 (D2)
  CSN     GPIO5 (D1)
  SCK     GPIO14 (D5)
  MOSI    GPIO13 (D7)
  MISO    GPIO12 (D6)
*/

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>

// Pin definitions for NodeMCU ESP8266
#define CE_PIN 4  // D2
#define CSN_PIN 5 // D1

// Create radio object
RF24 radio(CE_PIN, CSN_PIN);

// Communication address (must match receiver)
const byte address[6] = "RNG01";

// Data structure for transmission
struct DataPacket {
 uint32_t packetNumber;
 int16_t testValue;
};

DataPacket data;
uint32_t packetCount = 0;

void setup() {
 Serial.begin(115200);
 delay(1000); // Give ESP8266 time to initialize serial

 Serial.println(F("nRF24L01 Range Test - TRANSMITTER (NodeMCU ESP8266)"));
 Serial.println(F("==================================================="));

 // Initialize radio
 if (!radio.begin()) {
  Serial.println(F("ERROR: Radio hardware not responding!"));
  Serial.println(F("Check wiring and power supply (use 3.3V, add 10uF capacitor)"));
  while (1) {
   delay(1000);
  }
 }

 // Configure radio settings
 // For PA/LNA modules: start with LOW power for close-range testing
 // Options: RF24_PA_MIN, RF24_PA_LOW, RF24_PA_HIGH, RF24_PA_MAX
 radio.setPALevel(RF24_PA_HIGH);   // Use LOW for PA/LNA modules initially
 radio.setDataRate(RF24_250KBPS);  // Slower data rate = better range
 radio.setChannel(108);        // Channel 108 (2.508 GHz)
 radio.setRetries(5, 15);      // 5x250us delay, 15 retries
 radio.setPayloadSize(sizeof(data));

 // Open writing pipe
 radio.openWritingPipe(address);
 radio.stopListening();

 // Print configuration
 Serial.println(F("Configuration:"));
 Serial.println(F(" PA Level: HIGH"));
 Serial.println(F(" Data Rate: 250KBPS"));
 Serial.println(F(" Channel: 108"));
 Serial.println();
 Serial.println(F("Transmitting..."));
 Serial.println();
}

void loop() {
 // Update packet data
 packetCount++;
 data.packetNumber = packetCount;
 data.testValue = (int16_t)(sin(packetCount * 0.1) * 1000); // Varying test value

 // Send the data
 bool success = radio.write(&data, sizeof(data));

 // Print status
 Serial.print(F("Packet #"));
 Serial.print(data.packetNumber);
 Serial.print(F(" | Value: "));
 Serial.print(data.testValue);
 Serial.print(F(" | Status: "));

 if (success) {
  Serial.println(F("ACK received"));
 } else {
  Serial.println(F("FAILED - No ACK"));
 }

 // Wait 1 second before next transmission
 delay(1000);
}


nRF24L01 Receiver

/*
 nRF24L01 Range Test - Receiver (NodeMCU ESP8266)

 Receives packets from transmitter and displays:
 - Packet number and test value
 - Packets received vs expected (to detect losses)
 - Signal quality statistics

 Wiring (NodeMCU ESP8266):
  nRF24L01  ESP8266
  VCC     3.3V
  GND     GND
  CE     GPIO4 (D2)
  CSN     GPIO5 (D1)
  SCK     GPIO14 (D5)
  MOSI    GPIO13 (D7)
  MISO    GPIO12 (D6)
*/

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>

// Pin definitions for NodeMCU ESP8266
#define CE_PIN 4  // D2
#define CSN_PIN 5 // D1
#define LED_PIN 2 // Onboard LED (GPIO2, active LOW on NodeMCU)

// Create radio object
RF24 radio(CE_PIN, CSN_PIN);

// Communication address (must match transmitter)
const byte address[6] = "RNG01";

// Data structure for reception (must match transmitter)
struct DataPacket {
 uint32_t packetNumber;
 int16_t testValue;
};

DataPacket data;

// Statistics
uint32_t packetsReceived = 0;
uint32_t lastPacketNumber = 0;
uint32_t packetsLost = 0;
unsigned long lastReceiveTime = 0;

void setup() {
 Serial.begin(115200);
 delay(1000); // Give ESP8266 time to initialize serial

 pinMode(LED_PIN, OUTPUT);
 digitalWrite(LED_PIN, HIGH); // LED off (active LOW)

 Serial.println(F("nRF24L01 Range Test - RECEIVER (NodeMCU ESP8266)"));
 Serial.println(F("================================================"));

 // Initialize radio
 if (!radio.begin()) {
  Serial.println(F("ERROR: Radio hardware not responding!"));
  Serial.println(F("Check wiring and power supply (use 3.3V, add 10uF capacitor)"));
  while (1) {
   delay(1000);
  }
 }

 // Configure radio settings (must match transmitter)
 // For PA/LNA modules: start with LOW power for close-range testing
 // Options: RF24_PA_MIN, RF24_PA_LOW, RF24_PA_HIGH, RF24_PA_MAX
 radio.setPALevel(RF24_PA_HIGH);   // Use LOW for PA/LNA modules initially
 radio.setDataRate(RF24_250KBPS);  // Slower data rate = better range
 radio.setChannel(108);        // Channel 108 (2.508 GHz)
 radio.setPayloadSize(sizeof(data));

 // Open reading pipe
 radio.openReadingPipe(1, address);
 radio.startListening();

 // Print configuration
 Serial.println(F("Configuration:"));
 Serial.println(F(" PA Level: HIGH"));
 Serial.println(F(" Data Rate: 250KBPS"));
 Serial.println(F(" Channel: 108"));
 Serial.println();
 Serial.println(F("Waiting for transmitter..."));
 Serial.println();
}

void loop() {
 // Check if data is available
 if (radio.available()) {
  // Flash LED on receive
  digitalWrite(LED_PIN, LOW); // LED on (active LOW)

  // Read the data
  radio.read(&data, sizeof(data));
  packetsReceived++;
  lastReceiveTime = millis();

  // Calculate lost packets
  if (lastPacketNumber > 0) {
   uint32_t expectedPackets = data.packetNumber - lastPacketNumber;
   if (expectedPackets > 1) {
    packetsLost += (expectedPackets - 1);
   }
  }
  lastPacketNumber = data.packetNumber;

  // Calculate success rate
  float successRate = 0;
  if (data.packetNumber > 0) {
   successRate = ((float)packetsReceived / (float)data.packetNumber) * 100.0;
  }

  // Print received data
  Serial.print(F("RX #"));
  Serial.print(data.packetNumber);
  Serial.print(F(" | Value: "));
  Serial.print(data.testValue);
  Serial.print(F(" | Received: "));
  Serial.print(packetsReceived);
  Serial.print(F("/"));
  Serial.print(data.packetNumber);
  Serial.print(F(" ("));
  Serial.print(successRate, 1);
  Serial.print(F("%) | Lost: "));
  Serial.println(packetsLost);

  // Brief delay then LED off
  delay(50);
  digitalWrite(LED_PIN, HIGH); // LED off
 }

 // Check for timeout (no packet received for 5 seconds)
 if (lastReceiveTime > 0 && (millis() - lastReceiveTime) > 5000) {
  Serial.println(F("WARNING: No signal for 5+ seconds - out of range?"));
  lastReceiveTime = millis(); // Reset to avoid spamming
 }
}


Preparing for Range Testing

Before walking around with the receiver, I set everything up so I could follow the signal in real time. I left the transmitter on my bench in the office and powered it from a USB port so it would stay in the same spot for the whole indoor test. For the receiver, I plugged it into my phone through an OTG adapter and opened a simple serial terminal app. That way I could see every packet pop up on the screen as I moved around.

I also made sure the LED on the receiver was working because it gave me a quick way to tell if the data was still coming through. When the light blinked, I knew the packet arrived. When it stayed off and the phone showed a warning after a few seconds, I knew the link was gone. With that all ready, I started walking from room to room, then down the stairs, and then even deeper into the house to see how far the signal could reach before it disappeared.


Indoor Range Results

When I started moving through the house, the first few rooms were no problem at all. I was about ten meters away on the same floor, and the packets came in clean with no drops. The LED kept blinking steadily, and the counter on my phone matched perfectly with what the transmitter was sending. At one point I saw a couple of missed packets, but I couldn’t repeat it, so it was probably just a bit of interference.

Once I went down one floor, the signal still held up surprisingly well. It had to pass through a thick concrete ceiling, but the receiver kept getting the data with almost no issues. Going down another level pushed things much harder. I reached the entry area and started seeing the LED blink only when I held the receiver at a certain angle. A small change in position made the packets disappear, so at that point the link became unreliable.

When I finally walked all the way to the basement, the small PCB antenna couldn’t keep up anymore. The signal had to go through several walls and three concrete floors, and that was just too much. Even when I swapped only the receiver for the larger antenna version, nothing came through. Only after switching both modules to the big antenna did I get occasional packets, but even then it depended heavily on how the antennas were aligned. Indoors, the big antennas helped, but concrete still won.


Outdoor Long-Distance Test Setup

For the outdoor test, I set things up a bit differently so I could measure the distance more accurately. I placed the transmitter on a tripod at the edge of the road and left it running there, sending a packet every second just like before. Keeping it fixed made the whole comparison much easier, since the only thing changing was how far I walked.

I kept the receiver in my hand and powered it from my phone again, using the same serial app so I could watch the packets as I moved. To keep track of the distance, I used the GPS on my phone and noted the starting point right next to the tripod. From there, I simply walked straight down the road, checking both the screen and the LED every few steps to see how the link behaved as the gap increased.


PCB Antenna Outdoor Range

As soon as I started walking, the small PCB antennas worked better than I expected. At around fifty meters, the packets were coming in clean with no drops at all. Even when I reached roughly a hundred meters, the link stayed solid, and the LED kept blinking in rhythm with the transmitter. Out in the open, without walls and floors in the way, these little modules suddenly felt much stronger.

When I pushed past that point, things slowly became more sensitive. At about 130 meters, the packets still arrived, but I started seeing gaps in the counter. If I faced the transmitter directly, the signal came through, but if I turned around and my body blocked the path, the data stopped almost instantly. Just me standing in the way was enough to kill the communication, which shows how directional these tiny antennas can be.

By the time I reached the limit, the distance was already well beyond what the module is rated for. I was getting close to 130–140 meters, which surprised me considering these are the smallest antennas available. The packets weren’t perfectly reliable at that point, but they still came through often enough to prove that the basic PCB version can cover a long stretch when there’s nothing blocking the line of sight.


External Antenna Outdoor Range

When I switched to the modules with the external antennas, the difference was obvious right away. I started walking the same route as before, and at around 160 meters the receiver was still getting every packet without a single drop. I didn’t even bother adjusting the antenna angle at first because the link felt solid enough that it didn’t seem to matter. It was clear these amplified modules had much more reach in open space.

Farther down the road, the distance kept climbing without any real trouble. I passed the 300-meter mark, then 400, and the packets were still coming in. Only during quick movements did I see an occasional missed packet, usually when I covered the antenna by accident. When I reached about half a kilometer, the signal was still usable as long as I kept the antennas in a straight line. If I turned around, the link would drop instantly, but turning back brought it right back.

The real limit showed up somewhere near 750 meters. Beyond that point, the packets became so rare that the connection wasn’t reliable anymore, even though the path was clear. When I walked back a few meters, the packets started showing up again, but even there the tiniest movement could break the link. For a stable connection, I’d trust these modules up to around 700 meters outdoors. It’s not the full kilometer that the specs suggest, but it’s still an impressive range for something this small.


Next Steps

By the time I wrapped up the outdoor tests, I had a pretty good feel for what these modules can really do. The small PCB version held up well indoors and reached farther outside than I expected, but it struggled once heavy walls or concrete got in the way. The amplified version with the big antenna made a huge difference in open space and stayed reliable up to around 700 meters, which is more than enough for most projects I can think of. It didn’t quite reach a full kilometer, but the link stayed strong for much longer than the datasheet claims for the basic module.

If I were building something that needs long-distance communication, I’d definitely go with the external antenna version and keep the antennas in clear view of each other. Indoors, I wouldn’t count on huge distances, but for room-to-room communication or a small building, the modules work just fine. After testing both versions through walls, floors, and an open road, I feel like I know exactly where their limits are and where they shine.

If you want to try this yourself, you can grab the modules, load the same example code, and start experimenting. It’s a simple setup and a fun way to learn how wireless links behave in the real world. And if you enjoyed following along with the tests, stick around for the next project by subscribing to my YouTube channel.



Tools and Materials

The links below are affiliate links. This means if you click through and make a purchase, I may earn a small commission at no extra cost to you. This is a simple way to support my work and helps me continue creating free content for you. Thanks for your support!


radio test nodemcu nRF24L01
Read next

Sensor Power Switch Using an ESP32 and P-Channel MOSFET

I’m working on a bigger electronics project, and I ran into a common problem: power waste. My project uses an ESP32 board along with several...

You might also enojy this

LoRa Distance Testing with RYLR998 in the open field - Amazing results!

I'm planning to build a device that will make use of the LoRa communication protocol to transmit data over long distances and for that, I fi...