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;*/ #endif
For the first test I built a quick test rig on matrix board containing an ATtiny84 and the nRF24L01+ wired as follows:
After confirming it worked I went on to botch one onto a TinyTX 3:
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:
And then I made this mess:
For the receive end I made a adapter on matrix board for connection to an Arduino.
This is wired as follows:
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.