RF24 Debugging

Hi all,

I'm having issues with two RF24 modules (NRF24L01+PA+LNA versions) and hoping to get some feedback with regards to diagnostic messages (in particular what the STATUS elements of printDetails should be or means) or tests I can do. To keep things compact I've attached the codes and Serial Output .JPG.

I have a transmitter running on an Arduino Pro Mini (based on https://howtomechatronics.com/projects/diy-arduino-rc-transmitter/) and receiver on the Arduino Mega 2560 Rev3 through a module base.
I have done a pin-out with a voltmeter to validate connections, and know the RF24 modules are getting 3.3 V to 3.6 V at over 150 mA (max just shy of 200 mA).
I have noticed however that both modules seem to have the MOSI pin high and MISO low, despite one being in receive and one in transmit, I might be wrong but the transmitter should have the MOSI high and receiver MISO high for the SPI protocol.

The transmitter is using the connections:
Power through a voltage regulator from x2 Li-ion batteries with x2 10 uF capacitors pre and post regulator
MOSI: 11
MISO: 12
SCK: 13
CE: 5
CSN: 6

The receiver is using the connections:
Power through the Arduino 5V pin with the module base having a voltage regulator and capacitors
MOSI: 51
MISO: 50
SCK: 52
CE: 44
CSN:45

I've tried to minimise power consumption through settings and be very specific about communication channels/addresses (having tried being minimalist with the default settings and not getting anywhere), yet still, I can't communicate between the two, and I've tried countless examples, i.e. like the ping pong getting started example.

One thing I'd be particularly keen to know is if there is a way to check if a message has even been sent or can even be sent based on a function call or diagnostics as at the moment either something is wrong in the code that I can't see or I am erring on the side of hardware damage.
Additionally are there any hardware-specific code adaptions needed to implement on the hardware I am using.

Thanks in advance!

RF24_H2M_Transmit_HelloWorld.ino (924 Bytes)

RF24_H2M_Receive_HelloWorld.ino (957 Bytes)

Pinout-Mega2560rev3_latest.pdf (506 KB)

Have a look at this Simple nRF24L01+ Tutorial.

Wireless problems can be very difficult to debug so get the wireless part working on its own before you start adding any other features.

The examples are as simple as I could make them and they have worked for other Forum members. If you get stuck it will be easier to help with code that I am familiar with. Start by getting the first example to work

There is also a connection test program to check that the Arduino can talk to the nRF24 it is connected to.

A common problem with nRF24 modules is insufficient 3.3v current from the Arduino 3.3v pin. This seems to be a particular problem with the nano. The high-power nRF24s (with the external antenna) will definitely need an external power supply. At least for testing try powering the nRF24 with a pair of AA alkaline cells (3v) with the battery GND connected to the Arduino GND.

If you are using the high-power nRF24s (with the external antenna) it may help to have a distance of about 3 metres between the two nRF24s so that the signal does not overwhelm the receiver. However someone on the Forum has had them working without that separation - I don't have any personal experience with them. If you are new to nRF24s it may be better to start with a pair of low power modules with the pcb antenna.

...R

srance:
I have noticed however that both modules seem to have the MOSI pin high and MISO low, despite one being in receive and one in transmit, I might be wrong but the transmitter should have the MOSI high and receiver MISO high for the SPI protocol.

The SPI protocol relates to how the microcontroller talks to the SPI device; which could be a sensor, memory or perhaps even a radio transmitter.

Whether the SPI device is a radio receiver or transmitter is not relavent.

I just thought I'd add in regards to the two comments.

Firstly in response to srnet with regards to SPI, my understand under the nRF24L01 configuration usage:

  • MOSI indicates data transmitted from the microcontroller (master) to nRF24L01 (slave) - i.e. transmitter
  • MISO indicates data transmitted from the nRF24L01 (slave) to the microcontroller (master) - i.e. receiver
    This would mean in a one-way set-up my transmitter should have MOSI high and receiver should have MISO high.
    My question is why am I seeing both MOSI high under this set-up
    Reference: NRF24L01 RF Module Pinout, Arduino Examples, Applications, Features

Secondly in response to Robin2:

I have got both modules as far as they can go (limited by USB length) which is about 2 metres.

Power-wise:

  • My transmitter (Arduino Pro Mini) has a 10uF capacitor over the 3.3V which is fed through a voltage regulator (also with a 10uF capacitor) power by x2 18650 Li-ion (3.7V) batteries with a common ground to the USB supply (normally this would also power the Pro Mini when in normal use), which are currently giving around 8V as they are fully charged. Currently I have the PC USB and Li-ion (needed to power nRF24L01) are both on at the moment so now quite sure how the Pro Mini itself it handling the RAW 8V and the 5V Vcc.
  • The receiver (Arduino Mega 2560) is powered from the 5V feed with Arduino supply currently via USB) with the nRF24L01 sitting on a header with a voltage regulator and capacitor, though not sure of the exact value.

