NRF24L01 - Noob can't get any program to work

Hey folks,
I've been struggling for a few weeks now to get the NRF24l01 to work with no luck. I've tried many different programs and libraries and still no success at all. For now, I am trying to get the "Getting Started" (GitHub - nRF24/RF24: OSI Layer 2 driver for nRF24L01 on Arduino & Raspberry Pi/Linux Devices) code to function. Using the same libraries that came with the download.

  1. Using two Unos that seem to work fine with non-radio programing
  2. Have tried 10uF Cap soldered across Vcc and Gnd with Vcc at 3.3v.
  3. Now using the base modules for the NRF24, hooking the base modules into 5v.
  4. Using the TRmRH20 pinout (see below)
  5. baud rate at 115200

Pinout (using base module):
NRF24L01 Arduino
GND GND
VCC 5V
CE 7
CSN 8
SCK 13
MOSI 11
MISO 12
IRQ not used

Results - the receiving radio continuously scrolls sending mostly "Sent response 0" and occasionally it will send a number. Weirdly, if i unplug the nrf24 power on the radios, nothing changes. Frustrated and confused. Any help is greatly appreciated.

Waxhead

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, but am still getting similar issues:

Typical output from send unit: "RSLT (1 = success) 0 Data Sent 138 139"

The send unit keeps incrementing the "Data Sent" numbers, but i always get "0" - I assume that means no success.

Constant scrolling of "Data received Number0 0 Number1 0" on the receive side

I did have to change one line of code from "#include <RF24L01.h>" to "#include <nRF24L01.h>" in order to get it to compile, is this an indication of my problem?

Had previously been through the tutorial you linked, that is where i got the idea for the capacitors and base module.

Went ahead and completely deleted my downloaded libraries, and used the ones you linked to, no change.

Thanks for pointing out the missing 'n'. I have corrected my demo. It would not be the cause of your problem.

Can you make a pencil diagram showing how you have everything connected and post a photo of the diagram.

Have you a 10 µF capacitor across Vcc and GND for the nRF24s ? I have found that is essential in some of my projects.

It would also help my confidence if you post the exact code that YOU are using.

...R

The user's sketch does not need to add the "#include <nRF24L01.h>" line as it's already contained in the .CPP file. You only need these two lines.

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

Attachment is a diagram of the setup. I believe the 10uf cap is unnecessary if using the base module (it presumably is a voltage regulator). Exact code i am using is below.


// TrackControl - the master or the transmitter

// http://tmrh20.github.io/RF24/

//~ - CONNECTIONS: nRF24L01 Modules See:
//~ http://arduino-info.wikispaces.com/Nrf24L01-2.4GHz-HowTo
//~ 1 - GND
//~ 2 - VCC 3.3V !!! NOT 5V
//~ 3 - CE to Arduino pin 9
//~ 4 - CSN to Arduino pin 10
//~ 5 - SCK to Arduino pin 13
//~ 6 - MOSI to Arduino pin 11
//~ 7 - MISO to Arduino pin 12
//~ 8 - UNUSED

#include <SPI.h>
//~ #include <TMRh20nRF24L01.h>
//~ #include <TMRh20RF24.h>
#include <nRF24L01.h>
#include <RF24.h>

#define CE_PIN 9
#define CSN_PIN 10

// NOTE: the "LL" at the end of the constant is "LongLong" type
// These are the IDs of each of the slaves
const uint64_t slaveID[2] = {0xE8E8F0F0E1LL, 0xE8E8F0F0E2LL} ;

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

int dataToSend[2];

unsigned long currentMillis;
unsigned long prevMillis;
unsigned long txIntervalMillis = 1000;
int txVal = 0;
int ackMessg[6];
byte ackMessgLen = 4; // NB this 4 is the number of bytes in the 2 ints that will be recieved

void setup() {

Serial.begin(115200);
Serial.println("Track Control Starting");
radio.begin();
radio.setDataRate( RF24_250KBPS );
radio.enableAckPayload();
radio.setRetries(3,5); // delay, count
}

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

