Read nrf24L01+ register

Hello,

I am communicating between two arduino's using 2 nrf24l01+ modules. I've basically got it working but want to get some additional info of the modules. This information is located in the module register.

This library is used to read data out of the register:

void Nrf24l::readRegister(uint8_t reg, uint8_t * value, uint8_t len)
// Reads an array of bytes from the given start position in the MiRF registers.
{
    csnLow();
    Spi.transfer(R_REGISTER | (REGISTER_MASK & reg));
    transferSync(value,value,len);
    csnHi();
}

and this is an example of a register read:

uint8_t Nrf24l::getStatus(){
      uint8_t rv;
      readRegister(STATUS,&rv,1);
      return rv;
}

Complete library: Arduino Playground - HomePage

I would like to read some RF_SETUP information out of the register:

http://www.nordicsemi.no/files/Product/data_sheet/nRF24L01P_Product_Specification_1_0.pdf

See page: 58

The RF_SETUP information is stored into one byte (correct me if I am wrong!!). but how do I print for example the RF_PWR value (2 bits)?

This is what I have tried in my Sketch

byte rv;
  Mirf.readRegister(RF_SETUP, &rv, 8);
  Serial.print(rv);

But this prints rubbish....

The problem is I don't know what length to choose? Now I have tried 8. And how do I print this value correct?

Anyone who knows how this stuff works?

Thanks in advance.

/me

But this prints rubbish.

What sort of rubbish? It looks like you will be printing out the ASCII code of what ever string you are receiving.

It prints, Chr =157 for example.

The problem is I don't know what length to choose in the readRegister void. What is the function of the length parameter?

As far as I know the parameters are represented as bits (1 or 0). RF_SETUP contains one byte, so 8 bits. And how can I visually represent the byte as one's and zero's?

Serial.print(rv, BIN)

If rv is one byte why should I choose a length?

/me

If rv is one byte why should I choose a length?

I think it wants the length in bytes. So for a two byte value use a length of 2. Or access the two bytes separately into separate byte variables.

uint8_t rv1, ry2;
readRegister(BYTE1,&rv1,1);
readRegister(BYTE2,&rv2,1);
Where BYTE1 and BYTE2 are the addresses of what you want to read.

but how do I print for example the RF_PWR value (2 bits)?

I would try:-
uint8_t rv;
readRegister(RF_PWR,&rv,1); // assuming RF_PWR has been defined in the headers
ry = ry >> 1; // move down the two bits into the least significant bits
then
Serial.print(ry & 0x3, BIN); // will just print the two bits

Sorry but I am pretty new into this bitwise stuff so I have the following:

In the header file of the library is the following coded concerning the RF Setup Register:

/* Memory Map */
#define RF_SETUP    0x06

/* Bit Mnemonics */
#define RF_PWR      1

Isn't is so (according to the datasheet, page 58) that this register (RF Setup Register) consists out of 8 bits (one byte) and contains the following parameters:

Bit 0 = Obsolete
Bit 1:2 = RF_PWR
Bit 3 = RF_DR_HIGH and the Bit Mnemonics = 1 (So I this this means that it start at) bit 1.
Bit 4 = PLL_LOCK
Bit 5 = RF_DR_LOW
Bit 6 = Reserved
Bit 7 = CONT_WAVE

You are talking about bytes, and that confuses me.

Maybe it is better to try to start with reading the whole RF Setup Register? I would like to see the 8 bits.

I would have thought that the readRegister() function returns a pointer to a byte quantity. It is almost unheard of to return bits. So you get all the bits in a byte back. If you want to isolate bits you have to use bit manipulation.
You need to read and understand this:-
http://www.arduino.cc/playground/Code/BitMath

Well I am not sure (I am not really well know into this registry stuff). I've read the datasheet but I can't figure out how to interpret the data?

The library comment on the readRegistery function says:

