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 ./configure make 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): gr.top_block.__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( itemsize=gr.sizeof_gr_complex*1, addr="127.0.0.1", port=8011, server=False, ) # 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 try: 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) top_block().run() except KeyboardInterrupt: pass
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.
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.