nRF24 experts to help with code?

I have a project which uses two nRF24 for one-way communication. Currently it uses a PIC on each end to send/receive the data. Which works perfectly. However, I would like to swap out the Receiver PIC and swap in an ESP32 connected to a nRF24 and use the Arduino IDE.

I used the Arduino nRF24 "Getting Started" example with two ESP32's connected to a nRF24 each and got that working (so the hardware is confirmed), I modified the example program settings to match the existing PIC's nRF24 register setup code.

I have a B/B+ understanding of how to set up the nRF24. I know the transmitter works, but I can't seem to get a response from the nRF24 receiver. I expect it's something I don't understand regarding addressing, pipes, payload size, or...?

Here are (what I think are) the relevant info on the PIC's set registers code (I attached the full .c and .h, zip file):
uint8_t RXTX_ADDR[3] = { 0xB5, 0x23, 0xA5 }; //Randomly chosen address

WriteRegister(NRF_CONFIG, 0x0B); //1 uint8_t CRC, POWER UP, PRX
WriteRegister(EN_AA, 0x00); //Disable auto ack
WriteRegister(EN_RXADDR, 0x01); //Enable data pipe 0
WriteRegister(SETUP_AW, 0x01); //3 uint8_t address
WriteRegister(SETUP_RETR, 0x00); //Retransmit disabled
WriteRegister(RF_CH, 0x01); //Randomly chosen RF channel
WriteRegister(RF_SETUP, 0x26); //250kbps, 0dBm
WriteRegister(RX_PW_P0, 0x01); //RX payload = 1 uint8_t

WriteAddress(RX_ADDR_P0, 3, RXTX_ADDR);
WriteAddress(TX_ADDR, 3, RXTX_ADDR);

//--------------------
Arudio Code Example Changes - (I attached the full program, zip file)
//--------------------

#define ce 4 //for ESP32
#define csn 5 //for ESP32

// instantiate an object for the nRF24L01 transceiver
RF24 radio(ce, csn); // using pin 7 for the CE pin, and pin 8 for the CSN pin

// Let these addresses be used for the pair
//uint8_t address[][6] = {"1Node", "2Node"};
uint8_t address[][6] = { 0xB5, 0x23, 0xA5, 0xB5, 0x23, 0xA5 }; //match PIC

void customSetup(){
radio.setAddressWidth( 3 ); //Match PIC
radio.setPayloadSize(1); //Match PIC
radio.setDataRate( RF24_250KBPS ); //Match PIC
radio.setChannel( 0x01 ); //Match PIC
radio.setAutoAck( false ); //Match PIC
}

Setup changes:

customSetup();

// save on transmission time by setting the radio to only transmit the
// number of bytes we need to transmit a float
// radio.setPayloadSize(sizeof(payload)); // float datatype occupies 4 bytes
radio.setPayloadSize( 1 ); //Match PIC

Loop changes:
// set the RX address of the TX node into a RX pipe
// radio.openReadingPipe(1, address[!radioNumber]); // using pipe 1
//*************************************************************
radio.openReadingPipe(1, address[radioNumber]); // using pipe 1 - not sure about pipes, etc... tried to match PIC
//**************************************************************

If anyone is willing to take a look at my code. It would be greatly appreciated! Thanks in advance...PIC-ESP32-Aduino files.zip (7.4 KB)

Try these 2 bare minimum sketches

Tx

//See http://tmrh20.github.io/RF24 for all documentation

#include <RF24.h>

const byte CE_PIN = 9;
const byte CSN_PIN = 10;

RF24 radio(CE_PIN, CSN_PIN);

const uint64_t pipe = 123456;
struct dataLayout
{
  byte aByte;
  int someInts[2];
  char someChars[20];
} dataPacket;