void loop() {

currentMillis = millis();
if (currentMillis - prevMillis >= txIntervalMillis) {

radio.openWritingPipe(slaveID[0]); // calls the first slave
// there could be a FOR loop to call several slaves in turn
dataToSend[0] = txVal; // this gets incremented so you can see that new data is being sent
txVal += 1;
dataToSend[1] = txVal;
txVal += 1;
bool rslt;
rslt = radio.write( dataToSend, sizeof(dataToSend) );
Serial.print("\nRSLT (1 = success) ");
Serial.println(rslt);
Serial.print("Data Sent ");
Serial.print(dataToSend[0]);
Serial.print(" ");
Serial.println(dataToSend[1]);
if ( radio.isAckPayloadAvailable() ) {
radio.read(ackMessg,ackMessgLen);
Serial.print("Acknowledge received: ");
Serial.print(ackMessg[0]);
Serial.print(" ");
Serial.println(ackMessg[1]);
}
prevMillis = millis();
}
}


// HandController - the slave or the receiver

// http://tmrh20.github.io/RF24/

//~ - CONNECTIONS: nRF24L01 Modules See:
//~ http://arduino-info.wikispaces.com/Nrf24L01-2.4GHz-HowTo
//~ 1 - GND
//~ 2 - VCC 3.3V !!! NOT 5V
//~ 3 - CE to Arduino pin 9
//~ 4 - CSN to Arduino pin 10
//~ 5 - SCK to Arduino pin 13
//~ 6 - MOSI to Arduino pin 11
//~ 7 - MISO to Arduino pin 12
//~ 8 - UNUSED

#include <SPI.h>
//~ #include <TMRh20nRF24L01.h>
//~ #include <TMRh20RF24.h>
#include <nRF24L01.h>
#include <RF24.h>

#define CE_PIN 9
#define CSN_PIN 10

// NOTE: the "LL" at the end of the constant is "LongLong" type

const uint64_t deviceID = 0xE8E8F0F0E1LL; // Define the ID for this slave

int valChange = 1;

RF24 radio(CE_PIN, CSN_PIN);

int dataReceived[2];
int ackData[2] = {12,23};

void setup() {

Serial.begin(9600);
delay(1000);
Serial.println("Hand Controller Starting");
radio.begin();
radio.setDataRate( RF24_250KBPS );
radio.openReadingPipe(1,deviceID);
radio.enableAckPayload();
radio.writeAckPayload(1, ackData, sizeof(ackData));
radio.startListening();
}

void loop() {

if ( radio.available() ) {
radio.read( dataReceived, sizeof(dataReceived) );
Serial.print("Data received Number0 ");
Serial.print(dataReceived[0]);
Serial.print(" Number1 ");
Serial.println(dataReceived[1]);
radio.writeAckPayload(1, ackData, sizeof(ackData));
ackData[0] += valChange; // this just increments so you can see that new data is being sent
}
}

You are right, the base module/adapter contains the 3V3 regulator and bypass filtering.

If the master and slave are too close together, the TX will overload the RX. Set the power level on both to 'MIN' and separate them by several feet.

@Waxhead, Please modify your post and use the code button </> so your code looks like this and is easy to copy to a text editor. See How to use the Forum

I need to copy it into my text editor so I can easily compare it with the original.

If you are using the base module you should not need the capacitor - I have never used them.

...R

Oops, here:

Transmitter:

// TrackControl - the master or the transmitter

 // http://tmrh20.github.io/RF24/

 //~ - CONNECTIONS: nRF24L01 Modules See:
 //~ http://arduino-info.wikispaces.com/Nrf24L01-2.4GHz-HowTo
 //~ 1 - GND
 //~ 2 - VCC 3.3V !!! NOT 5V
 //~ 3 - CE to Arduino pin 9
 //~ 4 - CSN to Arduino pin 10
 //~ 5 - SCK to Arduino pin 13
 //~ 6 - MOSI to Arduino pin 11
 //~ 7 - MISO to Arduino pin 12
 //~ 8 - UNUSED

#include <SPI.h>
//~ #include <TMRh20nRF24L01.h>
//~ #include <TMRh20RF24.h>
#include <nRF24L01.h>
#include <RF24.h>


#define CE_PIN   9
#define CSN_PIN 10

// NOTE: the "LL" at the end of the constant is "LongLong" type
// These are the IDs of each of the slaves
const uint64_t slaveID[2] = {0xE8E8F0F0E1LL, 0xE8E8F0F0E2LL} ;

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

int dataToSend[2];

