NRF24L01 and SPIDEV on the Beagle Bone Black
I am working on various electronics projects where I want to have a sensor node that collects data from a sensor and either logs it to a micro-SD-card directly or sens it wirelessly to another machine that uses/logs/etc the data. I opted for a set of NRF24L01+ boards for the wireless communication between the nodes and data loggers. So to test it out I want to communicate between my Beagle Bone Black and an Arduino. The NRF24 library by TMRh20 supplies a unified API for the NRF24L01 that should work on Arduino, linux (like Beagle Bone Black and Raspberry Pi) and other platforms. It also includes some examples that are identical across platforms so you can test between platforms with the same code. Really cool. I had trouble getting it to work on my Beagle Bone Black. This post hopefully will help other getting it to work on a Beagle Bone Black running Debian Jessy.
There are various howto’s about the Beagle Bone Black and RF24, and as so often with the BBB, there are many articles contradicting eachother, using different pinouts than my BBB uses I guess. What I have found is that the only reliable pinout for a BBB is the one specified on the standard webinterface of your BBB (on the front-page at the bottom). So the only really useful how-to I ended up using is about the RF24 library on [https://tmrh20.github.io/RF24/Linux.html], which doesn’t talk about the BBB specifically. So after installing the RF24 library I just tried what some other how-to’s said but as soon as I started the “gettingstarted” example from there, I got the error
It took me quite a while to figure out what was going wrong. It turned out to be various problems, mostly related to the SPI bus and it’s pinout.
The NRF24L01 uses the SPI bus for communication. The Beagle Bone Black uses SPIDEV for this and has two SPI buses. Those need to be enabled, and for them (or I believe actually only 1 of the 2) to work, the HDMI bus needs to be disabled. What I had to do was first edit /bootuEnv.txt
and make sure the following two lines were in there:
After that you need to restart your beaglebone. With
you can see the devices are there. You can also see they are available with
BB-SPIDEV0 I think corresponds to /dev/spidev1* and BB-SPIDEV1 to /dev/spidev2*. in the filesystem. If you look at the pinout for my Beagle Bone Black (but be sure to check yours on the web-interface of yours) specifies the following pinouts:
- .
There, the pins SPI1_DO, SPI1_D1, SPI1_CSO and SPI1_SCLK correspond to BB-SPIDEV1 and /dev/spidev2*. So I wired my NRF24L01+ in the following way:
Beagle Bone | NRF pin name | NRF pin number |
---|---|---|
DGND | GND | 1 |
VDD3V3 | VCC | 2 |
GPIO_115 | CE | 3 |
SPI1_CSO | CSN | 4 |
SPI1_D0 | MOSI | 6 |
SPI1_D1 | MISO | 7 |
SPI1_SCLK | SCLK | 5 |
After having it wired like this I wanted to get the gettingstarted sample in ~/rf24libs/RF24/examples_linux/gettingstarted.cpp to work. The problem I had there is that the RF24 radio() statement in there, which instantiates the RF24 radio is different on Linux than it is on Arduino. On Arduino you give the radio() function the pin numbers to which the CE and CSN pins of the NRF24 are connected. With the Beagle Bone Black and SPIDEV the first argument is the pin number of the CE pin, while the second argument is the number of the SPI device that it is connected to. If you connected it as I showed above, the CE pin is connected to pin GPIO_115 (pin 27 of header P9) and you’re using SPI1. So the line with RF12 radio() in ~/rf24libs/RF24/examples_linux/gettingstarted.cpp should look like this:
The first argument specifies the CE pin is GPIO_115 while the second says that it uses SPI1, or in other words /dev/spidev2.0.
After that you need to run
in the ~/rf24libs/RF24/examples_linux directory to compile it. After that, the example works (provided you have another device, like an Arduino, with an NRF24L01 listening to pong back):