I can not get ack to work on nRF24L01+

I have read so many posts, blogs and the datasheet and I absolutely can not get nRF24L01+ to do acknowledge. I have pretty much exhausted myself with it at this point. I understand all the concepts, I have a working transmitter to receiver hook up and code working but the moment I try to use enableAckPayload() I get a big nothing.

So bare with me I am extremely tried right now, could be argued I shouldn't be posting this now but I am so I can sleep. :confused: Based on the post found at this link which I could not reply to:

I have tried SimpleTxAckPayload.ino and SimpleRxAckPayload.ino seen in reply #2. I have tried to attach the output screen captures to this post hopefully they make it. It's all "Data Sent Message 0 Tx failed" on the TX side and gets stuck at "SimpleRxAckPayload" Starting on the RX side. The only difference in my code is

RF24 radio(9,10);

because that is where my pins are and that is how it works in my constant TX and constant RX working model. That is the only thing I changed and it's all glued down now I don't want to mess with changing that.

I started to write my own acknowledge off of working code I already have but it almost seems to me that when I add enableAckPayload() the whole attempt locks up. Meaning I just add that to a working script it won't work anymore, so I abandon writing my own till I can see a working proof of concept. My library is RF24 TMRh20 v1.3.11 right off the arduino library list.

So it's not the hook up, if the code works for others it should work for me and I am just out of ideas here.

Thank you!
Drew

Which Arduino board are you using?

Which variant of the nRF24L01 are you using? Is it the LNA+PA variant?

Did you get the SimpleTX and SimpleRX examples working?

And did you try the Connection Test program in my Simple nRF24L01+ Tutorial

...R

markd833:
Which Arduino board are you using?

Which variant of the nRF24L01 are you using? Is it the LNA+PA variant?

Did you get the SimpleTX and SimpleRX examples working?

NRF M 24L01+ 2012AH & UNO V3
I have not tried the SimpleTx and SimpleRX from that posting because I already had a working TX/RX setup by the time I reached that post. I don't know, I can't image there would be a vast difference but happy to give it a try later today and see what the outcome is. :smiley:

Drew

As I suspected, SimpleRX and SimpleTX appear to work just fine. Interestingly enough, I used it completely unmodified too. I tried the ACK example again unmodified, no dice, still doesn’t work.

Although it makes no difference in the end result in this case, I will mention that in my notes I had the CE and CSN definition meaning order confused in RF24() but had them the right way around it appears in SimpleRxAckPayload and SimpleRxAckPayload when I modified it to my config. It appears the default setup of SimpleRxAckPayload and SimpleRxAckPayload, as well as SimpleRX and SimpleTXhave the pins matching my setup. I just confused the names in my notes.

So it seems to me if one example works, the other should also work. I don’t get why it’s not. :blush:

Drew

pikadroo:
So it seems to me if one example works, the other should also work. I don't get why it's not. :blush:

Remind us about exactly what works and what does not work.

...R

PS ... please don't post pictures of text. Just copy and paste the text.

Ah you bet Robin… Hey I fixed your code for you it works now.

Arduino Compiler v1.8.10 and v 1.8.13
RF24 by TMRh20 Version 1.3.11
Authentic Arduino UNO V3
NRF M 24L01+ 2012AH

// SimpleRxAckPayload_Working (Example: Used as a data collection base slave)

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

#define CE_PIN   9
#define CSN_PIN 10

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

RF24 radio(CE_PIN, CSN_PIN);

char dataReceived[10]; // this must match dataToSend in the TX
int ackData[2] = {109, -4000}; // the two values to be sent to the master
bool newData = false;

//==============

void setup() {

    Serial.begin(9600);

    Serial.println("SimpleRxAckPayload Starting");
    radio.begin();
    radio.setDataRate( RF24_250KBPS );
    radio.openReadingPipe(1, thisSlaveAddress);
    radio.enableAckPayload();
    radio.enableDynamicPayloads();
 
    radio.startListening();

    radio.writeAckPayload(1, &ackData, sizeof(ackData)); // pre-load data
}

//==========

void loop() {
    getData();
    showData();
}

//============

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

//================

void showData() {
    if (newData == true) {
        Serial.print("Data received ");
        Serial.println(dataReceived);
        Serial.print(" ackPayload sent ");
        Serial.print(ackData[0]);
        Serial.print(", ");
        Serial.println(ackData[1]);
        newData = false;
    }
}

//================

