NRF24l01 Reading a Register. Avoiding "private within this context" Message

My goal is to store the number of Tx "retries" in a variable. The Nordic data sheet describes a read-only register called PLOS_CNT which contains the number of retries. I am trying to read that register. Does anyone know how to accomplish this?

FAILURE INFO
I am using the tmrh20 RF24 library, which has a class reference document that refers to a protected member function called read_register(). But being a protected member function it causes the Arduino IDE to say:

uint8_t RF24::read_register(uint8_t, uint8_t*, uint8_t)' is private within this context

The RF24 Class documentation says this about "protected member functions":

Regular users cannot ever call these. They are documented for completeness and for developers who may want to extend this class.

My code:

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#define CE_PIN   9
#define CSN_PIN 10
 
int potRead; //
uint8_t ploss; //packet loss
const byte slaveAddress[5] = {0x52,0x78,0x41,0x41,0x41};

RF24 radio(CE_PIN, CSN_PIN); 

void setup() {
    radio.begin(); //
    radio.setDataRate( RF24_250KBPS ); 
    radio.setRetries(3,5); 
    radio.openWritingPipe(slaveAddress);
   
}

void loop() {

  potRead=(analogRead(A0));
      radio.write(&potRead, sizeof(potRead));
      radio.read_register(PLOS_CNT, ploss, 2);
      delay(50);
 }

Class pages:

For reading a chunk from a register

For reading a byte from a register

Any solution to reading the PLOS_CNT register or a tmrh20/RF24 public class for accessing the PLOS_CNT value would be greatly appreciated.

Thanks,

Dan
San Jose

Can't you just count the number of times that radio.write() is unsuccessful ?

Pseudo code;

#define CSN_PIN 10
#define CMD_R_REGISTER      0x00

uint8_t readRegister(uint8_t reg)
{
  uint8_t result;

  digitalWrite(CSN_PIN, LOW);
  SPI.transfer(CMD_R_REGISTER | reg);
  result = SPI.transfer(0xff);
  digitalWrite(CSN_PIN, HIGH);
  return result;
}

True, but I would benefit from leaning how to reach into peripherals to read and manipulate registers. Second reason is battery life.

srnet, thank you so much for the pseudo code!!

Following is a question about it. Patience with my C-plussplusslessness is appreciated!

SPI.transfer(CMD_R_REGISTER | reg);

Is this possibly both an instruction and a memory address packaged into the same byte? ( I ask this because in the NRF24L01.h it identifies Instructions in a range of 1F and higher, where memory locations are 1D and Lower. Seems possible.

Thanks for reading! And thanks for any comments or corrections.

Dan
San Jose

I was able to get srnet's code working to read the OBSERVE_TX register. However I am now stalled on an issue with the returned value.

INFO:
OBSERVE_TX contains two values:
7~4 PLOS_CNT (packets lost since switching to the current channel. Resets on next channel change.
3~0 ARC_CNT (number of retries for the current transmission. Resets to zero on next Tx.

Turns out ARC_CNT is the one I want, not PLOS_CNT.

srnet's code allowed me to read the OBSERVE_TX register in the radio. Glory.

uint8_t readRegister(uint8_t reg)
{
  uint8_t result;

  digitalWrite(CSN_PIN, LOW);
  SPI.transfer(R_REGISTER | reg);
  result = SPI.transfer(0xff);
  digitalWrite(CSN_PIN, HIGH);
  return result;
}

With PRX powered on it always returned 0 as expected. With PRX turned off, the function outputs a number that starts at zero and rises (it's counting failures - great!) skipping numbers, to 240 ( 0b11110000. And will only reset with a power off reset, as expected from the datasheet. However, the lower nibble is inactive. I figured the re-transmits were constantly resetting the lower nibble / ARC_CNT to check this I masked the byte

result = (result && 0b00001111);

With PRX functioning properly, it is always a 0, as expected. With the PRX unplugged, it rises to 1, never more, and never resets to zero... even after the PRX is plugged back in. I suspect I am failing to update something - BUT, why is it not going to 3 (the max number of retries?)

Full Code:


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

#define CE_PIN   9
#define CSN_PIN 10
int jitter = 2; // permissable jitter / drift on the pot
int dataToSend;
int potRead; //
int oldPotRead;//
uint8_t ploss; //packet loss
const byte slaveAddress[5] = {0x52,0x78,0x41,0x41,0x41};
int ackMessg[2];
byte ackMessgLen = 2;

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

void setup() {
  Serial.begin(9600);
    pinMode(3, OUTPUT);
    radio.begin(); 
    radio.setDataRate( RF24_250KBPS ); 
    radio.setRetries(3,5); // delay, count
     radio.enableAckPayload();
    radio.openWritingPipe(slaveAddress);
    radio.setChannel(62);
    Serial.println("on");
    oldPotRead=(analogRead(A0));

    
}

void loop() {

potRead=(analogRead(A0));
  if (abs(potRead - oldPotRead) >= jitter )
  {   oldPotRead = potRead;
      radio.write(&potRead, sizeof(potRead));      
      if ( radio.isAckPayloadAvailable() ) {
             radio.read(ackMessg,ackMessgLen);
                 Serial.println(ackMessg[0]);
                
 }
 delay(3);
ploss = readRegister(0x08); 
Serial.println(ploss);
        }
     
                 
 }//end main loop
 



uint8_t readRegister(uint8_t reg)
{
  uint8_t result;

  digitalWrite(CSN_PIN, LOW);
  SPI.transfer(R_REGISTER | reg);
  result = SPI.transfer(0xff);
  result = (result && 0b00001111);
  digitalWrite(CSN_PIN, HIGH);
  return result;
}

Clearly it is, since the code works, it was taken from a larger program that prints out the NRF24 registers.

You are using a "logical AND" instead of a binary AND

result = (result & 0b00001111);

or

result = (result & 0x0F);

Thank you srnet and hzrnbgy. Everything works!

Euphoria!

Dan

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