void setup()
{
  Serial.begin(115200);
  while (!Serial);
  radio.begin();
  radio.setPALevel(RF24_PA_MAX); //max power
  radio.setDataRate(RF24_250KBPS);  //low data rate
  radio.openWritingPipe(pipe);
  Serial.print("Transmitting at PA level ");
  Serial.println(radio.getPALevel());
}

void loop()
{
  dataPacket.someInts[0]++;
  dataPacket.someInts[1]--;
  sprintf(dataPacket.someChars, "Count : %d", dataPacket.someInts[0]);
  radio.write(&dataPacket, sizeof(dataPacket));
  Serial.println(dataPacket.someChars);
  delay(1000);
}

Rx

//See http://tmrh20.github.io/RF24 for all documentation

#include <RF24.h>

const byte CE_PIN = 9;
const byte CSN_PIN = 10;

const byte ledPin = A5;
boolean ledState = false;

RF24 radio(CE_PIN, CSN_PIN);

const uint64_t pipe = 123456;
struct dataLayout
{
  byte aByte;
  int someInts[2];
  char someChars[20];
} dataPacket;

void setup()
{
  Serial.begin(115200);
  while (!Serial);
  pinMode(ledPin, OUTPUT);
  radio.begin();
  radio.setDataRate(RF24_250KBPS);  //low data rate
  radio.openReadingPipe(1, pipe);
  radio.startListening();
  Serial.println("Listening");
}

void loop()
{
  if (radio.available())
  {
    radio.read(&dataPacket, sizeof(dataPacket));
    Serial.print(dataPacket.someInts[0]);
    Serial.print("\t");
    Serial.print(dataPacket.someInts[1]);
    Serial.print("\t");
    Serial.println(dataPacket.someChars);
    ledState = !ledState;
    digitalWrite(ledPin, ledState);
  }
}

Do they work on your system ?

The PIC code is quite interesting in that it is very close to the datasheet and is directly manipulating the NRF24L01+ registers.
The Arduino library is a level above that and therein lies one problem. For example, this is what it says about optional configurators: "Calling begin() sets up a reasonable set of defaults." which is a bit vague so you have to drill down to find these defaults to ensure they match the PIC settings.

Here is an example where they don't match. It is the CRC encoding:

In the PIC code, you have for the initialisation :

WriteRegister(NRF_CONFIG, 0x0B);     //1 uint8_t CRC, POWER UP, PRX

Which, from the both the comment and data sheet register description, implies CRC (1byte) encoding. In the Arduino library, in the begin() method, you have something similar, but there a 2 byte CRC encoding is specified:

    // Clear CONFIG register:
     //      Reflect all IRQ events on IRQ pin
     //      Enable PTX
     //      Power Up
     //      16-bit CRC (CRC required by auto-ack)
     // Do not write CE high so radio will remain in standby I mode
     // PTX should use only 22uA of power
     write_register(NRF_CONFIG, (_BV(EN_CRC) | _BV(CRCO)) );
     config_reg = read_register(NRF_CONFIG);

That is at least one issue you have to address, in this case using the setCRCLength() method.

Thanks for your reply! Yes that worked perfectly with the exception of
changing the ce/csn pins to my hardware
const byte CE_PIN = 4; //esp32
const byte CSN_PIN = 5;//esp32

And "pipe" seems to be reservered? "myPipe" worked fine.
const uint64_t myPipe = 123456;
radio.openWritingPipe(myPipe);

The solution to my problem was that I was using 8bit CRC on the PIC, whereas the Arduino library defaults to 16bit CRC. My problem is solved, but thank you for suggesting this code. It's perfect to use as a hardware test.

Thank you! Yes that was the one thing I didn't check...
radio.setCRCLength( RF24_CRC_8 ); And data started streaming immediately!
thanks.

I'm pleased it was so simple. I'll add links to the documentation I used, in case someone else attempts something similar:

data sheet for the NRF24L01+

documentation for the Arduino RF24 library by TMRh20 :
https://nrf24.github.io/RF24/classRF24.html

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