NRF24L01 Range question

Say I have a base nrf24l01(without pa+lna) as an rx,
In terms of range, would it matter if the nrf24l01 on the tx has a pa+lna or not?

Basically, I wanted to know if the features of the rx matters or not. Would i get better range with a pa+lna model as compared to a model without it?

I need to know, if I need to buy two pa+lna models or just one on the tx would work.

To be clear, my use case for the project is a one-way communication, and I already have a set of base nrf24l01 modules.

Help?

For the price, get two.

heh heh kinda in a tight spot with my money.. dont wanna waste :slight_smile:

What range are you looking for?

What sort of obstacles would the signal encounter?

Ok, but if you're using the auto-acknowledge feature (which I think most examples actually do), the 'RX side' will also TX part of the time. So in that case it would be beneficial to have a PA + antenna on both sides of the communication. Depending on actual distance and conditions of course; e.g. I use these modules as glorified remote controls in a home setting where they only need to bridge a couple of meters; no PA & antenna needed here.

There are ways to maximize the range of what you have. Do a search for "increase nrf24l01 range".

Its for an indoor rc car, so the obstacles would be walls?

What is auto-acknowledge? ill pin my code here and tell me if I have it, and if so what part that is.

RX(car)

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

#define CE_PIN   3
#define CSN_PIN 4

const byte address[5] = {'R', 'x', 'A', 'A', 'A'};

RF24 radio(CE_PIN, CSN_PIN);

bool newData = false;
int text;
int m11 = 9;
int m12 = 8;
int m21 = 7;
int m22 = 6;
int en1 = 10;
int en2 = 5;

