NRF24L01+ will not receive with auto ack turned off

I have several receivers in my house, some further away than others. Sometimes the one farthest away will not receive the signal because a closer receiver sent the ack. I want to turn off the auto acknowledge on the closer receiver, but when I do the receiver no longer receives anything.

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

boolean newData = false;//used to verify that data has been received
char data[14]; //holds data as received from the radio
byte radioAddress[5] = {'C', 'S', 'C', 'A', 'A'};

RF24 radio(6, 7);//CE,CSN

void setup() {
  Serial.begin(115200);  
  printf_begin();
  radio.begin();
  //radio.setAutoAck(false);
  radio.openReadingPipe(0, radioAddress);
  radio.setPALevel(RF24_PA_MIN);
  radio.setDataRate( RF24_250KBPS );
  radio.startListening();
  radio.printDetails();
}

void loop() {
  getData();
  if (newData == true) {
    Serial.println(data);
    newData = false;
  }
}

void getData() {
  if ( radio.available() ) {
    radio.read( &data, sizeof(data) );
    newData = true;
  }
}

I have the “radio.setAutoAck(false)” commented out since that line disables the radio from receiving. Other people seem to use that option just fine, but I have never been able to get it to work.

You need to post the TX program also. Maybe it is not transmitting if it fails to receive an acknowledgement.

I'm not sure this makes sense

Sometimes the one farthest away will not receive the signal because a closer receiver sent the ack

Do you mean that both receivers are listening on the same address and are intended to receive the same message?

If so they should both have received the message before any of them sends an ACK and then both of them would send an ACK (unless it is disabled) which will cause the ACK to be garbled.

If you want to have more than one listener then only one of them should have AutoAck enabled.

...R
Simple nRF24L01+ Tutorial

The TX code really does not matter, I don’t think. It works with all the other receivers. I have many receivers (though I have tested with just one pair with the same results). Only the receiver that I turn off ACK does not receive. I wanted to turn off ACK for just the reason that you say, but it breaks that receiver. The others still get the message.

TX code:

#include <nRF24L01.h>
#include <RF24.h>
#include "printf.h"
#include "LowPower.h"

const byte slaveAddress[5] = {'C', 'S', 'S', 'A', 'A'};//set receiver to same address
char data[14] = "TS123456789ABC";

RF24 radio(6, 7);//CE,CSN

void setup() {
  Serial.begin(115200);
  printf_begin();
  radio.begin();
  radio.setPALevel(RF24_PA_MIN);
  radio.setDataRate( RF24_250KBPS );
  radio.setRetries(2, 10); // delay, count
  radio.printDetails();
  radio.openWritingPipe(slaveAddress);
}

void loop() {
  send();
  delay(1);
  LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);//sleep for 8 seconds
}

void send() {
  bool rslt = radio.write( &data, sizeof(data) );
  if (rslt) {
    Serial.println("  Acknowledge received");
  } else {
    Serial.println("  Tx failed");
  }
}

it is stripped down code to keep it simple. I have not actually tested this version as I have much to do this morning. But it does compile. The setup code is the same.

Both receivers are on the same address and intended to receive the same message. One is a lot closer and it seems that when it is listening the far receiver does not get the message sometimes. The closer receiver gets the message and sends the ack. If the remote receiver was the only one sending the ack then the transmitter would retry a few times.

I'm finding your description a bit confusing. First you say "It works with all the other receivers. I have many receivers" and later you say "Both receivers are on the same address and intended to receive the same message"

Are you using many, or just two?

When you use many, are they all listening on the same address and do they all have AutoAck on or off?

You have a "sleep" line in your program and I am not familiar with that. Does it mean that there is an 8 second interval between sending messages?

What happens if you also turn AutoAck off in the TX?

Is your problem specific to a particular nRF24 module?

...R

