Experimenting with the nRF24L01+ 2.4GHz radios

nRF24L01+ mounted on a TinyTX3
nRF24L01+ mounted on a TinyTX3

I thought it was about time I did a post on the testing I did with the nRF24L01+. This low cost transceiver IC from Nordic Semiconductor works in the 2.4GHz ISM band and you can find boards based on this chip very cheaply indeed, I picked a pair up on ebay for 2.89 USD including shipping from China, yes, an incredible 97p each!

The nRF24L01+ supports 3 data rates, 250kbps, 1Mbps and 2Mbps, there is also the older nRF24L01 which only supports 1Mbps and 2Mbps so the + model is the one to go for as the 250kbps data rate option can extend the range by around 3x compared to 1Mbps mode and is easily fast enough for a simple sensor node.

As they operate in the 2.4GHz range you wouldn’t expect the range indoors to be as good as a 433Mhz or even 868MHz device but I’ve tested it around the house and I seem to be getting a range not too dissimilar to the RFM12B, or at least it works in all the positions I have an RFM12B. I’m surprised it works as well as it does as I’ve heard other saying they only get a few meters although Martin did get some decent results too.

There is a library here that makes it easy to get up and running in a standard Arduino environment but I wanted to try it with our little friend the ATtiny84 as used in the TinyTX, which requires a different approach. Instead I used this forked version of mirf that is compatible with this fork of the aforementioned RF24 library.

I saw a lot of people saying that this Mirf based library worked fine on the ATtiny85 the author had used but not the ATtiny84 and that was initially the case for me too but I managed to get it working (using the arduino-tiny core) by changing the SPI pin definitions in SPI85.cpp in the SPI85 library to use the Arduino pin numbers instead of the port names. I’m a bit puzzled as to why this is necessary to be honest but sometimes you’ve just got to go with what works. If anyone can shed any light on this then please do let me know.  Here is what I changed it to:

#if defined( __AVR_ATtiny84__ )
/* This works */
const static uint8_t SS = 1;
const static uint8_t MOSI = 5;
const static uint8_t MISO = 4;
const static uint8_t SCK = 6;

/* This does not work
const static uint8_t SS = PA7;
const static uint8_t MOSI = PA5;
const static uint8_t MISO = PA6;
const static uint8_t SCK = PA4;*/

For the first test I built a quick test rig on matrix board containing an ATtiny84 and the nRF24L01+ wired as follows:

Matrix board sensor node
Matrix board sensor node
nRF24L01 Pinout
nRF24L01 Pinout
nRF24L01+ ATtiny84
Gnd 1 GND
Vcc 2 Vcc
CE 3 Pin 11/D8
CS 4 Pin 10/D7
SCK 5 Pin 9/D6
MOSI 6 Pin 8/D5
MISO 7 Pin 7/D4

After confirming it worked I went on to botch one onto a TinyTX 3:

TinyTX3 with nRF24L01
TinyTX3 with nRF24L01

This required cutting three tracks so I could use the secondary pads for D8,D9,D10 to link to different pins with jumper wires on the bottom of the board.

I cut the tracks indicated by the yellow dots on the pictures below:

tinytx3_nrf24l01_cut_front tinytx3_nrf24l01_cut_rear

And then I made this mess:


For the receive end I made a adapter on matrix board for connection to an Arduino.

nRF24L01+ Arduino Adapter
nRF24L01+ Arduino Adapter

This is wired as follows:

nRF24L01+ Arduino
Gnd 1 GND
Vcc 2 3v3
CE 3 D9
CS 4 D10
SCK 5 D13
MOSI 6 D11
MISO 7 D12

Finally here is some basic proof of concept code for an ATtiny84 temperature sensor node and a receiver on an Arduino that simply outputs to serial. All in all these are quite nice little modules with a better than expected range and most of all an unbeatable price. I’ll probably do some more with these once the DigiX board that I backed on Kickstarter arrives as it has one built in. I particularly want to try the RF24 mesh networking.

Next on the bench to test are some low cost CC1101 based radio modules, stay tuned.


