NRF24L01+ only transmits over a short distance (about 15-20 feet)

I am using four different Arduino Nanos to transmit a short message to one receiving Nano using these NRF24L01+ Transceivers. I am also using these Adapter Boards because they make it easy to connect the nrf24l01 to the arduinos without a bunch of wires. They also include a 10uf filter capacitor to filter out noise.

I am using the internal pullups to connect 4 buttons to each nano, and each button sends a slightly different message. For example the first nanos buttons will send “11, 12, 13, or 14” depending on the button pressed. The second nano “21, 22, 23, and 24”, the third “31, 32, 33, 34” and so on. The receiving nano interprets these messages.

When I have the transmitter and receiver right next to each other (a few feet apart) everything works wonderfully. It is not until I get about 15-20 feet away that I will only intermittently be able to successfully send the message along.

Here is my code for the transmitter:

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

RF24 radio(10, 9);

byte addresses[][6] = {"1Node", "2Node"};
boolean buttonPressed = false;
boolean dataToSend = false;
int button;
unsigned char data;
#define red 2
#define yellow 3
#define green 4
#define blue 5

void setup() {
  Serial.begin(9600);
  setupRadio();

  pinMode(red, INPUT_PULLUP);
  pinMode(yellow, INPUT_PULLUP);
  pinMode(green, INPUT_PULLUP);
  pinMode(blue, INPUT_PULLUP);
}

void loop() {

  if (!buttonPressed){
  checkButton();
  }
  
  if (dataToSend) {
    radio.write( &data, sizeof(unsigned char));
    Serial.print("Sent: ");
    Serial.print(data);
    dataToSend = false;
  }
  
  delay(20);
  
  while (digitalRead(button) == LOW){
    //wait for button to be unpressed
    delay(5);
  }
  buttonPressed = false;
}

void checkButton() {
  for (int i = red; i <= blue; i++) {
    if (digitalRead(i) == LOW) {
      button = i;
      buttonPressed = true;
      switch (i) {
        case red:
          data = 41;
          break;
        case yellow:
          data = 42;
          break;
        case green:
          data = 43;
          break;
        case blue:
          data = 44;
          break;
      }
      dataToSend = true;
      break;
    } else {
      button = 0;
    }
  }
}

void setupRadio(){
    // Initiate the radio object
  radio.begin();

  // Set the transmit power to lowest available to prevent power supply related issues
  radio.setPALevel(RF24_PA_LOW);

  // Set the speed of the transmission to the quickest available
  radio.setDataRate(RF24_1MBPS);

  // Use a channel unlikely to be used by Wifi, Microwave ovens etc
  radio.setChannel(124);

  // Open a writing and reading pipe on each radio, with opposite addresses
  radio.openWritingPipe(addresses[1]);
  radio.openReadingPipe(1, addresses[0]);

  radio.stopListening();
}

I am not including my code for the receiver because it is quite long and I am pretty sure there are no issues on that end. I can include it upon request though.

I was originally using a 12V 2A wall adapter and wasn’t having much luck with more than 10 feet, but I found a different 12V 3A wall adapter and am getting about 15-20 feet now.

I was looking into buying the version of the NRF24L01+ that includes a PA+LNA for improved range (1100m) but I really only need to be able to transmit about 50-60 feet so I think that might be overkill and might not solve the issue I am having.

I am very much open to trying stuff out if anyone has any suggestions.

Thanks!

Antennas are extremely important. Boards with "PCB squiggle" antennas aren't worth more than the $1.20/each you paid for them.

These should yield 100 meters or better, outdoors and line of sight: https://www.amazon.com/-/es/longruner-Transceiver-NRF24L01-antiest%C3%A1tico-Compatible/dp/B06WLH4ZG6/

Have a look at this website.

Quote from page ...

The example with radio.setPALevel(RF24_PA_LOW); will be only 10 feet or so. But reliable. You can do these things to get better range:

So that website says that once I can supply around 250mA of current from 3.3V, then I could change RF24_PA_LOW to RF24_PA_MAX. I don't think I will be able to get the much current from the 3.3V of the Arduino, especially because I am drawing current from 4 leds in each button I am using. I will try disconnnecting the leds and see if that makes a difference.

I am also considering getting the boards with the antennas and replacing the "PCB squiggle" ones, but I am wondering if that wouldn't make a difference if I can't set my PA level any higher due to my limited current draw...

My next solution may be to use a separate 3.3V supply that can supply more current than the Arduino can.

jremington: Boards with "PCB squiggle" antennas aren't worth more than the $1.20/each you paid for them.

That's a bit unfair. I have had a pair of them working at 110m outdoors with clear line of sight. I would certainly expect them to work at 15 to 20metres (rather than feet).

A lot will depend on whether the antennas are correctly oriented and and no shielded by metal parts close to them. I believe th signal radiates outwards perpendicular to the flat faces of the PCB.

Another possible reason for poor performance is interference from other 2.4GHz devices nearby. It might be a good idea to try using a different channel.

It looks as if the OP's program sends data all the time that a button is pressed

if (digitalRead(i) == LOW) {

That probably results in too many messages being sent IMHO it is better to send a message at a regular interval - perhaps 5 times per second - even if the data has not changed. That way if the next few messages fail to arrive the receiver can tell there is a communication problem. That is the technique that is used in this Simple nRF24L01+ Tutorial

...R