I have reviewed your tutorials (very handy), though I still have issues.
I've combined both the one-way and connection test in the below scripts - with a few tweaks that just help me.
One thing that has struck me is that the radio.write state is always 0, I have tried this on both Arduinos as well.
I have also attached the scripts and Serial outputs a jpg.
I've also attached a table of pin states as nowhere have I found anything talking about the voltage or response of the pins.

  • Firstly is my connection okay from the NRF serial output perspective?
  • Are the power supplies suitable?
  • Furthermore, do you have expectations as to the voltage all SPI pins?
  • Is there anything from the script standing out as wrong

Transmitter:

// SimpleTx - the master or the transmitter

// Libraries
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#include <printf.h>

// Define Radio Pins
// Arduino Pro Mini
// MISO = 12 || MOSI = 11 || SCK = 13
#define CE_PIN  5
#define CSN_PIN 6
/*
// Arduino Mega 2560
// MISO = 50 || MOSI = 51 || SCK = 52
#define CE_PIN  44
#define CSN_PIN 45
*/

// Radio Set-up
const byte slaveAddress[5] = {'R','X','A','A','A'};
RF24 radio(CE_PIN, CSN_PIN); // Create a Radio

// Radio Message Set-up
char dataToSend[10] = "Message 0";
char txNum = '0';

// Transmission Timing
unsigned long currentMillis;
unsigned long prevMillis;
unsigned long txIntervalMillis = 1000; // send once per second

//====================

void setup(){
  // Serial Set-up
  Serial.begin(9600);
  delay(1000);
  printf_begin();
  delay(1000);
  Serial.println("SimpleTx Starting");
  Serial.println();

  // Radio Set-up
  radio.begin();
  Serial.println("Radio Initial Status");
  Serial.println();
  radio.printDetails();
  Serial.println();
  delay(1000);
  radio.setDataRate(RF24_250KBPS);    // Fast enough.. Better range
  radio.setPALevel(RF24_PA_MIN);
  radio.setChannel(108);              // 2.508 Ghz - Above most Wifi Channels
  radio.setRetries(3,15);             // setRetries(delay,count) - max 15 for both delay and count
  // delay: How long to wait between each retry, in multiples of 250us, max is 15. 0 means 250us, 15 means 4000us. 
  // count: How many retries before giving up, max 15 
  radio.openWritingPipe(slaveAddress);
  radio.stopListening();
  Serial.println("Radio Configured Status");
  Serial.println();
  delay(1000);
  radio.printDetails();
  Serial.println();
  delay(1000);
}

//====================

void loop() {
  currentMillis = millis();
  if (currentMillis - prevMillis >= txIntervalMillis) {
    send();
    prevMillis = millis();
  }
}

//====================

void send(){
  bool rslt;
  rslt = radio.write(&dataToSend,sizeof(dataToSend));
  // Always use sizeof() as it gives the size as the number of bytes.
  // For example if dataToSend was an int sizeof() would correctly return 2

  Serial.print("Data Sent: ");
  Serial.print(dataToSend);
  Serial.print(" || Transmission Status: ");
  Serial.print(rslt);
  Serial.print(" - ");
  if(rslt){
    Serial.println("Acknowledge received");
    updateMessage();
  }
  else{
    Serial.println("Tx failed");
  }
}

//====================

void updateMessage(){
  // so you can see that new data is being sent
  txNum += 1;
  if(txNum > '9'){
    txNum = '0';
  }
  dataToSend[8] = txNum;
}

//====================

Receiver:

// SimpleRx - the slave or the receiver

// Libraries
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#include <printf.h>

