NRF24L01 less range with Antenna

Hello All,

I'm at my wits end with this issue, so I'm turning to the Hivemind for help.

I have been using NRF24L01 modules for a while now, and recently wanted to make an RC controller for an RC car. Wanting more than the ~80m of range I get with two NRF24L01 modules, I bought 2 NRF24L01 Wireless Modules with Antenna and PA for 5V external power, and I read online I should be able to get a few hundred meters comfortably. However, despite uing an external 5V supply and 100uF capacitor, my range between two antenna Modules is a few centimeters max.

I bought new Antennas thinking they may just be defective, same issue again. I have quintuple checked my Pins are correct, have tried them without the PA, I have made sure I'm getting stable connection through my SPI, tried shorter and longer wiring, bought brand new modules (same issue) and varied my capacitors. Below is a picture of my current setup (usually used for modules without antenna), and I use the getting started code from the R24.h library. Any Tips would be greatly appreciated

#include <SPI.h>
#include "printf.h"
#include "RF24.h"

#define CE_PIN 9
#define CSN_PIN 10
// instantiate an object for the nRF24L01 transceiver
RF24 radio(CE_PIN, CSN_PIN);

// Let these addresses be used for the pair
uint8_t address[][6] = { "1Node", "2Node" };
// It is very helpful to think of an address as a path instead of as
// an identifying device destination

// to use different addresses on a pair of radios, we need a variable to
// uniquely identify which address this radio will use to transmit
bool radioNumber = 1;  // 0 uses address[0] to transmit, 1 uses address[1] to transmit

// Used to control whether this node is sending or receiving
bool role = false;  // true = TX role, false = RX role

// For this example, we'll be using a payload containing
// a single float number that will be incremented
// on every successful transmission
float payload = 0.0;

void setup() {
  // 1. Initialize Serial first
  Serial.begin(115200);
  
  // 2. Wait for Serial port to connect (CRITICAL for modern boards like Nano Every, Leonardo, ESP32)
  while (!Serial) {
    delay(10); 
  }
  // Force a slower SPI clock speed during initialization
  
  // 3. Print immediate confirmation that the board is alive
  Serial.println(F("--- Arduino Booting Up ---"));

  radio.begin();
  radio.setPALevel(RF24_PA_MIN); // Force lowest power draw (Software band-aid)

  if (!radio.isChipConnected()) {
    Serial.println(F("CRITICAL ERROR: radio hardware is not responding!!"));
    radio.printDetails();
    while (1) { delay(1000); 
    }
  }

  Serial.println(F("RF24/examples/GettingStarted"));
  Serial.println(F("Which radio is this? Enter '0' or '1'. Defaults to '0'"));
  
  while (!Serial.available()) {
    // wait for user input
  }
  
  char input = Serial.parseInt();
  radioNumber = input == 1;
  Serial.print(F("radioNumber = "));
  Serial.println((int)radioNumber);

  Serial.println(F("*** PRESS 'T' to begin transmitting to the other node"));

  radio.setPALevel(RF24_PA_LOW); 
  radio.setPayloadSize(sizeof(payload)); 
  radio.stopListening(address[radioNumber]); 
  radio.openReadingPipe(1, address[!radioNumber]); 

  if (!role) {
    radio.startListening(); 
  }
}

void loop() {

  if (role) {
    // This device is a TX node

    unsigned long start_timer = micros();                // start the timer
    bool report = radio.write(&payload, sizeof(float));  // transmit & save the report
    unsigned long end_timer = micros();                  // end the timer

    if (report) {
      Serial.print(F("Transmission successful! "));  // payload was delivered
      Serial.print(F("Time to transmit = "));
      Serial.print(end_timer - start_timer);  // print the timer result
      Serial.print(F(" us. Sent: "));
      Serial.println(payload);  // print payload sent
      payload += 0.01;          // increment float payload
    } else {
      Serial.println(F("Transmission failed or timed out"));  // payload was not delivered
    }

    // to make this example readable in the serial monitor
    delay(1000);  // slow transmissions down by 1 second

  } else {
    // This device is a RX node

    uint8_t pipe;
    if (radio.available(&pipe)) {              // is there a payload? get the pipe number that received it
      uint8_t bytes = radio.getPayloadSize();  // get the size of the payload
      radio.read(&payload, bytes);             // fetch payload from FIFO
      Serial.print(F("Received "));
      Serial.print(bytes);  // print the size of the payload
      Serial.print(F(" bytes on pipe "));
      Serial.print(pipe);  // print the pipe number
      Serial.print(F(": "));
      Serial.println(payload);  // print the payload's value
    }
  }  // role

  if (Serial.available()) {
    // change the role via the serial monitor

    char c = toupper(Serial.read());
    if (c == 'T' && !role) {
      // Become the TX node

      role = true;
      Serial.println(F("*** CHANGING TO TRANSMIT ROLE -- PRESS 'R' TO SWITCH BACK"));
      radio.stopListening();

    } else if (c == 'R' && role) {
      // Become the RX node

      role = false;
      Serial.println(F("*** CHANGING TO RECEIVE ROLE -- PRESS 'T' TO SWITCH BACK"));
      radio.startListening();
    }
  }

}  // loop