16 thoughts on “Experimenting with the nRF24L01+ 2.4GHz radios

  1. Hi Nathan,

    Thanks for this information! I was a little shocked last night when I read that the RFM12b is end of life so I ordered a bunch to keep playing with and build some more TinyTX sensors.
    I am happy to see that you already did some testing on the nRF24L01+ and the link to the DigiX board makes me look forward to new developments.

    Looking forward to your results on the C1101 radio’s and actually I’m hoping that TinyTX 4 will become nRF24L01 based 😉

    Best regards,

  2. Yes the RFM12B EOL was a worry for a while but seems that reports of its death were exaggerated and I’ve seen several sources state they have had confirmation from Hope RF that it isn’t going away any time soon, they are just trying to steer people towards their newer modules I think. It was a good prompt to review the alternatives though. I made some progress with the CC1101 modules last week but not quite there yet. Hopefully will be able to spend some more time on it this week.


  3. Hi Nathan,
    Germany writing you 🙂
    First, i’m very impressed in your project and just started to create the same on my own. I already have two RFM12B for 433Mhz and two RFM12B for 868Mhz and 2 nRF24L01+ are ordered. I frist want to create everything on a breadboard and try which of the 3 “system” matches my needs (range and bidirectional).
    Awaiting my first testresults i have two few questions for my future planning:
    1. Do you have any idea if and when you will create the “new” TinyTX Board for the nRF24L01+??
    2. I want to use an arduino uno as “base station”, this should be possbile with a few changes on your sketches, correct?

    Many thanks for your answer!

  4. No plans to switch from the RFM12B at the moment, I have a lot of TinyTX sensors and other nodes (Nanode, WiNode, OSWIN) already deployed using it so I will probably stick to that for the forseeable.

    An uno would be fine as a base station. With the RFM12B you would need to power it from the 3.3v and use some resistors as a level shifter on the SPI pins as they won’t handle 5V. Jeelabs do a nice little board for that or just make your own: http://jeelabs.com/products/rfm12b-board

    It’s a bit easier with the nRF24L01 as the SPI pins are 5V tolerant although it still needs power from the 3.3V.

  5. Hi Nathan,
    many thanks for your answer, i think i will go on and start my new project also with 868Mhz (RFM12B). Anyhow, i want to exchange the Arduino Uno with one of these stations:
    JeeNode USB or Nanode Gateway or NanodeRF SMT 868Mhz from openenergymonitor

    What do you think ,which one should i use. I need it as basestation which should be able to send data via usb or ethernet to my homeautomation system. I think i preferr the NanodeRF SMT 868Mhz from openenergymonitor cause its interesting for the price and its able to send adat via ethernet!
    What do you think?

    Thanks and greetz from Germany

  6. Hi Nathan. Just found your blog and have a bit of reading to do. Looks like lots of great information, thanks. I found this page while searching for information on the RF24’s. I am just getting up to speed with them and have some more digging to do. But I wanted to ask a quick question…

    One of the things I am hoping to do is be able to use the RF24’s to very simply extend an I2C. I would want to couple an RF24 to an I2C IO-expander such as the MCP23008. And I would (ideally) implement that as a leaf node. The RF24 would simply pass I2C bits, rather than messages to be interpreted. In that way the leaf nodes do not have a processor (and as a result do not have a program to be managed.) Not sure whether the RF24 as a leaf node could handle that or if it would require some compute capability.

    Alternatively I have seen some other, even cheaper, RF transmitters and transceivers on ebay. But the data rates seem low and the documentation is nearly non-existent on them. So I am thinking they might to a path of frustration and the popularity of the RF24 might be the way to go.

    Any thoughts?

    Thanks in advance. Off to read more…


  7. Hi Nathan, I’am very happy for your information and I’am looking for your sensor node for temperature with DS18B20. I notice that you assign the same pin of the Attini (D7 pin 10) for the GND of sensor and the CSN command of nrf24l01, it’s right?
    regards Andrea

  8. Great site with best info and examples I could find on Attiny84.

    If I have to use Arduino Mega instead of UNO for the Rx, what would be the pin numbers I should use to connect nRF24L01+ to Arduino Mega?

    Do I need do I need to change anything in Rx program?

  9. Hi Nathan,
    Good write up. RIght now I’m using an Arduino Nano with the NRF24l01 for testing but wnat to get the footprint down with the NRF24L01 hot glued to the ATTiny84 . Any suggestions for power. By the way, check your MISO and SCK assignments 😉

  10. Hello Nathan,
    Great site and good info,iam trying to communicate between attiny84 and raspberry pi via nrf24l01+,still now iam unable to do so,could you please share a working link for attiny84 + nrf24l01,thank you for the help

  11. Nathan, I like this project, but I’m in trouble with the code.
    In your TinyTX_nRF24L01_DS18B20.ino the ONE_WIRE_GND is not declared; I think it doesn’t matter, because gnd of 18B20 goes on gnd, but if I comment this row, other error appear during arduino verify code.
    In file included from attiny84_nRF24L01_temp_sensor_node.ino:16:
    /Arduino/libraries/SPI85/SPI85.h: In static member function ‘static uint8_t SPI85Class::transfer(uint8_t)’:
    /Users/ivano/Documents/Arduino/libraries/SPI85/SPI85.h:68: error: ‘USIDR’ was not declared in this scope

    Can you help ?

Leave a Reply

Your email address will not be published. Required fields are marked *

Notify me of followup comments via e-mail. You can also subscribe without commenting.