I'm sorry it is confusing. I have many receivers and transmitters, all who share the same address. I use identifiers in the data to indicate where the data came from. However, I have tested with just two radios, one as a transmitter, the other as a receiver. When I turn off ACK on the receiver it stops receiving. I have gone bare bones with the setup and I have never gotten it to receive. I usually don't have any trouble transmitting and receiving on my network, but I just ran into a problem with one of my remote transmitters failing to reach the receiver, and I suspect that it is due to a closer receiver sending the ACK.

I'm using this type of radio: 1 pc Long Range E01 ML01DP5 Ebyte 20dBm 2100m SPI NRF24L01+PA+LNA 2.4GHz RF Wireless Transceiver Module Antenna with Shield|Integrated Circuits| - AliExpress

I'm not exactly sure where I got mine from, but all have worked well so far.

the sleep line is just that, it puts the micro into powerdown mode, only a timer continues to run. It's a battery powered transmitter.

I have not tried turning off ACK on the TX. That makes little sense to me, but I can try it later.

amdkt7:
the sleep line is just that, it puts the micro into powerdown mode, only a timer continues to run.

That does not answer my simple question which was "Does it mean that there is an 8 second interval between sending messages?"

And you have not said whether the problem is specific to a particular nRF24 - in other words have you tried swapping them around?

The devices in your link look nothing like the nRF24s that I am familiar with but, as you say that they work, it must just be a style question. Unless, of course, they are not using Nordic nRF24L01+ chips.

I will try to test things with my nRF24s tomorrow.

...R

Gee.. yes it is an eight second interval as I included in the comments in the code.

Yes, it is multiple radios that I have tried. I have swapped them around.

I did some more testing. I shut down all the receivers in the house and found that I still had a problem receiving from the remote TX, when it is at the planned location. So, the problem does not seem to be a closer radio giving the ACK.

I tried doubling the number of retries to 20. Still missing transmissions.

Now trying increasing the power on the RX radio, from MIN, to LOW. So far no missed transmissions. Next, start firing up the other receivers.

I fired up two more receivers, both near the receiver that I am working on. I started getting a few missed coms. So I upped the RX radio from LOW, to HIGH. The receiver will not be battery powered and so I can afford the power usage.

Two more close receivers did not cause a problem. Brought a couple more on line that are closer the the transmitter. Now, the problem has come back. I'll try MAX power on the receiver.

MAX power is helping, but not solving the problem. I guess I will next take the transmitter power up a notch. I might give this unit it's own network as I don't need it's data widely available. The role of this transmitter is critical, a missed transmission is important. The other sensors don't matter so much. Eventually an update will happen.

Upped the TX power to low. Still getting missed transmissions. I guess I will need to put these on a different address. I could also try setting up a software based acknowledgment system, but that would increase the battery usage.

It's clear that the other receivers are providing the acknowledgment and thus not allowing the far receiver to pick up and respond.

I wish I could disable the ACK.

Why not give each nRF24 a separate address and have the master send the message to each of them in succession?

...R

I think this post is going to help me: TMRh20s Project Blog?sm_au=iHVkFHTMF5JJS1PjT1R3HK3KqKVCW

From tmrh20:
"I think you are just misunderstanding/misusing the ESB/AA functionality. With AA its generally 1->1 communication per address. Disable it on at least one pipe on all devices for multicasting."

I hope to dig into this later today, looking busy so far.

I have set up 3 Arduinos. One of them has the SimpleTx program from my Tutorial and the other two have the SimpleRx program.

So far I have had the same experience as you. With a Tx and Rx pair If I disable AutoAck on the RX nothing appears to be received. However if I also disable AutoAck on the Tx the system works fine.

With 3 devices if I have AutoAck enabled on the Tx and one Rx they work fine. But if AutoAck is off on the second Rx it does not receive anything. (I did not try it with AutoAck on for both Rxs).

Conversely if I have AutoAck off for the Tx and one Rx they work fine but the second Rx with AutoAck on does not receive anything.

However from studying the nRF24 datasheet it seems that it should receive the data even if AutoAck is off on the receiver.

It has taken me a long time to get the three Arduinos set up so I am going to take a break from my exploring. May try more later today or tomorrow.

...R