unsigned long currentMillis;
unsigned long prevMillis;
unsigned long txIntervalMillis = 1000;
int txVal = 0;
int ackMessg[6];
byte ackMessgLen = 4; // NB this 4 is the number of bytes in the 2 ints that will be recieved


void setup() {

    Serial.begin(115200);
    Serial.println("Track Control Starting");
    radio.begin();
    radio.setDataRate( RF24_250KBPS );
    radio.enableAckPayload();
    radio.setRetries(3,5); // delay, count
}

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

void loop() {

    currentMillis = millis();
    if (currentMillis - prevMillis >= txIntervalMillis) {

    radio.openWritingPipe(slaveID[0]); // calls the first slave
                                        // there could be a FOR loop to call several slaves in turn
    dataToSend[0] = txVal; // this gets incremented so you can see that new data is being sent
    txVal += 1;
    dataToSend[1] = txVal;
    txVal += 1;
    bool rslt;
    rslt = radio.write( dataToSend, sizeof(dataToSend) );
    Serial.print("\nRSLT (1 = success) ");
    Serial.println(rslt);
    Serial.print("Data Sent ");
    Serial.print(dataToSend[0]);
    Serial.print("  ");
    Serial.println(dataToSend[1]);
    if ( radio.isAckPayloadAvailable() ) {
        radio.read(ackMessg,ackMessgLen);
        Serial.print("Acknowledge received: ");
        Serial.print(ackMessg[0]);
        Serial.print("  ");
        Serial.println(ackMessg[1]);
    }
    prevMillis = millis();
 }
}

Receiver:

// HandController - the slave or the receiver

    // http://tmrh20.github.io/RF24/

    //~ - CONNECTIONS: nRF24L01 Modules See:
    //~ http://arduino-info.wikispaces.com/Nrf24L01-2.4GHz-HowTo
    //~ 1 - GND
    //~ 2 - VCC 3.3V !!! NOT 5V
    //~ 3 - CE to Arduino pin 9
    //~ 4 - CSN to Arduino pin 10
    //~ 5 - SCK to Arduino pin 13
    //~ 6 - MOSI to Arduino pin 11
    //~ 7 - MISO to Arduino pin 12
    //~ 8 - UNUSED

#include <SPI.h>
//~ #include <TMRh20nRF24L01.h>
//~ #include <TMRh20RF24.h>
#include <nRF24L01.h>
#include <RF24.h>

#define CE_PIN   9
#define CSN_PIN 10

// NOTE: the "LL" at the end of the constant is "LongLong" type

const uint64_t   deviceID = 0xE8E8F0F0E1LL; // Define the ID for this slave

int valChange = 1;

RF24 radio(CE_PIN, CSN_PIN);

int dataReceived[2];
int ackData[2] = {12,23};

void setup() {

    Serial.begin(9600);
    delay(1000);
    Serial.println("Hand Controller Starting");
    radio.begin();
    radio.setDataRate( RF24_250KBPS );
    radio.openReadingPipe(1,deviceID);
    radio.enableAckPayload();
    radio.writeAckPayload(1, ackData, sizeof(ackData));
    radio.startListening();
}

void loop() {

    if ( radio.available() ) {
        radio.read( dataReceived, sizeof(dataReceived) );
        Serial.print("Data received Number0 ");
        Serial.print(dataReceived[0]);
        Serial.print(" Number1 ");
        Serial.println(dataReceived[1]);
        radio.writeAckPayload(1, ackData, sizeof(ackData));
        ackData[0] += valChange; // this just increments so you can see that new data is being sent
    }
}

Arctic Eddie,
Not sure if this was right, but added "radio.setPALevel(RF24_PA_MIN);" to the setup void on each program. I don't believe this was the issue, since it made no difference at MIN, LOW, MAX, or commented out.

