Beaglebone RF24(nRF24L01) Library

Why?

I started working on a project which require communication with multiple radios. I started looking at nRF24L01 chip and found it to be very useful, cheap little device which has many features built-in. Initially I got two AVRs to talk to each other through the simple library found here (http://www.tinkerer.eu/AVRLib/nRF24L01). But I found multiple issues with the library when the number of nodes in the network increases,

  • Didn’t support retries
  • Dynamic packet sizes
  • Channel scanning, etc

It was a simple library to start with and understand how the radio actually works in different configurations. I didn’t want to spend lot of time implementing all features I wanted so started looking around for complete libraries for nRF24L01, and I found RF24.

RF24 is one of the most complete libraries available for the nRF24L01[+]. So I implemented my project using RF24, It was an excellent library for AVRs (Arduino), but there was no port for devices running linux, as one of the nodes in my network was running linux I had to hack the code in order to get it to work on the beaglebone. So I had to spend a weekend hacking the RF24 library to come up with a very thin layer below the library to support all its features on embedded linux boards. I used a beaglebone for testing.

This is a Beaglebone port of the popular RF24(nrf24l01) library posted on https://github.com/maniacbug/RF24/.
If you find the library is out of sync with the Arduino library please drop an email to purinda@gmail.com

Contains portions of the GPIO library posted here,
https://github.com/mrshu/GPIOlib

Complete wiki can be found here
http://maniacbug.github.com/RF24Network/index.html

Features

  • Refer to RF24 documentation.

Requirements

How to connect the pins

  • I used one of these boards to test the library. http://iteadstudio.com/store/images/produce/Wireless/RF2401/RF24013.jpg
  • Connect PIN 1 (GND) of NRF24L01 board to Expansion header P9 PIN 1(GND) of Beagleboard
  • Connect PIN 2 (VCC) of NRF24L01 board to Expansion header P9 PIN 3(3v3) of Beagleboard
  • Connect PIN 3 (CE) of NRF24L01 board to Expansion header P9 PIN 27(GPIO3_19) of Beagleboard
  • Connect PIN 4 (CSN) of NRF24L01 board to Expansion header P9 PIN 25(GPIO3_21) of Beagleboard
  • Connect PIN 5 (SCK) of NRF24L01 board to Expansion header P9 PIN 31(SPI1_SCLK) of Beagleboard
  • Connect PIN 6 (MOSI) of NRF24L01 board to Expansion header P9 PIN 30(SPI1_D1) of Beagleboard
  • Connect PIN 7 (MISO) of NRF24L01 board to Expansion header P9 PIN 29(SPI1_D0) of Beagleboard

Notes

  • Note that the library uses a GPIO pin in BeagleBone as CS pin, which is an workaround/issue exist in the code. Planning to fix it whenever I have time.
  • Project is written using NetBeans and I have commited some files used by netbeans IDE.
  • main.c contains a program which prints out the information of the connected NRF24L01 device and ping demo.
  • you may need to upload the Arduino sketch in ‘pingpair_dyn_arduino_pongback’ directory to a Arduino board in order for both Beaglebone and Arduino to run interactively.

Download the source here

https://bitbucket.org/purinda/rf24bb/src

25 thoughts on “Beaglebone RF24(nRF24L01) Library

  1. Great effort! Wondering, would this be easy enough to compile and get running on a Raspberry Pi running Raspbian as opposed to a Beaglebone?

    Thanks,

    Paul

  2. I am planning to make the port, didn’t have time. if you cant wait for a month or so, I recommend you to explore RF24 dir in lib folder to make all pin changes. As far as I can see thats all you need to do (if you have spi working on rPI).

  3. Hi Purinda,

    Thank you for this library !

    I would like to use SPI0 instead of SPI1, because I’d like to retain use of the HDMI. I see you have hard-coded /dev/spidev2.0 in spi.cpp. Do I simply change that to use /dev/spidev1.0 to use SPI0 ? If I do that, could you outline which pins on the GPIO to use ?

    I see in main.cpp:
    RF24 radio(115, 117);

    how does 115 and 117 map to the pins ?

    • Hi Grant,

      Try checking all enabled SPI devices in your beaglebone system, to do that run
      “ls -l /dev/spi*” without quotes. If there is only one SPI then try changing spi.cpp to use that device.

      In short this is how pin 115 and 117 pins were figure out,
      Open this document http://beagleboard.org/static/beaglebone/latest/Docs/Hardware/BONE_SRM.pdf
      Goto page 59 where you can see a table explaining P9 header. Then read the following example calculation closely.

      example:

      117 = (pin 25 on P9 -> GPIO3_21 = 32*3+21 = 117)

      This is how I learnt how to calculate this stuff, he explains extremely well

      Make sense?

  4. Hi,

    Great work on the port! I’ve been trying to compile it on my beaglebone black running the latest angstrom image, but I can’t seem to get it to work.

    I go the folder and type ‘make’ and I got an error because it could not find ‘arm-linux-gnueabi-g++’ but I just created a link to ‘arm-angstrom-linux-gnueabi-g++’ (also had to do it for gcc). And the ‘make’ ran and did not complain.

    What am I suppose to go after I type make? It’s not obvious to me.

    Any help would be appreciated,

    Marc

    • Hi Marc,

      Once the make has completes, look inside the directory ./dist/Release/GNU_Arm-Linux-x86 for the compiled binary.

      Hope that helps,
      -Grant.

      • Thanks for the help. But when I do ./rf24bb in the dist/Release/GNU-Arm-Linux directory, I get the following error “can’t open device: no such file or directory”. Is this an SPI issue?

    • Hi Marc,

      Grant already answered your question. He beat me to it :)

      One last thing, if you are new to linux, just keep in mind that you can run applications by typing the name of the program with a “./” in front (only if you are in that directory),

      ex:
      ./rf24bb

      also if it says “-bash: ./: Permission denied”
      you make need to set execute bit to the application.

      Ex:
      chmod +x

      If you would like to learn more about linux read http://www.tldp.org/LDP/intro-linux/intro-linux.pdf
      Specially Chapter 2.

      Let us know if you got have further questions.
      Happy to help.

      • Just for clarification, the rf24bb is just a bb version of the pingpair test, right? It’s an example of how to use the library?

        I’ve got a beaglebone black and a raspberry pi, I’m going to try to set them both up. I see in the main.cpp that it seems the role is hardcoded to that of a sender by default and the role_pin read was removed during setup. I assume I can drop this onto the pi (once I get that one’s libraries set up), change the role, and it will work as a pong and reply to my bbb? Here’s what I’m getting now:

        STATUS = 0x0e RX_DR=0 TX_DS=0 MAX_RT=0 RX_P_NO=7 TX_FULL=0
        RX_ADDR_P0-1 = 0xf0f0f0f0e1 0xf0f0f0f0d2
        RX_ADDR_P2-5 = 0xc3 0xc4 0xc5 0xc6
        TX_ADDR = 0xf0f0f0f0e1
        RX_PW_P0-6 = 0x20 0x20 0x00 0x00 0x00 0x00
        EN_AA = 0x3f
        EN_RXADDR = 0x03
        RF_CH = 0x4c
        RF_SETUP = 0x27
        CONFIG = 0x0f
        DYNPD/FEATURE = 0x3f 0x04
        Data Rate = Model = CRC Length = PA Power = Now sending length 4…Failed, response timed out.
        Now sending length 6…Failed, response timed out.
        Now sending length 8…Failed, response timed out.

        I’m new to SPI and the whole bit, so I’m hoping that I at least have the BBB ready to go. There were a few pitfalls like needing to “ln -s /usr/bin/arm-linux-gnueabihf-g++ /usr/bin/arm-linux-gnueabi-g++” and “ln -s /usr/bin/arm-linux-gnueabihf-gcc /usr/bin/arm-linux-gnueabi-gcc” in case anyone else finds this useful, and the SPI documentation seems to be spotty. Some instructions were pretty confusing but in the end the built-in bbb image just requires “echo BB-SPIDEV1 > /sys/devices/bone_capemgr.*/slots”.

      • I did manage to get the Rasperry PI’s RF24 communicating with the BeagleBone. I had to copy their pingtest.cpp and change the includes to match the beaglebone’s libs. It also looks like these could use a little love in the printDetails as the RF24 libs in the BBB repo fail to print the data rate/model/power correctly. I’d love to see this pulled into Stanley’s git repo so both platforms are working against the same RF24.

        root@beaglebone:~/code/purinda-rf24bb-a255ab052e56/dist/Release/GNU_Arm-Linux-x86# ./rf24bb

        RF24/examples/pingpair/
        ROLE: Ping out
        STATUS = 0x0e RX_DR=0 TX_DS=0 MAX_RT=0 RX_P_NO=7 TX_FULL=0
        RX_ADDR_P0-1 = 0xf0f0f0f0e1 0xf0f0f0f0d2
        RX_ADDR_P2-5 = 0xc3 0xc4 0xc5 0xc6
        TX_ADDR = 0xf0f0f0f0e1
        RX_PW_P0-6 = 0x20 0x20 0x00 0x00 0x00 0x00
        EN_AA = 0x3f
        EN_RXADDR = 0x03
        RF_CH = 0x4c
        RF_SETUP = 0x07
        CONFIG = 0x0f
        DYNPD/FEATURE = 0x00 0x04
        Data Rate = Model = CRC Length = PA Power = Now sending 102…ok…Got response 102, round-trip delay: 76
        Now sending 1186…ok…Got response 1186, round-trip delay: 93
        Now sending 2283…ok…Got response 2283, round-trip delay: 53
        Now sending 3340…ok…Got response 3340, round-trip delay: 103

      • Nice to see that you got it running on your board!

        Yes like you said it would be nice if we could merge both these repos into a one so everyone can use it with just toggling a flag in the code depending on the board they use.
        If you could kindly send me a list of things you did to get the library running on BBB (I got mine last week so Im new to the BBB), I would merge that into the codebase or add as a setup note.

      • Hi, I didn’t do much. the abi compilers are named differently so I symlinked them. I also changed to /dev/spidev1.0 in the header. Aside from enabling SPI on the bbb I think that was it.

        As I mentioned in Martin’s response, I later took the code and adjusted it a bit to match what the RPI guys did so you end up with a shared object installed, which for me is an easier result to get started with. I also took the lines from RF24.cpp that were responsible for printing the data rate, etc from the rpi version into my bbb version and that fixed it. I have sent a pull request to Stanley for that and you can see it in my own repo.

  5. Sorry, that i bug you with years old project, but i have few headaches here…
    I’m trying over-and-over again, but i fail to get your “library” to work on Beaglebone Black SPI1 (running Debian).
    (yes, i disabled HDMI and HDMIN first…)

    it compiles fine, but output is something like (never got futher from here):
    /////////////////////////////////////////////////////////////////////////
    root@beaglebone:~/purinda/purinda-rf24bb-a255ab052e56/dist/Debug/GNU_Arm-Linux-x86# ./rf24bb
    STATUS = 0x0e RX_DR=0 TX_DS=0 MAX_RT=0 RX_P_NO=7 TX_FULL=0
    RX_ADDR_P0-1 = 0xf0f0f0f0e1 0xf0f0f0f0d2
    RX_ADDR_P2-5 = 0xe2 0xe3 0xe4 0xe5
    TX_ADDR = 0xf0f0f0f0e1
    RX_PW_P0-6 = 0x20 0x20 0x20 0x20 0x20 0x20
    EN_AA = 0x3f
    EN_RXADDR = 0x3f
    RF_CH = 0x4c
    RF_SETUP = 0x27
    CONFIG = 0x0f
    DYNPD/FEATURE = 0x3f 0x04
    Data Rate = Model = CRC Length = PA Power = Now sending length 4…Failed, response timed out.
    Now sending length 6…Failed, response timed out.
    Now sending length 8…Failed, response timed out.
    Now sending length 10…Failed, response timed out.
    ^C
    root@beaglebone:~/purinda/purinda-rf24bb-a255ab052e56/dist/Debug/GNU_Arm-Linux-x86# uname -a
    Linux beaglebone 3.8.13-bone47 #1 SMP Fri Apr 11 01:36:09 UTC 2014 armv7l GNU/Linux
    //////////////////////////////////////////////////////

    other side: Arduino with your “pingpair_dyn_arduino_pongback” sketch, with output :
    /////////////////////////////////////////////
    RF24/examples/pingpair_dyn/
    STATUS = 0x0e RX_DR=0 TX_DS=0 MAX_RT=0 RX_P_NO=7 TX_FULL=0
    RX_ADDR_P0-1 = 0xf0f0f0f0d2 0xf0f0f0f0e1
    RX_ADDR_P2-5 = 0xc3 0xc4 0x21 0xc6
    TX_ADDR = 0xf0f0f0f0d2
    RX_PW_P0-6 = 0x20 0x20 0x00 0x00 0x00 0x00
    EN_AA = 0x3f
    EN_RXADDR = 0x33
    RF_CH = 0x4c
    RF_SETUP = 0xa6
    CONFIG = 0x0f
    DYNPD/FEATURE = 0x3f 0x06
    Data Rate = 250KBPS
    Model = nRF24L01+
    CRC Length = 16 bits
    PA Power = PA_MAX
    /////////////////////////////////////////////

    and also,that loogs interesing in BeagleBone Black that “Data Rate, Model and etc.” of Status printout is all in one line:

    CONFIG = 0x0f
    DYNPD/FEATURE = 0x3f 0x04
    Data Rate = Model = CRC Length = PA Power = Now sending length 4…Failed, response timed out.
    Now sending length 6…Failed, response timed out.

    I would be really happy, if you could help me out.
    Martin

    • Sorry about the delayed response Martin.
      I didn’t have a Beaglebone Black till last week and had to try my code on it. I figured that on beagle bone black the test application fails. Haven’t figured out why though.
      But I tried sending a message to the Arduino and that worked. I guess the ping fails because of a timing issue in the library, I will have to look for a possible solution.

      Since everyone is trying out this library on the Beaglebone Black I will modify the library and try my best to fix this particular issue you are having.

    • I was able to get it to work with BBB, and then pulled it in and rearranged it a bit into the RPi repo. This version builds a shared object which to me seems more straightforward to start programming with.

      https://github.com/mlsorensen/RF24.git

      I also blogged about my experience at http://electron14.com. I did see what you’re seeing once, but could not reproduce it. I’m not sure if it was an ordering thing or what (pinging or ponging first from the bbb). When I did see a problem dmesg said:

      [ 376.425604] gpio_request: gpio-117 (sysfs) status -16
      [ 376.425640] export_store: status -16

      I powered off the BBB, powered it on, and then everything was fine.

      • Looks like status 16 is busy. Martin’s output looks as though it’s correct and the bbb is communicating with the radio, as did mine when I saw this. I can make the error above happen if I run both the pingtest and the pongtest on the same bbb, so perhaps I did something accidental. I can’t reproduce it at the moment (other than running two things at once), rebooted my bbb three times and tried various things in differing order.

      • Ok, not just my imagination. I got it into a bad state again with the dmesg -16 messages, rebooted, did nothing but run ‘pingtest’, got same dmesg errors. Could not get it working again until I shut down, removed power, started up again. So perhaps something is getting in a strange state in the hardware.

      • yup, same problem here.
        first time it runs fine, but second time, dmesg shows up errors:

        ///////////////////////////

        [ 385.279836] gpio_request: gpio-115 (sysfs) status -16
        [ 385.279879] export_store: status -16
        [ 385.282472] gpio_request: gpio-117 (sysfs) status -16
        [ 385.282506] export_store: status -16

        ///////////////////////////

Leave a comment