void setup() {
  Serial.begin(9600);
  Serial.println("SimpleRx Starting");
  radio.begin();
  radio.setDataRate( RF24_250KBPS );
  radio.setPALevel(RF24_PA_LOW);
  radio.openReadingPipe(1, address);
  radio.startListening();

  pinMode(10, OUTPUT);
  pinMode(9, OUTPUT);
  pinMode(8, OUTPUT);
  pinMode(7, OUTPUT);
  pinMode(6, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(LED_BUILTIN, OUTPUT);
  analogWrite(en1, 255);
  analogWrite(en2, 255);
}

void loop() {
  if ( radio.available() ) {
    radio.read( &text, sizeof(text) );
    newData = true;
  }
  //else if (!radio.available()) {
  //    text = 0;
  //    Serial.print ("unav");
  //  }
  if (newData == true) {
    //Serial.print("Data received ");
    //Serial.println(text);
    newData = false;
  }
  //  Serial.print(millis());
  switch (text) {
    case 1 : // Forward
      digitalWrite(m11, HIGH);
      digitalWrite(m12, LOW);
      digitalWrite(m21, HIGH);
      digitalWrite(m22, LOW);
      break;
    case 2 : //backward
      digitalWrite(m11, LOW);
      digitalWrite(m12, HIGH);
      digitalWrite(m21, LOW);
      digitalWrite(m22, HIGH);
      break;
    case 3 : //left
      digitalWrite(m11, LOW);
      digitalWrite(m12, HIGH);
      digitalWrite(m21, HIGH);
      digitalWrite(m22, LOW);
      break;
    case 4 : //right
      digitalWrite(m11, HIGH);
      digitalWrite(m12, LOW);
      digitalWrite(m21, LOW);
      digitalWrite(m22, HIGH);
      break;
    case 5 : //forward right
      digitalWrite(m11, HIGH);
      digitalWrite(m12, LOW);
      digitalWrite(m21, LOW);
      digitalWrite(m22, LOW);
      break;
    case 6 : //forward left
      digitalWrite(m11, LOW);
      digitalWrite(m12, LOW);
      digitalWrite(m21, HIGH);
      digitalWrite(m22, LOW);
      break;
    case 7 : //backward right
      digitalWrite(m11, LOW);
      digitalWrite(m12, LOW);
      digitalWrite(m21, LOW);
      digitalWrite(m22, HIGH);
      break;
    case 8 : //backward left
      digitalWrite(m11, LOW);
      digitalWrite(m12, HIGH);
      digitalWrite(m21, LOW);
      digitalWrite(m22, LOW);
      break;
    case 0 : //nothing
      digitalWrite(m11, LOW);
      digitalWrite(m12, LOW);
      digitalWrite(m21, LOW);
      digitalWrite(m22, LOW);
      break;
  }
  //  Serial.print("   ");
  //  Serial.println(millis());

}

TX(remote)

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

#define CE_PIN   9
#define CSN_PIN 10

const byte address[5] = {'R', 'x', 'A', 'A', 'A'};

RF24 radio(CE_PIN, CSN_PIN);

unsigned long currentMillis;
unsigned long prevMillis;
unsigned long txIntervalMillis = 50; // send once per second
int text = 0;
int rlt;
int bu = 7;
int bd = 8;
int bl = 6;
int br = 5;

void setup() {
  Serial.begin(9600);
  Serial.println("SimpleTx Starting");
  radio.begin();
  radio.setDataRate( RF24_250KBPS );
  radio.setPALevel(RF24_PA_LOW);
  //  radio.setRetries(3, 5); // delay, count
  radio.openWritingPipe(address);

  pinMode(bu, INPUT_PULLUP);
  pinMode(bd, INPUT_PULLUP);
  pinMode(bl, INPUT_PULLUP);
  pinMode(br, INPUT_PULLUP);
}

void loop() {
  if (digitalRead(bu) == 1 && digitalRead(bd) == 1 && digitalRead(bl) == 1 && digitalRead(br) == 1) {
    //Serial.println("0, nothing");
    text = 0;
  } else if (digitalRead(bu) == 0 && digitalRead(bd) == 1 && digitalRead(bl) == 1 && digitalRead(br) == 1) {
    //Serial.println("1, forward");
    text = 1;
  } else if (digitalRead(bu) == 1 && digitalRead(bd) == 0 && digitalRead(bl) == 1 && digitalRead(br) == 1) {
    //Serial.println("2, backward");
    text = 2;
  } else if (digitalRead(bu) == 1 && digitalRead(bd) == 1 && digitalRead(bl) == 0 && digitalRead(br) == 1) {
    //Serial.println("3, left");
    text = 3;
  } else if (digitalRead(bu) == 1 && digitalRead(bd) == 1 && digitalRead(bl) == 1 && digitalRead(br) == 0) {
    //Serial.println("4, right");
    text = 4;
  } else if (digitalRead(bu) == 0 && digitalRead(bd) == 1 && digitalRead(bl) == 1 && digitalRead(br) == 0) {
    //Serial.println("5, forward right");
    text = 5;
  } else if (digitalRead(bu) == 0 && digitalRead(bd) == 1 && digitalRead(bl) == 0 && digitalRead(br) == 1) {
    //Serial.println("6, forward left");
    text = 6;
  } else if (digitalRead(bu) == 1 && digitalRead(bd) == 0 && digitalRead(bl) == 1 && digitalRead(br) == 0) {
    //Serial.println("7, backward right");
    text = 7;
  } else if (digitalRead(bu) == 1 && digitalRead(bd) == 0 && digitalRead(bl) == 0 && digitalRead(br) == 1) {
    //Serial.println("8, backward left");
    text = 8;
  } 
  currentMillis = millis();
  if (currentMillis - prevMillis >= txIntervalMillis) {
    bool rslt;
    rslt = radio.write( &text, sizeof(text) );
    Serial.println(text);
    if (rslt) {
      rlt = 0;
    }
    else {
      rlt = 1;
    }
    prevMillis = millis();
  }
}

one more question, I want to make a failsafe, so if the radio loses connection i want the 'text' variable on the rx to go to zero... I tried to do "!radio.available()" , but it didnt work. Help on this too

OR any metal object that will reflect the 2.4gHz signal. Your car, for instance.

Thanks! I will try some solutions. But my goal for posting this question was to get the answer to my question, if i buy it or not

The receiver sends a confirmation back to the sender; an 'acknowledgement' - hence the name. The nrf24 chip handles this autonomously; i.e. the sender waits a certain period of time for the acknowledgement from the receiver, if it doesn't come, sender sends the data gain, until a timeout is reached. By default I think this function is enabled in the RF24 library.

For your application I would expect that some kind of confirmation from the car that the command has been received is pretty useful. Not having it will make the thing less responsive, annoying to drive etc.

Noo, I live in an apartment, there are hardly any metal objects here. only wood cabinets and concrete walls

yeah, but wouldnt that add a delay?
I can afford lost packets of data, as new data is being sent every 50 ms.

Also read the note on the bottom of my reply to you, I need some help with my code

And concrete walls all have rebar and a concrete floor is poured on a steel pan with rebar/steel screen in the concrete.

ummmm yeah..... sooo will the pa+lna chip increase my range? or its useless?

Only your test will give you the answer.

well, that would be quite an expensive test

I found pages about the range with 2 low power modules and pages about 2 high power modules. None with data about 1 the range to expect with 1 low and 1 high power module. One would think that the range would be somewhat increased over 2 low power modules but without data that is guessing.

My advice. Try what you have. Maximize the range using the available information. If the range is not sufficient , buy a high power module and repeat from step1. Or go to 2 high power modules.

About the price of a couple of trips to Starbucks.

You seem to contradict yourself. You mention that it's OK if packet loss occurs, but at the same time you want to detect a lost connection. I'd start by figuring out what you need. Hint: it's probably going to boil down to having a somewhat robust communication protocol that can handle (temporary) loss of connections etc. In my experience having the auto-ack feature is a good first step, but on top of that additional features might be useful. But I'd just start with the kind of code you have in the examples; they're a good start.

Yes, but handling a similar feature manually by disabling auto-ack adds much more of a delay. Trust me, I tried. In fact, I have a working protocol that doesn't use auto-ack but instead waits for a CRC from the receiver. I mostly wrote this to work around the 6-connections limit of the RF24 chip. Don't bother with this if it's just a remote and a car.

That doesn't check the connection with the remote side; it only checks the connection between the Arduino and the RF24 chip.
A fairly simple way is to just enable payloads over acknowledgements as shown in this example: https://github.com/nRF24/RF24/blob/master/examples/ManualAcknowledgements/ManualAcknowledgements.ino
By doing so you can for instance have the car echo back the command to the remote control so that the remote knows if it was received correctly. You could periodically send a 'keep alive packet' to the car just to check that the connection still lives. If the car doesn't respond, something is wrong etc.
I use this kind of approach in my remote controls to blink a red led if a command is not correctly acknowledged by the device it was sent to, so basically for the kind of user feedback you would probably use it as well.

1 Like