Yes, I think that turning off AutoAck on the transmitter would completely disable that feature, which I need for the situation where I have having trouble receiving, due to the whole house being in the way.

It appears that you have to use autoAck on individual pipes instead of on all. I'm not clear yet on how to set it up. My time too is busy today.

Thanks, I appreciate your research. Your results confirm that I'm not totally stupid.

amdkt7:
It appears that you have to use autoAck on individual pipes instead of on all. I'm not clear yet on how to set it up. My time too is busy today.

I was thinking about that but I have not tried it yet. Again, from reading the datasheet it is not obvious that it should make a difference.

...R

I think I have made some progress. I Googled nrf24 multicast and I got this link

I hope it will make things easier to follow if I describe my test setup. I am using the SimpleTx and SimpleRx programs from my Tutorial with no changes other than what is described below. I have a Mega set up as the Tx and another Mega set up as the first Rx. Then I have an Uno as the 2nd Rx. It is only on the Uno that I am experiment with turning AutoAck off.

To start with if I don't turn AutoAck off on the Uno some of the Mega transmissions report a fail - presumably because the two ACKs collide.

Then if I disable AutoAck the Uno won't receive anything - that is consistent with your experience.

Following the advice in the above link I added the two lines

radio.enableDynamicPayloads() ;
radio.enableDynamicAck();

to all three programs.

The two Megas continue to work as previously.

If I do NOT disable AutoAck on the Uno it, also receives all the messages normally and there is no sign that the TX sees any tx fails.

When I disabled AutoAck on the Uno it continued to receive data but it was receiving two (?) sets of messages so that the correct values were in every second message. I suspected that the confusion was due to multiple messages in the nRF24 Rx buffer. Unfortunately the TMRh20 RF24 library has created the flush_rx() function as private so I had to create my own equivalent - like this

void flushRx() {
    uint8_t status;

    digitalWrite(CSN_PIN, LOW);
    status = _SPI.transfer(FLUSH_RX);
    digitalWrite(CSN_PIN, HIGH);

}

and if I call flushRx() after the radio.read(..... the received data is presented correctly

One might conclude from all of this that it is not actually necessary to disable AutoAck, and, to be honest, I don't know whether it will make a difference. Perhaps it would if there were several "slaves" all sending ACKs back to the master.

Hope this makes sense and is of some help.

...R

I am hoping to get some time today to dig into all the resources I have, and to understand what you just did. I appreciate your digging in to the issue.

You can send single messages without ack by using

bool  write (const void *buf, uint8_t len, const bool multicast)

Whandall:
You can send single messages without ack by using

bool  write (const void *buf, uint8_t len, const bool multicast)

The idea is to transmit using ack so that the furthest receiver can verify that it received the message. Hoping to turn off ack for the closer receiver. That looks like a command to transmit without ACK completely.

amdkt7:
That looks like a command to transmit without ACK completely.

Yes, it is the one that works if more than one station listens to the same pipe with acks enabled.

Whandall:
You can send single messages without ack by using

I was hoping you might join the party.

However the plan is to send the messages with an ACK expected from one slave only. The other slaves should just receive the data. And my explorations as described in Reply #13 seem to solve the problem.

What I don't understand, despite a lot of study of the nRF24 datasheet, is why a slave with AutoAck disabled can't receive a message unless there is special treatment (as in Reply #13) in the TX. The flow charts seem to me to suggest that it should.

...R

Robin2:
However the plan is to send the messages with an ACK expected from one slave only. The other slaves should just receive the data.

This should work in a TX-Ack, 1-RX-Ack and many-RX-NoAck. The plan is as least uncommon.

Robin2:
What I don’t understand, despite a lot of study of the nRF24 datasheet, is why a slave with AutoAck disabled can’t receive a message unless there is special treatment (as in Reply #13) in the TX. The flow charts seem to me to suggest that it should.

I have not experimented much with global Ack/No-Ack, I handle it on a per pipe/packet base which works as one would expect.

I often use an additional No-Ack-pipe listener to eavesdrop the communication between two normal acking nodes.