Custom Ack Payload not received on NRF

I have two programs, one for the receiver, and one for the transmitter. The transmitter should transmit an integer value from the Serial Input to the Receiver, which should receive it and send back a custom ack payload containing an integer.

The data transmission works fine, where the receiver gets the integer from the transmitter, but there is nothing on the ack payloads. Do you have any inputs or advice?

Thanks!

Transmitter Code:

// Load in the libraries
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>

/*
PAYLOAD -- KEY
* All integers
0 - CONTINUE. When everything looks normal, this continues normal operations of the flight computer.
1 - ABORT. Log the abort and current state to SD, then shut off all active control.
*/

// Set the CE & CSN pins
#define CE_PIN   0
#define CSN_PIN 1

// This is the address used to send/receive
const byte rxAddr[6] = "00001";

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

void setup() {
  
  // Start up the Serial connection
  while (!Serial);
  Serial.begin(9600);
  
  // Start the Radio!
  radio.begin();
  
  // Power setting. Due to likelihood of close proximity of the devices, set as RF24_PA_MIN (RF24_PA_MAX is default)
  radio.setPALevel(RF24_PA_MIN); // RF24_PA_MIN, RF24_PA_LOW, RF24_PA_HIGH, RF24_PA_MAX
  
  // Slower data rate for better range
  radio.setDataRate( RF24_2MBPS ); // RF24_250KBPS, RF24_1MBPS, RF24_2MBPS

  radio.enableAckPayload();
  radio.enableDynamicPayloads();
  
  // Number of retries and set tx/rx address
  radio.setRetries(15, 15);
  radio.openWritingPipe(rxAddr);

  // Stop listening, so we can send!
  radio.stopListening();
}

void loop() {
  // Set up a message and a timestamp to it using millis()
  String str = Serial.readString();
  int ackData;

  if (str != "") {
    str.trim();
    int str_len = str.length() + 1; 
    // Prepare the character array (the buffer) 
    char char_array[str_len];
    // Copy it over 
    str.toCharArray(char_array, str_len);
    // Ace, let's now send the message
    radio.write(&char_array, sizeof(char_array));

    // Let the ourside world know..
    Serial.print("Sent Message: ");
    Serial.print( char_array );
    Serial.println("");
    if (radio.isAckPayloadAvailable()) {
      radio.read(&ackData, sizeof(ackData));
      Serial.print("Ack data recieved: ");
      Serial.println(ackData);
    }
  }
}

Receiver Code:

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

#define CE_PIN   9
#define CSN_PIN 8

RF24 radio(CE_PIN, CSN_PIN);

/*
PAYLOAD -- KEY
* All integers
0 - CONTINUE. Log continnue and current state to SD. When everything looks normal, this continues normal operation of computer.
1 - ABORT. Log abort and current state to SD, then shut off all active control.
2 - HOLD. Log halt and current state to SD, then stop all active control, while keeping data and configurations in-place.
*/

// The tx/rx address
const byte rxAddr[6] = "00001";

int ackPayload = 4;

void setup()
{

  // Start the serial
  Serial.begin(9600);
  while(!Serial);
  Serial.println("NRF24L01P Receiver Starting...");
  
  // Start the radio, again set to min & slow as I'm guessing while testing theire really close to each other
  radio.begin();
  radio.setPALevel(RF24_PA_MIN);   // RF24_PA_MIN ,RF24_PA_LOW, RF24_PA_HIGH, RF24_PA_MAX
  radio.setDataRate( RF24_2MBPS ); // RF24_250KBPS, RF24_1MBPS, RF24_2MBPS

  // Set the reading pipe and start listening
  radio.openReadingPipe(0, rxAddr);

  radio.enableAckPayload();
  radio.enableDynamicPayloads();
  
  // Preload a custom ack payload
  radio.writeAckPayload(0, &ackPayload, sizeof(ackPayload));

  radio.startListening();

}

void loop()
{
  if (radio.available())
  {

    // the buffer to store the received message in
    char text[100] = {0};
    
    // Now read the message, old examples have done = radio.read(), that doesn't work anymore!!!
    radio.read(&text, sizeof(text));
    int payload = atoi(text);
    // Print the message out to the COM window
    Serial.println("Received Payload: ");
    Serial.print(payload);
    Serial.println("");
    // Preload the next ack payload
    ackPayload = 2;
    radio.writeAckPayload(0, &ackPayload, sizeof(ackPayload));
  }
}

I suggest starting with the AcknowledgementPayloads example from the library. I wired up nRF24L01s to a couple of Uno R3s just now and It worked just fine for me, successfully sending back custom Ack payloads.

1 Like

And perhaps more importantly setAutoAck() on both sides. This sets a feature bit on the chip that turns on much more basic functionality than just AutoAck. Without it turned on, it downgrades the whole packet version being sent over the air to be compatible with an older chip you aren’t using.

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