void updateReplyData() {
    ackData[0] -= 1;
    ackData[1] -= 1;
    if (ackData[0] < 100) {
        ackData[0] = 109;
    }
    if (ackData[1] < -4009) {
        ackData[1] = -4000;
    }
    radio.writeAckPayload(1, &ackData, sizeof(ackData)); // load the payload for the next time
}
// SimpleTxAckPayload_Working (Example: Used as handheld master device to access data on collection base)

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


#define CE_PIN   9
#define CSN_PIN 10

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

RF24 radio(CE_PIN, CSN_PIN); // Create a Radio

char dataToSend[10] = "Message 0";
char txNum = '0';
int ackData[2] = {-1, -1}; // to hold the two values coming from the slave
bool newData = false;

unsigned long currentMillis;
unsigned long prevMillis;
unsigned long txIntervalMillis = 1000; // send once per second

//===============

void setup() {

    Serial.begin(9600);
    Serial.println(F("Source File /mnt/sdb1/SGT-Prog/Arduino/ForumDemos/nRF24Tutorial/SimpleTxAckPayload.ino"));
    Serial.println("SimpleTxAckPayload Starting");

    radio.begin();
    radio.setDataRate( RF24_250KBPS );
    radio.enableAckPayload();
    //radio.enableDynamicPayloads();
    radio.setRetries(5,5); // delay, count
 ¬† ¬†// 5 gives a 1500 ¬Ķsec delay which is needed for a 32 byte ackPayload
    radio.stopListening();
    radio.openWritingPipe(slaveAddress);
}

//=============

void loop() {

    currentMillis = millis();
    if (currentMillis - prevMillis >= txIntervalMillis) {
        send();
    }
    showData();
}

//================

void send() {

    bool rslt;
    rslt = radio.write( &dataToSend, sizeof(dataToSend) );
        // Always use sizeof() as it gives the size as the number of bytes.
        // For example if dataToSend was an int sizeof() would correctly return 2

    Serial.print("Data Sent ");
    Serial.print(dataToSend);
    if (rslt) {
        if ( radio.isAckPayloadAvailable() ) {
            radio.read(&ackData, sizeof(ackData));
            newData = true;
        }
        else {
            Serial.println("  Acknowledge but no data ");
        }
        updateMessage();
    }
    else {
        Serial.println("  Tx failed");
    }

    prevMillis = millis();
 }


//=================

void showData() {
    if (newData == true) {
        Serial.print("  Acknowledge data ");
        Serial.print(ackData[0]);
        Serial.print(", ");
        Serial.println(ackData[1]);
        Serial.println();
        newData = false;
    }
}

//================

void updateMessage() {
        // so you can see that new data is being sent
    txNum += 1;
    if (txNum > '9') {
        txNum = '0';
    }
    dataToSend[8] = txNum;
}

All you have to do is be sure to use:

radio.enableDynamicPayloads()

in the code for the RX unit and it works in 2021. Thank me, you’re welcome. 8)

These posts were helpful too:

Cheers Friends!
Drew

pikadroo:
All you have to do is be sure to use:

radio.enableDynamicPayloads()

in the code for the RX unit and it works in 2021. Thank me, you’re welcome. 8)

I wonder if that means there has been another change to the RF24 library that is not backwards compatible. If so that makes me mad for the second time.

I will investigate later.

Many thanks for your input.

…R

There isn't any backward incompatible code changes in v1.3.11. The fact that your tutorial code never called enableDynamicPayloads() before using ACK payloads means you weren't paying enough attention to the library example's comments nor reading the library's docs. I'm sorry you're so frustrated, but unofficial tutorials have been the #1 cause of confusion for people coming to github with troubleshooting questions. So, the frustration goes both ways.

2bndy5:
There isn't any backward incompatible code changes in v1.3.11.

Compared to what earlier version?

The Tutorial that I wrote in 2016 has worked perfectly well for other Forum users until recently. And it seems to me people have had more success with it (probably because it is deliberately simpler) than with the official examples.

I have added a note at the top of my Tutorial advising people to use V1.1.7 of the RF24 library.

If it is necessary for a new version of a library to be incompatible with an earlier version then the new version should be published under a different name so that users {A} can have easy access to both versions and {B} so that there is no possibility of confusion between compatible and incompatible versions. Without that the concept of a centralised Arduino library is nonsense and "library" files will have to stored with the application just in case a newer version breaks existing code.

...R

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.