NRF24l01 trmh20 pingpair_ack date rate issues?

As the subject, the pingpair_ack example only works at 1MBPS. It fails completely at 250k and at 2M it gets a few blank responses before getting out of step, returning the previous, rather than the current message. Can anyone else duplicate this result?

I am using arduino uno and arduino nano.

Post your code so we can see what you can see.

Have you got your nRF24s to work with other code?

I got my nRF24s working with this Tutorial

I suggest you use the TMRh20 version of the RF24 library - it solves some problems from the ManiacBug version

The pair of programs in this link may be useful.

...R

Thanks for the reply.

I'm using trmh20 library. The code is the example pingpair_ack. My nrf24l01+ modules work with other examples. My question is specific to this mode of working ie an ack payload.

I'm not sure how you post code to this forum other than a copy paste. By code do you mean the .ino file or is there another file like a .lst that will show the real code rather than the library calls.

I've tried your example. The rx gets the data correctly but the tx never gets the reply.

cjcj1949:
I’m not sure how you post code to this forum other than a copy paste. By code do you mean the .ino file or is there another file like a .lst that will show the real code rather than the library calls.

I mean the code in the .ino file

I just mean to copy and paste it using the the code button </> so your code looks like this and is easy to copy to a text editor. See How to use the Forum

My question is specific to this mode of working ie an ack payload

The pair of programs I linked to use ackPayload

…R

[code]
/*
  // March 2014 - TMRh20 - Updated along with High Speed RF24 Library fork
  // Parts derived from examples by J. Coliz <maniacbug@ymail.com>
*/
/**
 * Example for efficient call-response using ack-payloads 
 *
 * This example continues to make use of all the normal functionality of the radios including
 * the auto-ack and auto-retry features, but allows ack-payloads to be written optionlly as well.
 * This allows very fast call-response communication, with the responding radio never having to 
 * switch out of Primary Receiver mode to send back a payload, but having the option to if wanting
 * to initiate communication instead of respond to a commmunication.
 */
 


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

// Hardware configuration: Set up nRF24L01 radio on SPI bus plus pins 7 & 8 by default. I use 9 and 8 to get all pins on one connector
RF24 radio(9,8);

// Topology
const uint64_t pipes[2] = { 0xABCDABCD71LL, 0x544d52687CLL };              // Radio pipe addresses for the 2 nodes to communicate.

// Role management: Set up role.  This sketch uses the same software for all the nodes
// in this system.  Doing so greatly simplifies testing.  

typedef enum { role_ping_out = 1, role_pong_back } role_e;                 // The various roles supported by this sketch
const char* role_friendly_name[] = { "invalid", "Ping out", "Pong back"};  // The debug-friendly names of those roles
role_e role = role_pong_back;                                              // The role of the current running sketch

// A single byte to keep track of the data being sent back and forth
byte  counter =65;

void setup(){

  Serial.begin(57600);
  printf_begin();
  printf("\n\rRF24/examples/pingpairack. pins 9 and 8/\n\r");
  printf("ROLE: %s\n\r",role_friendly_name[role]);
  printf("*** PRESS 'T' to begin transmitting to the other node\n\r");

  // Setup and configure rf radio

  radio.begin();
  radio.setAutoAck(1);                    // Ensure autoACK is enabled
  radio.enableAckPayload();               // Allow optional ack payloads
  radio.setRetries(0,15);                 // Smallest time between retries, max no. of retries
  radio.setPayloadSize(1);                // Here we are sending 1-byte payloads to test the call-response speed
  radio.setDataRate(RF24_1MBPS);  
   radio.setPALevel(0);                   
  radio.openWritingPipe(pipes[1]);        // Both radios listen on the same pipes by default, and switch when writing
  radio.openReadingPipe(1,pipes[0]);
  radio.startListening();                 // Start listening
  radio.printDetails();                   // Dump the configuration of the rf unit for debugging
}