from what you say, it would point to power supply instability, a genuine counterfeit board with a wrong crystal load capacitor, or the PA/LNA stage never actually turning on.

How do you power the module ? The PA+LNA version of the NRF24L01 draws current spikes that can reach 100 to 150 mA during transmission, well beyond what a basic linear regulator or a thin breadboard wire can supply cleanly. A 100uF capacitor placed far from the pins doesn't always absorb these spikes. adding a 10uF ceramic or tantalum capacitor placed as close as possible to the module's VCC and GND pins, in addition to the 100uF further up the supply line

I also noticed in the code:

Try forcing RF24_PA_HIGH or RF24_PA_MAX if you're confident the power supply can handle it.

A few centimetres suggests a power or antenna-path problem. Confirm the radio itself receives 3.3 V .... use 5 V only if the adapter includes a regulator ..... and place 100 nF plus 10–100 uF capacitors directly across its power pins.

Also verify the antennas are 2.4 GHz with the correct SMA/RP-SMA centre contact. Test at RF24_PA_LOW and RF24_250KBPS, several metres apart, and try each PA module against a known-working standard module. This should identify whether the problem is power, receiver overload, or faulty modules.

Wow, it looks like you based your code on the official RF24 gettingStarted example!

Usually I see examples using addresses like "00001" and disabling Auto-Ack etc lol so nice job with the code.

There is also a setting to control the LNA, which you can adjust by calling radio.setPALevel(RF24_PA_MIN,0);, this will set PA to minimum and disable the LNA.

Other than that, the main 2 problems I see are the length of your connecting wires and possibly the power supply.

Forgot to add, you may want to try some ghetto shielding also, scroll down all the way at Optimized high speed nRF24L01+ driver class documentation: Common Issues

What's the unused item next to the breadboard?

I can't offer any more suggestions than has been done already, other than a close check of the SMA antenna connection.

As you might already know, the RP designation is Reversed Polarity. It's to stop, supposedly, fitting antenna that would not comply with regulations. Make sure the male pin fits in good contact with the female receptacle.

Thanks for the suggestions!

I've tried soldering a 10uF ceramic capacitor directly to the VCC GND pins, setting the power to high and messing around with the wire again. I've successfully extended the range from 3cm to about 6cm. I have a sinking feeling that the issue may be with the Antenna itelf.

The Antenna is indeed 2,4 GHz but i'm having issue locating it's signal because of how weak it is. It's being drowned out by the Antena-less Module on the other side of the room when I forget to turn it off.

Making a faraday cage also increased the range by a few centimeters, meaning I now have 12cm of range with the Antenna! I will order two new Modules from a different supplier and see if that fixes the issue. The only other issue I can see is that the Antennas themselves are somehow not a match for the modules, but I have no idea how i would test that (the Modules seem to have the same range with or without the Antenna)

Make your own 1/4 wavelength antenna.

Cut a piece of solid wire 31.25mm long and insert into SMA connector. Length does not include part insered into the connector.

Easy to do.

Antennas have a radiation pattern. That antenna probably has a Smith chart on the datasheet. An omnidirectional antenna in your picture:

Pattern: 360-degree horizontal "donut" shape; weak directly above/below

you have half an antenna. you have a radiator - the black stick. you do not have a ground plane. that antenna needs a disc, or at least a wire at an angle to the brass connector. a search for 2.4 ghz diy antenna will turn up a hundred sites that show you how

Not needed with the rubber duck antenna.

Could be. I have had at least one 2.4GHz antenna where the contact pin has broken off.

And I have just noticed that I have two where the internal threaded part is not aluminium but plastic so the contact at the end may not be good.

Is it broken or is it a reverse polarity connector?

I see that some AI agent is adding useless caption text to the pictures here. For example I've got:

I've tried two browsers now so I guess it is the forum software.

Let me try

No AI interference

Did you click on the picture ?

EDIT
I think I've found it:

Are those microcontroller pins soldered on ?

What microcontroller are you using ?

I wonder why the AI caption did not identify the microcontroller?

Good point. On a tablet screen with pinch magnification I can now read the silk screen markings sufficiently enough to see that it is a Nano ESP32.

Not until you prompted me !