Using the RF24 library for nRF24L01 on Raspberry Pi with Python 3
Update 21. February 2017
Since publishing this post, the RF24 library got updated a lot! A significant change was making the boost python wrapper compatible with Python 3. So the RF24 library now works on system with Python 3 out of the box without any funky hacks! If you want to use the RF24Mesh extension for mesh networks, check out my fork with Python 3 support: https://github.com/joernesdohr/RF24Mesh
I’ll have to get around making a pull request into the main repository eventually…
The nRF24L01 radio module is an incredibly cheap yet very powerful piece of hardware for building your own wireless networks. Some folks are doing amazing work in providing proper communication features through libraries. One of them is the RF24 library from user TMRh20, which provides solid and reliable functionality to send and receive data via the nRF24L01 and nRF24L01+ transmitters on both the Arduino and Raspberry Pi.
The library is originally written in C++ but also provides an installable Python wrapper for use as the RF24 module in Python applications. The only downside so far is that the project documentation only guides you through setting up the library for Python 2.7, which sucks because Python 3 is the latest craze. So this is a guide to assist you in setting up the TMRh20/RF24 library for use in Python 3 applications.
To create Python wrappers for C++ code, the Boost library collection can be used, which we’ll install and use on the RF24 framework.
Step 1: Get the Boost sources
We have to get the Boost.Python library for Python 3 to turn the C++ code of RF24 into a Python 3 module. Since Boost.Python built with Python 3 is not available through Aptitude (correct me if I’m wrong), we have to compile it ourselves.
Download the latest source of Boost from a hoster like Sourceforge and put it somewhere on your Raspberry Pi. One way is to use
wget http://sourceforge.net/projects/boost/files/boost/1.57.0/boost_1_57_0.tar.gz/download; -O path/to/download/boost.tar.gz
And unpack it:
tar -xzf boost.tar.gz
Make sure to have enough disk space, Boost 1.57 requires about 600MB for the archive and unpacked sources. You can check your available disk space with the
$ df -Bm command.
Step 2: Compile and install Boost.Python
Go into the unpacked boost folder. Boost has a ton of libraries, which take a long time to compile if done all at once, since we only want to use the Python 3 library, we need to define that in the command parameters with the
--with-libraries argument and also define the version of Python to build the Boost library with the
--with-python argument (in this case I built it with Python 3.2):
./bootstrap.sh --with-libraries=python --with-python=python3.2
When it is done preparing the python library, we can install it by executing:
sudo ./b2 install
This can take a while. At the end, Boost.Python should be installed in your default /usr/local/include/boost location. There you should be able to find a file called libboost_python3.so.1.57.0 (or similar, depending on the version of Boost).
Step 3: Install the RF24 Python 3 wrapper
First of all, get the TMRh20/RF24 repository from Github and install the C++ libraries as is described on the Github project page.
Now that we have Boost.Python for Python 3, we can use the library to create our wrapper for the C++ classes of the RF24 library. Go down into the
RF24/RPi/pyRF24 folder of the repository, where you’ll find the
pyRF24.cpp file with some explicit Python wrapper definitions. Use the following command to build that file and install the RF24 Python 3 module into the default Python 3.2 module location
/usr/local/lib/python3.2/dist-packages. Change the
/path/to/RF24-parent-folder placeholder to the correct parent folder of the RF24 repository you are using.
sudo g++ pyRF24.cpp -I/usr/include/python3.2 -I/usr/local/include -I/path/to/RF24-parent-folder -lboost_python3 -lrf24-bcm -lpython3.2mu -o /usr/local/lib/python3.2/dist-packages/RF24.cpython-32mu.so -shared
Quick explanation: The
-I arguments define locations to look in for required C++ header files, the
-l argument defines locations of libraries. Important to note is that
boost_python3 is used as opposed to just
boost_python (which is for Python 2).
Remark: It’s not a good idea to manually put files into the dist-packages folder, but I couldn’t figure out to make an altered setup.py do that for me — for some reason, the stock setup.py in the RF24 repository still builds the wrapper with Boost.Python 2.7, even though I changed the the Boost.Python reference to Python 3.
Check if everything works
There should now be the
RF24.cpython-32mu.so shared object in your
python3.2/dist-packages folder. With this you are able to import the RF24 library as a module in your Python application.
To see if everything works as it should, you can quickly change the RF24 pingpair_dyn.py example to Python 3 compatible code and execute it. Replace the
input(), and that should be it I think.
You can change the Installation folder for Boost libraries through additional command line arguments. Information about this and more can be found in this Unbuntu forum posting:
Thank you for the tutorial. At least it has helped me with progressing on one project due shortly.
When I however try the example (pingpair_dyn.py) I am getting the error I cannot solve by myself:
ImportError: /usr/local/lib/python3.2/dist-packages/pyRF24.so : undefined sympol: _Py_ZeroStruct
How to overcome the issue?
Thanks in advance