Before we get started, here's a brief summary of what we're going to do:
- install puredata on the raspberry pi.
- install and test the RF24 library on the raspberry pi & arduino.
- install the puredata external.
- transmit data to puredata using an arduino.
Getting puredata on the raspberry pi
The easiest way that I've found is to download one of the image files from the pd-la group. Their image files have puredata and all the required dependencies pre-installed, simply follow their instructions to copy the image to an SD card and away you go. Use a 16gb card, as an 8gb SD card won't leave you with much free space.
At this point, if you want to start puredata and have a play around, just type pd into a terminal window and hit enter.
Optional: Running the pi headless
At the moment you probably have a screen and keyboard plugged into the pi. I'd recommend keeping it this way for the moment, rather than trying to log in over SSH or X over SSH, because the puredata external will only execute if puredata is run as root.
If, despite what I've said, you wish to run the raspberry pi headless (i.e. without a screen), I'd suggest following the instructions from the linux laptop orchestra. You will then have to work out how to execute commands as root. These instructions worked for me, but I'm no linux expert.
Installing the RF24 library
Next we need to install the RF24 library on the raspberry pi, so that the puredata external can talk to the RF24 module. Make sure your pi is connected to the internet, then open a terminal window and execute:
git clone https://github.com/stanleyseow/RF24.git cd RF24 cd librf24-rpi/librf24 make sudo make installViola! the library should be installed.
Optional: Getting sound output from puredata
The built in sound on the raspberry pi 1 is quite poor, so I used an external USB soundcard (GWC Technologies AA1570), however, any of the cards found here should work. If you don't need sound for your puredata project, then more power to you!
Testing the hardware & RF24 library
At this stage I'd suggest powering off the pi, and connecting the RF24 module to it according to the wiring diagram found on this blog (for a raspberry pi 1). At the same time, connect the second RF24 module to an arduino, using the wiring diagram from the link above. Make sure that you do not accidentally connect the RF24 modules to a 5V supply! I'd also suggest soldering a 1uF capacitor across the supply terminals of the NRF24 modules.
Now, boot your pi up. If there is smoke, either turn your pi off or stop smoking inside. If there isn't smoke, then upload and compile the code from Simon John's blog on both the arduino and the pi. Execute the code on the pi, and you should see a series of increasing numbers printed to the screen. If you don't see any numbers, then check all of the connections between the RF24 modules and the arduino/pi. You should also make sure that each module isn't more than a meter or so apart. If numbers are only occasionally printed to the screen, then you have issues with packet loss - make sure those capacitors are soldered on!
If you have a lot of issues with this step, don't get dejected. Search the forums. check your wiring. Try different modules. Did I mention check your wiring?
Installing the puredata external
Now that our hardware is working, we need to get puredata set up to receive data from the NRF module. You can either use the precompiled external from the github page, or compile the external from source.
Using the precompiled external
Go to the github project page and download the RF24Listener.pd_linux file. Now copy that file to the ../puredata/extra/ directory. It's as simple as that. Skip to step 7 for a guide on how to use the external.
Read on to see how to compile the external from source.
Compiling the external from source
This is where things get a little complicated. Firstly, the external uses the flext development environment, which you will have to download and install in order to compile the external. We will then have to modify several files in the flext install, to point flext to the RF24 library, and to make sure flext compiles the external for the raspberry pi (and not another system).
Follow the instructions on the link above to install flext. Once flext is installed, you need to modify two files in the flext install directory. Note that these next steps assume you will be using gcc on linux to compile the external.
The first file is located in the flext install directory under:
Open this file, go to the end, and modify the OFLAGS section so that it reads as follows:
# user defined optimization flags # (check if they match your system!) OFLAGS=-mfpu=vfp # optimizations for build system OFLAGS+=-mfloat-abi=hard -march=armv6zk -mtune=arm1176jzf-s -lrf24-bcm -I/usr/local/include/RF24
Now save and close the file. Our modification will ensure the code compiles correctly for the raspberry pi, however we still need to make g++ link the RF24 library.
The second file is located in the flext install directory under:
Open this file, and locate the LIBS+ line (around line 9). Modify so that it reads as follows:
#ifdef SHARED #LIBS += -l$(FLEXTNAME).$(FLEXTMAJOR).$(FLEXTMINOR) #else LIBS += -l$(FLEXTNAME) -lrf24-bcm #endif
Now save and close the file. This modification will ensure the RF24 library is linked correctly when compiling.
Finally, download the source code for the puredata external from the git repository. You will need both the main.cpp file and the package.txt file. Now navigate to the source directory in a terminal window, and execute the following command:
../flext/build.sh pd gcc
Then install the external (i.e. copy it to the puredata extras directory) by executing the command:
../flext/build.sh pd gcc install
You can now use the external in puredata, as described in the next step.
Using the puredata external
Firstly, open puredata from the command line:
sudo pd -verboseWhy sudo? we must run puredata as root for the external to execute properly. I believe this has something to do with the bcm2835 library, though I'm basing my opinion entirely on error messages thrown by puredata. If you have any ideas, please let me know in the comments!
Once puredata has opened, create a new object and call it RF24Listener. After creating the object, puredata will automatically load the file you copied into the puredata/extra/ directory. The object you created should have 10 outputs and one input, which can be connected as shown in the screenshot below:
As you can see, I am driving the RF24Listener object with a 1 millisecond metronome. Every time a bang is received at the input, the RF24Listener checks if there is any data available on the NRF24 module. If there is, it reads the data into the raspberry pi, and outputs the raw value to the first (leftmost) outlet. The second outlet outputs the pipeline number that data is received on - with the current code it will always output 1. Outlets 3 to 10 output the data read from the NRF24 module in 2 byte chunks - i.e. first two bytes, second two bytes, third two bytes. Thus you can send data from one to eight arduino analog inputs, and receive all the values in puredata.
Transmitting useful data
With the external installed in puredata, we are ready to start sending some data! Grab the transmitter code from the github page, and upload it to the arduino. Make sure you have the RF24 and SPI libraries installed for the arduino! Note that I used an arduino pro mini, however you could use just about any arduino. The code reads data from the arduino analog inputs, stores the data in a 32 byte array, and transmits the data to the NRF24 module over SPI.
With the arduino plugged in and the puredata sketch running, the RF24Listener object should be outputting data (Make sure you've started the metronome, by clicking the bang object...). It is best practice to tie any unused analog inputs to ground. Now's the time to experiment with different sensors and puredata sketches!