// Define Radio Pins
/*
// Arduino Pro Mini
// MISO = 12 || MOSI = 11 || SCK = 13
#define CE_PIN  5
#define CSN_PIN 6
*/
// Arduino Mega 2560
// MISO = 50 || MOSI = 51 || SCK = 52
#define CE_PIN  44
#define CSN_PIN 45

// Radio Set-up
const byte thisSlaveAddress[5] = {'R','X','A','A','A'};
RF24 radio(CE_PIN, CSN_PIN);

// Radio Message Set-up
char dataReceived[10]; // this must match dataToSend in the TX
bool newData = false;

//====================

void setup(){
  // Arduino Mega 2560 Set-up
  pinMode(53,OUTPUT);
  
  // Serial Set-up
  Serial.begin(9600);
  delay(1000);
  printf_begin();
  delay(1000);
  Serial.println("SimpleRx Starting");
  Serial.println();

  // Radio Set-up
  radio.begin();
  Serial.println("Radio Initial Status");
  Serial.println();
  radio.printDetails();
  Serial.println();
  delay(1000);
  radio.setDataRate(RF24_250KBPS);    // Fast enough.. Better range
  radio.setPALevel(RF24_PA_MIN);
  radio.setChannel(108);              // 2.508 Ghz - Above most Wifi Channels
  radio.openReadingPipe(0,thisSlaveAddress);
  radio.startListening();
  Serial.println("Radio Configured Status");
  Serial.println();
  delay(1000);
  radio.printDetails();
  Serial.println();
  delay(1000);
}

//====================

void loop(){
  getData();
  showData();
}

//====================

void getData(){
  newData = false;  // Ensures acknowledgement is repeatedly check rather than carried over
  if(radio.available()){
    radio.read(&dataReceived,sizeof(dataReceived));
    newData = true;
  }
}

//====================

void showData(){
  if(newData == true){
    Serial.print("Data received ");
    Serial.println(dataReceived);
    newData = false;
  }
}

//====================

SimpleRX_Original_Mod.ino (1.89 KB)

SimpleTX_Original_Mod.ino (2.63 KB)

srance:
I've combined both the one-way and connection test in the below scripts

Wireless problems are sufficiently difficult to debug without making the programs more complex. The whole purpose of my Tutorial is to keep everything separate.

You are, of course, free to do as you please.

...R

srance:

  • MOSI indicates data transmitted from the microcontroller (master) to nRF24L01 (slave) - i.e. transmitter
  • MISO indicates data transmitted from the nRF24L01 (slave) to the microcontroller (master) - i.e. receiver
    This would mean in a one-way set-up my transmitter should have MOSI high and receiver should have MISO high.

That is a total misunderstanding of the SPI protocol, which is always bidirectional.
For any bit sent, there will be one received.

Get a cheap logic analyzer and have a closer look at the transactions.

srance:
Firstly in response to srnet with regards to SPI, my understand under the nRF24L01 configuration usage:

  • MOSI indicates data transmitted from the microcontroller (master) to nRF24L01 (slave) - i.e. transmitter
  • MISO indicates data transmitted from the nRF24L01 (slave) to the microcontroller (master) - i.e. receiver
    This would mean in a one-way set-up my transmitter should have MOSI high and receiver should have MISO high.
    My question is why am I seeing both MOSI high under this set-up
    Reference: NRF24L01 RF Module Pinout, Arduino Examples, Applications, Features

You do indeed completly missunderstand how SPI works.

Last post on this as it is now working.

So I went back and did the ping pong demo that's in the RF24 library and found when I set both NRF24L01+ modules to the transmitter setting, I was getting some communication.
A bit more playing with the RX/TX and found my Arduino Pro Mini was perfectly fine but the Arduino Mega 2560 was only transmitting and couldn't receive.

This seemed weird so found a thread talking about a similar issue with Megas only supporting transmission and not receiving. This suggested not using the NRF24L01+ base module and 5V pin and instead use some high capacitance capacitors and the 3.3V pin (Problem with Nrf24L01+ and arduino mega - Networking, Protocols, and Devices - Arduino Forum).
So I've stuck x4 100uF capacitors in parallel and that has workedwith no changes to my code.

My best guess is that the capacitor that's on the base module that you can buy with the antennas just isn't enough when used with a Mega to ensure sufficiently smooth power supply from the 5V pin after the voltage regulator.
This also explains why I don't have an issue with my Pro Mini as its antenna is powered from a Lipo and not through the board.