Getting Started with nrf24L01+ and Arduino

Getting Started with nrf24L01+ and Arduino

After several months of learning and playing, I’m finally ready to share some of my notes about the nrf24L01+ modules and Arduino. As a newbie to arduino, I am hoping that my experience will be useful to others who are getting started.

Intro to the nrf24L01+

The nrf24L01+ is a very inexpensive transceiver that runs in the 2.4ghz space. I bought a pair of the slightly more expensive ones from Amazon because they have a nice little pin diagram right on them. You’re going to spend time looking this diagram up every 10 minutes if you don’t get this pair first. Later on, once you get an idea of what you’re doing, pick up a handful of the cheap version for about $1.59 each.

What to expect

These radios have a short onboard antenna and are rather low-power, so don’t expect crazy range with these. Outdoors with no obstructions, I was able to get almost 300 feet before the packets failed to go through. Indoors, I can get from one corner of the house (corner of garage, through the floor, several walls, to the other corner) to the other pretty solidly.

My base station is using a bigger version (NRF24L01+PA+LNA SMA) that has an external antenna. I haven’t done a full test of this yet, but I was able to get over 1200 feet with this one while walking through the park. I lost sight of my house and there were several trees in the way, so I’m eager to test them out in an open field.

Connecting the radios to your Arduino

I’m going to assume here that you’re using a Pro Micro, but you can translate this to a pro mini or any other if you just match SCK, MOSI, MISO pins together. The CE and CSN can be any digital pins. On my full-size arduino, I use pins 2 and 3, for CE/CSN for example.

### Transmit/Receive Example Code The code example everyone points at for your first connection (the ping-pair sketch) is not exactly designed for readability, but it does a decent job of getting a connection tested with some feedback. Various people have expanded the ping pair test to let you quickly turn one into transmit mode & the other into receive mode, and there are all sorts of alternate example sketches. These examples can be quite frustrating to debug, because what they are doing is not super clear from the beginning and they don't explain what they are doing, why, and when it happens. Once you know what's going on, they are easy, but I don't feel like these are the best examples to throw at newbies. I took apart the examples and put together a very [simple transmit/receive example sketch](https://gist.github.com/bryanthompson/ef4ecf24ad36410f077b) that should get you started. Basically, it transmits a 32 byte packet of data with a single value, then the receiver echos it back. Once you have the basic sketch working, you can experiment with more interesting ways to send things like structs, floats, and other bits of data back and forth. If you want to see something super awesome, check out [this video](https://www.youtube.com/watch?v=hI4JGDB7WtU) where [Kevin Darrah](http://www.kevindarrah.com/) shows how he can physically control pins on a remote arduino with these radios. Pretty wild. ### Basic troubleshooting When getting started with the nrf24L01+, try not to get overwhelmed with the massive amount of forum posts, library versions, etc. There are some incredibly smart people who have written up posts that, to a newbie, will be entirely useless, but once you get a handle on it, you'll appreciate what they are saying. **Before hooking anything up, make sure you have a good 3.3v supply ready** When my parts arrived, I raced down to Radio Shack to pick up a voltage regulator. Unfortunately, they only had 5v and adjustable regulators ([LM317](http://www.amazon.com/gp/product/B00K38NMVI/ref=as_li_tl?ie=UTF8&camp=1789&creative=390957&creativeASIN=B00K38NMVI&linkCode=as2&tag=10586904-20&linkId=YUEAEIY6VHKK6OQR)), so I picked up the 317 and a few packs of resistors. Eventually, I got the 317 to give me 3.3v, but I found it pretty frustrating. Later on, I picked up a pile of 3.3v regulators (LD1117V33) and everything has been perfect. My biggest problem with the LM317 was that the voltage seemed to drop rather erratically as I tested the radios. I was almost surely doing something wrong, but, as noobs, we can make our lives easier by spending the $1 on the right regulator in the first place. **Use a 10uF cap right before the radio** Once you have your power in order, stick a 10uF cap right before your radio. I've tested with and without the cap, and I get about 25% loss without it, so just use one from the start. **Avoid jumper hell** Buried away in a forum thread where someone was trying to debug issues similar to what I was seeing (radio would lose its pipe addresses randomly), someone suggested removing the pins and wiring directly to the board. Once I did that, all of my problems stopped and I was able to actually make some progress. Until then, I think half my problems were due to either bad jumpers or pin mixups. When you do solder your wires on, pick a color scheme and stick with it. **Don't get confused between libraries** I noticed a few things while trying to sort through different versions of different peoples' forks of the common libraries: The readme files are almost never updated, their blog posts don't stay up-to-date with repos, so good luck trying to connect the two, and once people find something that works, they just seem to stop talking about it, so you really can't tell what state they left thigns in. The best choice I made was to grab a copy of Stephen Crane's [SPI and rf24 libraries](https://github.com/jscrane?tab=repositories). His [blog](http://programmablehardware.blogspot.com/) has a lot of good info and is fairly well updated, and his other repos helped to shed a little more light on what I was doing wrong. Download and install his SPI and rf24 libs, ignore anything (for now) that talks about the Mirf library. Look at that stuff once you have the basic stuff working. ### Slightly more interesting troubleshooting **Problem: receiver streams 'packet received' messages erroneously** This typically happened when my MOSI/MISO lines were switched. Check that you have it wired up properly. **Problem: either end shows 0x00000000 address** Usually when this happened to me, it was because my power source was being flaky or that my jumpers were losing their connection. As you move stuff around, make sure your wires are tight in the breadboard as well. **Problem: radios losing their pipe address/assignments** This always turned out to be a connection issue for me. Soldering the lines really helped, and this was the most frustrating problem to pin down. I found it by making a new loop() method that simply prints the radio details over and over and I could see that they changed/got lost randomly. ```c void loop() { radio.printDetails(); delay(1000); } ``` Your output should look something like this: ``` STATUS = 0x0e RX_DR=0 TX_DS=0 MAX_RT=0 RX_P_NO=7 TX_FULL=0 RX_ADDR_P0-1 = 0xc2c2c2c2c2 0xe7e7e7e7e7 RX_ADDR_P2-5 = 0xc3 0xc4 0xc5 0xc6 TX_ADDR = 0xc2c2c2c2c2 RX_PW_P0-6 = 0x20 0x20 0x00 0x00 0x00 0x00 EN_AA = 0x00 EN_RXADDR = 0x03 RF_CH = 0x4c RF_SETUP = 0x07 CONFIG = 0x0f DYNPD/FEATURE = 0x00 0x00 Data Rate = 1MBPS Model = nRF24L01+ CRC Length = 16 bits PA Power = PA_HIGH ``` ### Leveling up from here Once you get an example working one time, everything changes. You'll start to move around your CE/CSN pins, you'll experiment with different types of Arduinos, and you'll quickly find that you need to design your own protocol so you can move around different types of data from different units. I eventually got these working with the atmega328 and attiny84's directly, but that's a topic for another post. If you found this writeup useful, or if you find any problems or have questions, ***please leave a comment below***.
nrf24L01+ Pro Micro nrf24L01+ Pro Micro
VCC3.3v GNDGround
CSN10 CE9
MOSI16 SCK15
IRQNot Connected MISO14