This post is about how I set up remote operation on my ham radio through a Wifi network, over a VPN, and around the world using a Raspberry Pi, like this:
This could be useful for people who travel a lot and want to be able to use their rig while away. Or for people who want to set up their radio and antenna far away from where they actually live (e.g. apartment dwellers who have friends or parents who live in the boonies and wouldn’t mind you erecting an antenna). If you want to skip the VPN and just control your ham shack from your kitchen, that’s even easier.
I did this all with an ICOM-7100 all-mode radio, a Raspberry Pi B+, a Buffalo DD-WRT router/VPN server, and a laptop running Ubuntu 15.04. This post focuses on the radio control and networked audio but not on setting up the VPN.
Prerequisites
Setting up the Raspberry Pi
I want the RPi to be a “headless” remote server (no screen, no keyboard), so I need to be able to SSH into it from my client. This is pretty easy. I set up public/private keys so I don’t have to type a password every time I log in. Follow the link to set this up.
If you want your Raspberry Pi to work on wifi, you’ll have to set that up too.
Building PulseAudio 6.0 on the Raspberry Pi
We need to use the PulseAudio linux sound system to pipe audio through the network. PulseAudio 2.0 exists in the RPi repositories, but I had much better luck with a more recent version (PulseAudio 6.0), which I built from source. Following this guide, I got it to work (I skipped the bluetooth stuff). In summary, first install some build dependencies:
1 |
sudo apt-get install -y libltdl-dev libsamplerate0-dev libsndfile1-dev libglib2.0-dev libasound2-dev libavahi-client-dev libspeexdsp-dev liborc-0.4-dev libbluetooth-dev intltool libtdb-dev libssl-dev libudev-dev libjson0-dev bluez-firmware bluez-utils libbluetooth-dev bluez-alsa libsbc-dev libcap-dev checkinstall |
There’s a libjson-c dependency that I had to build myself:
1 2 3 4 5 6 |
git clone git://github.com/json-c/json-c.git cd json-c ./autogen.sh ./configure make sudo make install |
Clean pulse files that may be installed (note: this may break other installed packages like pygame)
1 |
sudo apt-get remove libpulse0 |
Now get the PulseAudio source code and compile. I used checkinstall so I could remove the built package easily later on.
1 2 3 4 5 6 7 8 9 10 11 |
git clone git://anongit.freedesktop.org/pulseaudio/pulseaudio cd pulseaudio ./bootstrap.sh ./configure --prefix=/usr --sysconfdir=/etc --localstatedir=/var --disable-bluez4 --disable-rpath --with-module-dir=/usr/lib/pulse/modules make sudo checkinstall --pkgversion 6.0 --fstrans=no sudo addgroup --system pulse sudo adduser --system --ingroup pulse --home /var/run/pulse pulse sudo addgroup --system pulse-access sudo adduser pulse audio sudo adduser root pulse-access |
Then I built the init.d script as in the link above to get pulseaudio to auto-start in system mode (yes, it says this isn’t recommended, but it makes sense on a Raspberry Pi). Start PulseAudio by rebooting or just using
1 |
sudo service pulseaudio start |
Configuring PulseAudio to pass sound from the Raspberry Pi through the network
On the Raspberry Pi, edit the /etc/pulse/system.pa
file and uncomment or add a line to turn on module-native-protocol-tcp, authorizing the local network to communicate with it.
1 2 |
### Enable networked audio load-module module-native-protocol-tcp auth-ip-acl=127.0.0.1;192.168.0.0/16 |
I also found it useful to comment out the module-suspend-on-idle line in there as it caused some 10 second lags at first.
Plug the radio into the Raspberry Pi and restart PulseAudio with:
1 |
sudo service pulseaudio restart |
Configuring PulseAudio on the laptop/client
On Ubuntu, PulseAudio runs on a per-user basis, not in system mode. As such, we can turn on and off modules with scripts, which is just what we’ll do. Make a script and put commands like this in it:
1 2 3 4 5 6 7 8 9 10 11 |
#!/bin/sh pactl load-module module-tunnel-source server=raspberrypi source_name=icom_source pactl load-module module-tunnel-sink server=raspberrypi sink_name=icom_sink # radio -> laptop speakers pactl load-module module-loopback source=icom_source # laptop microphone -> radio pactl load-module module-loopback sink=icom_sink source=alsa_input.usb-0d8c_C-Media_USB_Audio_Device-00-Device.analog-mono |
You will have to adjust the hostname of your Raspberry Pi (or just type in its IP address directly). You will also have to adjust the source of the second loopback module. I have it set to my USB microphone, but your laptop microphone will be different. Use the pacmd list-sources command to get a list of sources on your laptop and just take the name of the one you want. Make the script executable like this:
1 |
chmod +x radio_pulse.sh |
You could also enable networking in this script, but I find it more convenient to use the paprefs program and just select “Make discoverable PulseAudio network sound devices available locally”.
Finally, you have to set up authentication. PulseAudio uses a shared secret called a cookie to authenticate. Copy the cookie from the RPi at /run/pulse/.config/pulse/cookie to ~/.pulse-cookie on your client computer (in the home directory). Now it will authenticate.
Restart PulseAudio on your client with
1 |
pulseaudio -k && sudo alsa force-reload |
Now, run the script created above. If all goes well, you should now hear the sound from your radio on your laptop. You may have to make some adjustments in the pavucontrol program. Turn down the radio squelch so there’s something coming through and then, on the playback tab, select Show: All Streams and make sure the loopback from the Raspberry Pi is playing on the device you want it to be playing on. It should look like this:
You can also run pavucontrol for the RPi from your client like this:
1 |
PULSE_SERVER=raspberrypi pavucontrol |
And then you can adjust the connections on the RPi side of things if necessary. I don’t think you’ll have to do this.
If you’re using a IC-7100 too, make sure you have it set either to DATA mode (FM-D) or in such a way that the USB audio will make it into the transmitter. Now you can do voice and digital modes through your network! Cool. Here’s a screenshot of running fldigi on my laptop, receiving audio in this kind of a setup.
Recall, at this point, we’re on a local network. We’d have to set up the VPN to go outside of our home through the internet.
Controlling the Radio from afar
If you just want to do digital modes through fldigi, you’re probably good to go at this point. You can have flrig running on the Raspberry pi and fldigi running on the client, and they will be able to communicate and key up the radio and stuff. But I wanted to do voice as well. So what to do?
Well, being a programming nerd, I thought it’d be fun to write my own little controller for the IC-7100. I did this in Python. It’s hosted on github. So far, it’s exceedingly simple, but it allows me to turn the radio on and off, go to different memory channels, turn DATA mode on and off, and key up the radio. This is a good start, but I hope to make it much more sophisticated later. I especially need to be able to type in the frequency I want or scan up and down the bands for HF. This should be easy to add. If you want to use it, feel free. But don’t expect much. If you want to improve it, please do!
There are also other programs out there that offer the ability to control a radio through the network.
Troubleshooting
I gone through many iterations and come across many problems while figuring all this out. At first, I did the PulseAudio configurations on the RPi but I eventually decided doing it on the laptop was more flexible. I tried very hard to get downsampling to work to minimize the required bandwidth. This is important for slow wifi networks but especially important when going over the VPN to the internet. I played a lot with resampling methods and took it down to 11025 sample rate. It works and sounds fine for a while, but it kept fading out every few minutes. I haven’t quite solved this issue.
To downsample, change your tunnel source to be:
1 2 |
pactl load-module module-tunnel-source server=tau.partofthething source_name=icom_source rate=11025 pactl load-module module-tunnel-sink server=tau.partofthething sink_name=icom_sink rate=11025 |
This uses about 60 KiB/s over the network, as opposed to 200 KiB/s with the defaults.
To adjust the sampling methods, edit /etc/pulse/daemon.conf on the Raspberry Pi and change the resample-method = speex-float-1 setting.
In certain resampling conditions, PulseAudio uses too much of the RPi CPU.
The biggest problem is that over a VPN, there are a few seconds of delay as the audio travels through the internet.
If you’re experimenting with different settings, you can unload all the PA modules on your laptop with commands like
1 |
pacmd unload-module 32 |
Where 32 is the index of the module to unload. Use pacmd list-modules to list all loaded modules. I do this a bunch as I tweak my script and rerun it.
Securely connecting to the LAN from afar with a VPN
A VPN will let you securely connect to your local network through the internet as if you were sitting in your kitchen, even though you may be in Paris. This unlocks the potential of the remote radio-through-RPi thing, as it allows you to do it all from everywhere.
Conveniently, I already had a “road-warrior” OpenVPN set up on my WRT-based router. This means I can connect to my home LAN at anytime from anywhere securely. I do this to print stuff from afar, talk to my internal devices, and avoid surveillance while on public or other untrusted networks. This is a non-trivial step that involves getting a WRT-compatible router, flashing it with a ROM that has an OpenVPN server (like OpenWRT or DDWRT), building some public/private keys, and configuring the server and clients. It’s not THAT hard, but definitely took me a while to get it working due to the large number of slightly different instructions available online. The GUI-based config in recent DDWRT builds makes it pretty easy. Get started with this guide (slightly outdated) and build some RSA keys and flash your router. Then go to this other guide that’s very close to what I actually did. Go buy some wifi security cameras while you’re at it because you can now securely connect to them and watch your home while you’re away.
I hope this helps someone. It was a lot of fun for me to figure out.
73!
Have you had any issues with the number of the ttyUSB port incrementing if you lose connection? I haven’t tried using Linux and my IC-9100 (which I believe uses the same USB chips as the IC-7100) on OS-X increments the serial number every time the connection changes. It’s a problem with how the USB port driver works, so I imagine it’s just a problem with OS-X, but want to make sure.
I noticed that as well on Linux. One thing you can do (at least on Linux, so you can probably do it on Mac as well) is make an alias for the IC-7100 that always gets a name. For instance, you could name it
/dev/ic7100
. See instructions here.My rule looks like this:
SUBSYSTEM=="tty", ATTRS{idVendor}=="10c4", ATTRS{idProduct}=="ea60", SYMLINK+="ic7100"
Hi Nick. I have a very similar setup running at home (http://alloutput.com/amateur-radio/remote-transceiver-operation/) and have run across your page while searching for tips on running Pulseaudio through VPN because I’m about to try running my setup across the Internet. I have some questions about your VPN config, maybe you could drop me an email if you have a chance? Great page, thanks for sharing!
This is awesome!
I’ve just sold enough stuff to order a new IC-7100 (on sale under $800. via GigaParts this November).
I’m planning an IF tap to feed a SDR into the PC in order to gain some features.
This goes between the IF and the SDR – I will probably need to add a filter https://www.ebay.com/itm/DC-12V-10KHz-1GHz-10dBm-RF-Broadband-Low-Noise-Amplifier-LNA-Module-HF-VHF-UHF-/182183408801
I’m really interested in remote operation from the EOC to test ARES setups – so your Raspi article was a timely find for me!
I’ll be checking back for updates & will share the page.
Thanks!
I have been considering remotely operated radios for disaster areas. I have not personally worked a disaster area, but do not see the sense in adding an on-site ham operator, for each radio, to assist a person communicate out of the area.
It seems to me that with the radios that take remote commands, an area could have only a couple hams on site consuming resources, and have a bunch of remote assist guys sitting at home while talking or messaging the people through the process of communicating with the outside world.
Good ideas in this article.
Just out of curiosity, how would this work exactly? A disaster stricken area is usually temporarily devoid of any kind of internet access site, especially at a bandwidth that would support a voice and CAT link. And if internet access was available, then the area wouldn’t need backup HF communications.
Can I get a downloaded copy of Ham Radio Remote for a Pi?
Ham radio operation through a Pi
For sure. My code is here on github: https://github.com/partofthething/radio-controller
It’s not polished in the least and probably needs some programming experience to get it working.
I’m encouraged by this.
I would like to get a 7100 as my first HF rig and set up an SDR/panadapter. But mainly I am interested in Winlink for my local ARES. I could also afford running the radio from the shop, or placing the radio in the shop and running it from the house/desk-shack. This is helpful and right up my alley.
Thanks
This is awesome to read and to find! I have been doing reading and searching since I got my license last fall. I just ordered my first HF radio, 857D, for my truck. I’m in hopes of connecting it and using it with a RPi3 touch screen setup to enhance its abilities, and mine. Thanks for the extra reference! This does help to fill in a few blanks or holes in my plan.
hi how are you
i want to ask about the pins you used to connect the radio to Raspberry Pi
please give me a picture to the pins in the radio and Raspberry Pi
I just plugged the radio into the Pi’s USB port. The 7100 has a USB port.
WANTED TO HIRE:
Ham into RPi.
I need help for using a SMALL SDR+RPi+5GHz WiFi for downlink/remote control of SDR.
Call for more details.
Paid project.
Call Mitch K8UR@yahoo.com
443-926-2541
New Bern, NC
Hi Nick,
excellent article and a good starting point. Setting up the RaspPi, enabling that VNC thing and so on was easy.
I wonder if you suffer from delay in the audio routed through PulseAudio to your laptop, how FLDigi would work in modes, which depend on a precise time sync like FT8? Wouldnt FLDigi take your laptops time and thus in turn no received signal ever be decoded?
In addition I would like to add – for those interested in a cheap method to run voice QSOs from abroad – that I found an almost comfortable way:
Assumption:
– FLRig is setup on RaspPi
– RasPi is connected to your radio either through USB only or in addition (if required) through an USB sound card with speaker/ out + mic/ in
– FLRig & your TRX work properly hand in hand at least for the most common and important controls
I did not find any way to use PulseAudio on my smartphone. I tried with Skype and similar stuff first, but this had many disadvantages, as they are: Audio is routed from/ to RaspPi and Smartphone through the service providers servers and causes too much delay. Skype itself has no native app running on RaspPi.
By random my DSL/ home phone provider had run an update on its technique and I got a letter with several credentials in order to reconfigure my router. Here in Germany nowadays its almost always VoIP services when it comes to landline phones. Usually they include 3 different phone numbers in a contract.
I use one for the default phone, the second to make my router accept facsimile and the third had no use – up to now.
When looking for alternatives to PulseAudio and Skype I became aware of LinPhone. At first sight I thought I would have to install that on every device in order to communicate between the latter. Actually, thats not the case.
I installed LinPhone on the RaspPi and during the setup procedure I was asked whether I would like to register with some SIP service or whether I already would have any such credentials. Thats when I recalled my landline phone providers letter.
I configured LinPhone by entering the SIP credentials of my ISP for the unused third landline phone number.
It took some time to figure out the best settings for the soundcard and the SSB DATA GAIN of the radio, but finally I can:
– call my landline number
– take the call at the RaspPi through the VNC
– listen to and control the radio that way
– easily understand transmissions, as long as their signal is fairly above noise level, since the USB soundcard has an AGC in place permanently on the mic/ line in (radio rx out)
– toggle PTT through VNC and leave a call or having a chat on air with the audio passed through the VoIP/ SIP service of my ISP
As the VNC is password secured, its only me being able to take a call
and control the radio.