void loop(void) {

  if (role == role_ping_out){
    
    radio.stopListening();                                  // First, stop listening so we can talk.
        
    printf("Now sending %d as payload. ",counter);
    byte gotByte;  
    unsigned long time = micros();                          // Take the time, and send it.  This will block until complete   
                                                            //Called when STANDBY-I mode is engaged (User is finished sending)
    if (!radio.write( &counter, 1 )){
      printf("failed.\n\r");      
    }else{

      if(!radio.available()){ 
        printf("Blank Payload Received\n\r"); 
      }else{
        while(radio.available() ){
          unsigned long tim = micros();
          radio.read( &gotByte, 1 );
          printf("Got response %d, round-trip delay: %lu microseconds\n\r",gotByte,tim-time);
          counter++;
        }
      }

    }
    // Try again later
    delay(1000);
  }

  // Pong back role.  Receive each packet, dump it out, and send it back

  if ( role == role_pong_back ) {
    byte pipeNo;
     byte gotByte;                                       // Dump the payloads until we've gotten everything
    while( radio.available(&pipeNo))                    // Note radio.available gets pipenumber
    {
      radio.read( &gotByte, 1 );                        //
      radio.writeAckPayload(pipeNo,&gotByte, 1 );    
   }
 }

  // Change roles

  if ( Serial.available() )
  {
    char c = toupper(Serial.read());
    if ( c == 'T' && role == role_pong_back )
    {
      printf("*** CHANGING TO TRANSMIT ROLE -- PRESS 'R' TO SWITCH BACK\n\r");

      role = role_ping_out;                  // Become the primary transmitter (ping out)
      radio.openWritingPipe(pipes[0]);
      radio.openReadingPipe(1,pipes[1]);
    }
    else if ( c == 'R' && role == role_ping_out )
    {
      printf("*** CHANGING TO RECEIVE ROLE -- PRESS 'T' TO SWITCH BACK\n\r");
      
       role = role_pong_back;                // Become the primary receiver (pong back)
       radio.openWritingPipe(pipes[1]);
       radio.openReadingPipe(1,pipes[0]);
       radio.startListening();
    }
  }
}

[/code]
This is the only change I’ve made :-
// Hardware configuration: Set up nRF24L01 radio on SPI bus plus pins 7 & 8 by default. I use 9 and 8 to get all pins on one connector
RF24 radio(9,8);

cjcj1949:
I’ve tried your example. The rx gets the data correctly but the tx never gets the reply.

I missed this Reply earlier

I presume you are referring to the pair of programs in my my earlier link.

I will check them out again and get back to you.

…R

Yes. The train controller programs. I have worked on interprocessor comms before, but in the late 70s. LSI11 DEC.

I've looked on the Nordic forum and there is a reply from a Nordic engineer that states that the payload must be loaded before the PRX receives data. This does make sense as the SPI interface will have a large delay built in. It is not really useful though in terms of getting the most recent information back, as you need to do something( load the payload in the PRX) before data is received form the PTX.

cjcj1949: the payload must be loaded before the PRX receives data.

That seems a fairly obvious requirement.

It is not really useful though in terms of getting the most recent information back, as you need to do something( load the payload in the PRX) before data is received form the PTX.

The way I use it is to send data 10 times per second. That means the data in the ackPayload is a tenth of a second out of date. Faster is possible.

What is your requirement?

I use ackPayload as a simple alternative to the code that would be needed to make both devices change roles so the "receiver" can send back a message. But it is perfectly possible (and normal) to write code to cause that change of role.

I have still not had time to verify that my programs work. Will do that later today - dinner first :)

...R

I have now downloaded the pair of programs from my link and uploaded them to my 2 Unos and they worked just as expected.

If they are not working for you please post some of the output that they produce.

...R

Track Control Starting

RSLT 1 Data Sent 0

RSLT 1 Data Sent 2

RSLT 1 Data Sent 4

RSLT 1 Data Sent 6

RSLT 1 Data Sent 8

RSLT 1 Data Sent 10

RSLT 1 Data Sent 12 Acknowledge received: 17

RSLT 1 Data Sent 14 Acknowledge received: 18

RSLT 1 Data Sent 16 Acknowledge received: 19

RSLT 1 Data Sent 18 Acknowledge received: 20

RSLT 1 Data Sent 20 Acknowledge received: 21

As far as I know the data in Reply #10 suggests the program is working properly.

It is, perhaps, not as sensible as it could be and I will have a look to see if I can make it clearer.

The updated version is now here

...R

My original point was that I couldn't get the results expected by the example program pingpair_ack. It seems that the hardware does not do what the example program expects. The example program loads the payload after receiving it's data. This seems to work at 1Mb data rate, but more by luck than judgement. The data just gets in the TX buffer in time to prevent the ack from being transmitted. There should be a setup time, to guarantee payload transmission rather than ack transmission. I don't think ack payload is a useful mode, I'll stick with separate RX,TX. Thanks