Raspberry Pi SDR with GNURadio

The Raspberry Pi is a small SoC type device you can find for around $40. I never had much use for it earlier on but, having found out one of the GPIO pins on the Raspberry Pi 2 can produce a square wave in the range of “130 kHz to 750 MHz”, I finally felt justified. Thanks to Evariste Courjaud F5OEO, creator of rpitx, the Raspberry Pi can transmit RF within said frequency range, effectively making it the cheapest transmitting SDR I’ve seen to date.

Note: As mentioned in many articles, the square waves will produce harmonics of the target frequency and may cause unwanted interference. A band pass filter is needed to restrict transmission to the desired frequency.

After some Googling, I found a GitHub repo with some useful command line examples for rpitx. I discovered the rpitx supports having samples piped in through STDIN. This is convinent because GNURadio supports TCP sinks and nc can act as an in-between (I couldn’t find GNURadio support for file descriptor sinks). I decided to run a few experiments, first setting up a template using GNURadio for modulation and then using the afsk Python package and csdr to transmit AX.25 frames on APRS.


After installing Rasbian Jessie on the Raspberry Pi, I installed all the necessary packages.

GNURadio, Git, PIP

sudo apt-get install git gnuradio python-pip


git clone https://github.com/F5OEO/rpitx.git
cd rpitx
sudo pip install setuptools
sudo python setup.py install


sudo pip install afsk


git clone https://github.com/simonyiszk/csdr.git
cd csdr
sudo make install

GNURadio Python script

After all the depencies were installed I wrote a basic Python template to boot rpitx and use GNURadio to pipe samples via nc:

#!/usr/bin/env python
from gnuradio import gr
from gnuradio import analog
from grc_gnuradio import blks2
import subprocess

class top_block(gr.top_block):
    def __init__(self):

        # Set parameters
        sample_rate = 32000
        ampl = 0.2

        # Generate a sine wave
        src = analog.sig_source_c(sample_rate, analog.GR_SIN_WAVE, 350, ampl)

        # Set the destination to nc to then send the samples to rpitx
        dst = blks2.tcp_sink(

        # Connect the source and destination
        self.connect(src, dst)

if __name__ == '__main__':

    # Set the target frequency
    freq = 144600

    # Spawn the processes, pipe them together, and run the GNURadio block
        nc_process = subprocess.Popen(["nc", "-l", "8011"], stdout=subprocess.PIPE)

        rpitx_process = subprocess.Popen(["sudo", "rpitx", "-m", "RF", "-i", "-", "-f", str(freq)], stdin=nc_process.stdout)

    except KeyboardInterrupt:

The script generates a sine wave and sends the raw samples to a TCP sink which is then received by nc and piped into rpitx. Though a simple example, more sophisticated configurations could be created using GNURadio’s extensive library of filters, modulators, encoders, etc. I hope to try various digital modulations in the future to see how well the Raspberry Pi performs.


Using the afsk package described earlier I was able to transmit an APRS message using the following command:

aprs --callsign <callsign> --output - "<message>" | csdr convert_i16_f | csdr gain_ff 7000 | csdr convert_f_samplerf 20833 | sudo rpitx -m RF -i - -f 144390

The signal came out loud and clear over the handheld transciever I was using to monitor.

Future work

While this is great news there are still several problems:

  • Raspberry Pi can only transmit
  • Band pass filter is needed
  • Transmission power is very low

The first problem can be solved with a RTL software defined radio dongle which can act as the receiver. Paired with the Raspberry Pi, full-duplex transmission can be acheived. Additionally, band pass filter and amplifier circuits can be found at http://www.minicircuits.com/ to assemble a shield.