void Nrf24l::readRegister(uint8_t reg, uint8_t * value, uint8_t len)
// Reads an array of bytes from the given start position in the MiRF registers.
{
    csnLow();
    Spi.transfer(R_REGISTER | (REGISTER_MASK & reg));
    transferSync(value,value,len);
    csnHi();
}

Here is says it read an array of bytes.... I am lost.....

Here is says it read an array of bytes.

Yes that's what I said. The length parameter is the number of bytes not as you thought the number of bits.
It is best if you read them one byte at a time like you have been doing and then you can isolate the bits you need to know about with the logical and operation (symbol &).
It is not registry stuff it is simply bits that have significance rather than collections of bits represented as numbers. Take the power we were discussing earlier, bits 1 and 2 represented the power with bit 0 unused. I shifted the bits along one place to the right with the shift operator >> to get rid of bit 0 and removed the other bits we were not interested in with the and operator ( & 0x3) to leave nothing but the two bits that represented power. You can then print that out as a number in hex, binary or decimal.

Maybe it is better to try to start with reading the whole RF Setup Register? I would like to see the 8 bits.

JR,

This is Nathan from MrRoot.net. I got your comment. I understand what you’re trying to do so I threw together a bit of sample code for you to consider:

/**
 * Pins:
 * Hardware SPI:
 * MISO -> 12
 * MOSI -> 11
 * SCK -> 13
 *
 * Configurable:
 * CE -> 8
 * CSN -> 7
 */

#include <Spi.h>
#include <mirf.h>
#include <nRF24L01.h>

void setup() {
  Serial.begin(9600);
  Serial.println( "Starting wireless..." );

  // Setup
  Mirf.init();
  Mirf.setRADDR((byte *)"clie1");
  Mirf.payload = sizeof(unsigned long);
  Mirf.config();
  
  // Read and print RF_SETUP
  byte rf_setup = 0;
  Mirf.readRegister( RF_SETUP, &rf_setup, sizeof(rf_setup) );
  Serial.print( "rf_setup = " );
  Serial.println( rf_setup, BIN );

  Serial.println( "Wireless initialized!" );
}

void loop() {}

You were doing just about everything correctly. To answer your question on the register map, yes, that particular register is 1 byte in size, so you only need to send 1 as the length argument for the readRegister function. The sizeof(rf_setup) is a common way of reading only the right amount of data that will fit into your variable ( rather than guessing the size of the variable ).

When I ran this code on my board, it printed:

Starting wireless...
rf_setup = 1111
Wireless initialized!

So that’s 00001111 for the value of RF_SETUP. Breaking it down, high bit to low bit:

0 - No continuous carrier wave
0 - Reserved - must be 0
0 - RF_DR_LOW is 0
0 - No PLL lock signal
1 - RF_DR_HIGH is 1, and according to chart, 01 = 2 Mbps
1 - High bit RF_PWR is 1
1 - Low bit RF_PWR is 1, according to chart, 11 = 0 dBm output power
1 - Not used/obsolete

Now, using that handy tutorial Grumpy_Mike suggested on bitwise math, if you wanted to display the information a little more clearly, you could yank out the specific bits you’re interested in and print messages like “RF Settings: 2 Mbps, 0dBm”.

I hope that helps! Best of luck!

Cheers,
Nathan

Hi Nathan,

Thanks for your fast reply!! Good to hear that all data is stored into one byte. I really got the feeling: So close but yet so far....

But now I am back in business :slight_smile:

Great to see that you solved my mystery problem. Maybe it is a good idea to include some readRegister, configRegister and writeRegister actions into the included examples. Just to clarify the usage of the code to the users. The code can actually be between:

/...../ to make it inactive.

I'll study the bitwise math tutorial to reveal the zero's and to make the code work for me (practically).

Maybe it is time to introduce your modified library to the community!!

Cheers,

/me

Hey!

Glad it worked for you. I’ve been out of touch with my electronics hobby for several months - been busy with work and what not. I do need to email those guys that run the playground and let them know about the updated library. :slight_smile: Let me know if you have any other questions.

Cheers,
Nathan