HOWEVER:
When bumping the receiver around, i noticed when the rx pin (CE pin #9) came unplugged, all of a sudden i started getting a different type of message scrolling across the receiver serial screen. I then added a 10k pulldown resistor this pin, and the scrolling at least got very consistent. The attachment is a screenshot capture of what i saw - is this what i am supposed to see?

Again folks, thanks for all your help so far,
Waxhead

oops, scratch that, i put a 10k resistor in series with the pin, not as a pulldown. Connecting 13 directly stops scrolling entirely, resistor puts a "-1", and pulldown puts in a "0" at the end:
Data received Number0 0 Number1 0".

Is this just noise that the ce pin is picking up?

Been trying to read the Nordic Product specification, but my brain is lacking....

I think the state of the CE pin determines whether the radio is in TX or RX. You'll have to look at the Nordic data sheet to be sure.

Also select a channel around 100 as you might be close to a local router with a lower number.

#define RF_CHN    100

radio.setChannel( RF_CHN );         // Select particular channel
radio.setPALevel( RF24_PA_MIN ) ;   // RF24_PA_MIN/LOW/HIGH/MAX

The only variation from my code seems to be that you have changed the baud rate in one of the programs.That should not matter. Why have you not used the same baud rate in both programs?

I have never had a problem using the default power level (HIGH) with the two nRF24s about 30cm apart on the same table.

Can you start the TrackControl / Master program while the other one is off and capture some of the output and put it in a text file.

Then while that is running, start the other Slave program and if there is any change in the output of the Master capture some of that also.

Then capture some of the output of the Slave program (whether or not there was a change in the Master output).

Please post the stuff you capture with sufficient commentary that I know what's what.

...R
PS, I know the other advice is well intentioned but my program does work for me and tinkering around with settings will only make it harder to find the problem.

I have just downloaded and tested my own programs on two Unos and they worked as expected.

I also tried them with the older ManiacBug version of the RF24 library and they don't work. The Master seems to work (i.e. it says it is sending stuff) but the Slave is not receiving anything and the Master is (obviously) not getting an acknowledgement.

By the way I am using Arduino IDE 1.5.6-r2 but I can't see that a different version would make any difference.

...R

Robin2:

  1. I re-downloaded your two files and ran them purely as is to alleviate concerns about tweaking; this is a very good point, it's easier to help if you know for sure what your are starting with.
  2. Test 1 attached is Serial monitor output without the receiver running, or even plugged in.
  3. Test 2 attached is Serial monitor output without the receiver running at first, then plugged in about halfway through. No change, didn't see the acknowledgement text come up.
  4. The receiver's serial monitor output said only "Hand Controller Starting", nothing else comes up unless I unplug the CE pin.
  5. Capture4.png shows the version of rf24 i've got installed, it appears to be 1.1.6.

nrf24 serial monitor test 1.txt (801 Bytes)

nrf24 serial monitor test 2.txt (1.26 KB)

There is something strange going on. If the Master is running and the slave is not it should be showing
RSLT (1 = success) 0

Are you using nRF24L01 modules or nRF24L01**+** modules? My code is written for the latter and I don't think it will work with the older (obsolete) devices.

Have you tried swapping which Arduino is using which program?

Have you a 3rd (or 4th) nRF24 that you could use in case one of them is faulty? - which has been known in this Forum.

One of mine has a complete short-circuit between Vcc and GND and I don't think that was my fault.

...R

One of the older models used 10 pins instead of 8 pins. On the old one, both pins on one end are Vcc and both on the other end are Gnd. The 6 pins in the middle area are the normal signals.

Robin 2,
They are the "+" version, it's stamped on the chip.
Still experimenting with swapping parts around. I removed the base module, just to see if that had any effect. Get slightly different results, depending on which arduino is programmed for what. Switched to a different uno, now i get the continuous scrolling on the receiver serial monitor, and I get that even when i completely remove the Nrf24; basically unplug it, and the scrolling continues. The success=1 is indeed confusing. Still seems like I've got a jacked up library somewhere, but don't have a good idea as to what to look for. I am using (as far as i know) the files that came with the rf24.h file that you pointed me to. Is there anyway you can check that what I am using for the attached files is correct?

I also tried some of the tweaking recommended by Arctic Eddie, so far no luck.

Anyway, i'm going to to keep hammering away at it, appreciate the help so far.

nRF24L01.h (3.41 KB)

RF24.cpp (43.1 KB)

RF24_config.h (4.13 KB)

RF24.h (66.5 KB)

I would be very surprised if the library is wrong.

Attached is the library I used for testing yesterday. I will leave it to you to do the comparisons :slight_smile:

...R

TMRh20_RF24-master.zip (327 KB)

I have not used those base units. Is it possible that some of the pinouts are in different places?

You could try some simple tests like setChannel() and getChannel() to see if you can actually communicate with the nRF24 that is connected to the Uno. The code for thos functions just writes and reads one of the nRF24 registers.

...R