This page began life as my online notes while setting up this project to remote my Elecraft K2 HF transceiver via my home network. I leave this page online because some of the ‘trial-and-error’ notes and references made may be useful to anybody trying to implement this themselves… please see my main project page for details of my current setup.
The method used should apply to pretty much any amateur transceiver that can be remote-controlled by serial port. Note the aim of this project is to operate the radio across a LAN where bandwidth is plentiful as opposed to many remote radio projects that are aimed at operation across the Internet. Space constraints and family life prevent me from having a dedicated ‘shack’ set up in the house so this is my solution – a small HF radio setup tucked away in a utility cupboard but accessible via the home wireless network allowing operation from a laptop computer. Two main aspects:
- Serial-over-IP for control of the radio
- Bi-directional streamed audio for transmit and receive audio
I already use remote desktop (VNC) methods for controlling radio receivers but haven’t found it responsive enough with the hardware I have for use with a transceiver. Also, using a ‘full size’ PC is prohibitive to my personal aim of fitting my transceiver equipment into a small cupboard. Instead, the aim here is to use a lightweight Linux computer (e.g. Raspberry Pi or BeagleBone) with a USB soundcard interface (e.g. Tigertronics SignaLink USB). Big credit to the Remote QTH project for pointers. The general idea:
- Serial-over-IP …complete!
- Hamlib and rigctl …an interesting aside…
- Audio Streaming …in testing…
- Video Streaming …complete!
Check out this how-to…
Serving the port:
There appear to be two obvious ways to create a serial proxy server on the RPi, ser2net and socat.
A line like this can get the device served out from socat:
sudo socat -d -d -d tcp-l:4001 pty,link=/dev/ttyUSB0,nonblock,raw,echo=0,waitlock=/var/run/tty,b4800,cs8,cstopb=1,parenb=0
…but I haven’t gone much further with this yet as ser2net seems to be working nicely. Note, the “-d -d -d” option in my socat lines turns on the 3rd level of debugging output which is useful to see if you’re not sure whether the nodes are connecting across the network.
Results so far
(work in progress!)
|Connects OK, good results with grig. Have to run other client applciations as root and FLRig/FLDigi don't connect. This is my current serial connection method.
|Windows: HW VSP3
|Connects OK, have control but a bit slow and not always responding...
|Connects OK, not played with this much.
|Windows: HW VSP3
Connecting to the port from a Linux client:
socat can connect to ser2net configured as above with this command:
sudo socat -v -d -d -d TCP4:192.168.1.101:4001 PTY,link=/dev/ttyS1,b4800,cs8,cstopb=1,parenb=0
I can access ttyS1 by running cutecom as root (but not as a normal user…?) and send and receive messages to/from the K2’s serial interface: Now, most excitingly, I can use grig to connect to and control my radio. The grig command for Elecraft K2 should be something like:
sudo grig -m 221 -r /dev/ttyS1 -s 4800 -d 3
Tryed adduser (me) to both the ‘dialout’ and ‘tty’ groups, no joy. Interestingly, the ttyS1 port doesn’t appear here when socat is linking it to the IP network: Think I need to be a member of group ‘lock’ to allow access to /var/lock…? In this page it mentions being able to write to /var/lock for control of serial ports… but Crunchbang doesn’t have a ‘lock’ group…? The best so far: AB3AP’s excellent K2 Control java application runs perfectly in Linux and when run as root can connect to the ttyS1 port I have socat linking to the serial proxy (ser2net) server giving me full control of the K2, filters, menus and everything. I have implemented mousewheel-scrolling of the dial frequency using easystroke, a gesture recognition application for Linux. It’s early days but this looks like the way to go for me.
Connecting to the port from a Windows client:
Tried com2tcp but some trouble getting it to build in MS Visual C++ 2005… HW Virtual Serial Port installs easily and works a treat – I now have control of my K2 via Raspberry Pi over the network! So far I have had FLRig successfully controlling the radio but Ham Radio Deluxe v5 has failed to read the radio frequency via the virtual COM port so this isn’t perfect yet…
Hamlib and rigctl
Hamlib actually offers functionality to run commands over the network so its rigctld service can be used as an alternative to the above method. This excellent page shows how. I’m currently looking into what rig control GUI software can access rigctld across the network. Grig can do it with the following commands: At the server (Raspberry Pi, note “221” is the code for my Elecraft K2 radio):
sudo rigctld -m 221 -r /dev/ttyUSB0 -s 4800
Run grig at the client (Linux PC, note the rig code is now “2” for Hamlib NET rigctl):
grig -m 2 -r <SERVER-IP>
And with this in mind fldigi connects to the server’s IP address, port 4532, rig type “Hamlib NET rigctl”: At the moment, grig appears solid in controlling the radio (although it only offers a limited subset of functionality e.g. no filter control, PTT button is ghosted…) but fldigi seems to be a bit flakey in this mode with frequent timeouts from hamlib. CQRLog also works into hamlib across the network but only offers limited control of the radio.
Note – the instructions below have now been superceded by using an RPi with Arch Linux (ARM) and pulseaudio 5.0 installed and this is working well. I leave these notes on this page as it may prove useful to anyone trying this, interested in the process, troubleshooting or maybe to the future-me trying to remember how I got all this working…
First steps, identify my sound hardware. I have my Tigertronics SignaLink USB connected to my Raspberry Pi. I have followed some of this thread to modify /etc/modprobe.d/alsa-base.conf
- Enabled snd-usb (change the line that sets its index -2 to 0 or uncomment that line)
- Could disable the built-in snd-bcm2385 here but I haven’t yet…
From here “speaker-test -c2 -D hw:0,0” does play some pink noise out of the left side (mono) of the SignaLink’s MON port (this would be my transmit audio). Interestingly, the VOX PTT doesn’t activate when this is playing – this is because the level coming out of the speaker-test is too low to activate the VOX. Looking at the devices in alsamixer shows the USB soundcard and the standard RPi audio device:
First trying to get some audio from the SignaLink’s input (SPKR) streamed across the network to my client PC. This method seemed way too simple (surely it can’t be this simple?!) and indeed it doesn’t quite work at the moment but it does stream what sounds like sped-up audio with clicks and errors so something’s working there. Recording and playing audio as described there also seems to have some erroneous rates so there could be some further experimentation to be done here…
I’ve had some progress with setting up a pulseaudio server on the RPi and accessing that from my client PC. These two threads have provided guidance here:
My steps have been:
sudo apt-get install pulseaudio pulseaudio-module-zeroconf alsa-utils avahi-daemon
Modify /etc/pulse/deamon.conf to set exit-idle-time = -1 to stop pulseaudio timing out. Modify /etc/pulse/default.pa to include (or un-comment) the lines: load-module module-alsa-sink device=hw:0,0 load-module module-alsa-source device=hw:0,0 load-module module-native-protocol-tcp auth-ip-acl=127.0.0.1;192.168.1.0/24 load-module module-zeroconf-publish …and disabled “Automatically load driver modules…” in favour of the manually specified ALSA sink and source above which point to my USB soundcard that I’ve set as device 0. I now start “pulseaudio -vvv” on the RPi (the -vvv option gives me the commentary to provide some clues as to what’s happening). Very quickly after this, the source and sink appear in my client PC volume control as “PCM2904 Audio Codec on pi@RPi-K2” under the Input Devices and Output Devices tabs. I can now start up FLDigi using the normal Port Audio (default) sound card settings (that I believe hook up to the local pulseaudio system on the client PC).
Back in the volume control, Recording tab, “PCM2904 Audio Codec on pi@RPi-K2” can be selected as the input to FLDigi. Similarly, once some output is created from FLDigi (e.g. hit the CQ or Tune button), on the Playback tab “PCM2904 Audio Codec on pi@RPi-K2” can also be selected as FLDigi’s audio destination. This gets the audio input and output of FLDigi on my client PC connected across the network to the SignaLink/ RPi. If the audio level is high enough (controlled by the client PC volume controls) the VOX PTT on the SignaLink is activated.
To start with I’m feeding a loop of recorded PSK31 audio into the SPEAKER port of the SignaLink, simulating reception. Transmit audio is monitored with headphones on the MON port. Initial performance was not great with visibly choppy audio on the FLDigi waterfall and similarly clicky sounding audio at the SignaLink/ RPi on transmit. Quality of the receive audio (RPi to Client PC) has been improved by applying this firmware downgrade to the RPi:
sudo rpi-update eeb2e51c3e08cd5efa4246aa8dc54a09b25ada12
Receive audio is now good enough for FLDigi to successfully decode: There are still some clicks visible on the receive waterfall (I haven’t set up anything to actually monitor the receive audio yet) but the decode is a big improvement and it could be workable. Transmit audio still sounds unusable with strong clicking and interrupts. Areas to investigate for improvement:
- TCP isn’t typically a good transport for audio. Can I use RTP?
- The RPi shares the USB bus with its Ethernet adapter and this can be an area of conflict. How does this technique perform on other hardware e.g. swap the RPi for a spare laptop? Tried on an IBM T41 laptop running Crunchbang, improvement on receive audio (RPi source to Client PC, 100% copy), no change in transmit.
- There are a lot of ALSA wakeups and underruns visible on the pulseaudio commentary, are these clues?
- Can I tweak sample rates or buffer sizes for better performance?
I’ve tried the tunneling method outlined in the above link but couldn’t see any difference in behaviour. I have performed the ‘renice’ procedure to prioritise the pulseaudio application on the RPi:
chmod u+s /usr/bin/pulseaudio
usermod -aG pulse-rt pi
@pulse-rt hard nice -20
@pulse-rt soft nice -20
Receive audio (RPi source to Client PC) now looks really good, no apparent glitches on the waterfall, but transmit audio (Client PC to RPi sink) is still choppy. If I can get the same performance in both directions that will be OK. Another problem is I’m clearly pushing the RPi at the moment. When I initiate a serial-over-IP connection with the pulseaudio server running there is a noticeable degradation in the received audio, copy becomes broken in FLDigi. This may again be a shared USB/ Ethernet bus thing or I might be running the RPi too hard… If I can’t iron this out then solutions could be to move to a more powerful device (there’s a lot of talk about the BeagleBone Black at the moment but no availability and new Single Board Computers seem to be coming out all the time) or get another RPi and run audio on one, serial and video on another one, I mean they’re cheap enough! 🙂
Playing a PSK31 sound sample wav file from VLC at the client to the Pulseaudio sink plays cleanly on the SignaLink and PTT is solid when the level is set to 100%…. so why doesn’t this work for fldigi playback? Fldigi configured to connect to a Pulseaudio server at 127.0.0.1 improves things but transmit audio has clicks on it so not usable yet… Trying an alternative to fldigi, gmfsk which may transmit sound using a different mechanism. To get gmfsk working in Crunchbang linux I have had to install the oss-compat package, reboot, then run:
sudo modprobe snd-pcm-oss
After doing this, gmfsk can successfully use its default sound device /dev/dsp. This gets gmfsk working with the onboard sound card on my laptop BUT using the legacy OSS sound system and gmfsk doesn’t appear in the list of applications on my system volume control. This is solved by installing osspd to act as a proxy to route OSS to the pulseaudio server on my laptop. The padsp utility probably also does the same thing.
Note: at this point pulseaudio-utils packages were updated when osspd was installed, this may have cured a local pulseaudio problem at the laptop…
I am now hearing good transmit audio from gmfsk configured to /dev/dsp (the proxy to local pulseaudio server), connected to the remote source/sink via the local Volume Control panel. Unfortunately it seems receive audio via the OSS proxy has just enough distortion on it to reduce a sample PSK31 wav file to about 80% copy, not good enough to work. I am now also hearing good transmit audio from fldigi configured to the local pulseaudio server 127.0.0.1, connected to the remote source/sink via the local Volume Control panel. Receive audio looks near perfect on the waterfall and I have 100% copy on the sample PSK31 wav file… I’ll tentatively say this could be the successful configuration… but I have spotted the occasional underrun/rewind glitch at the RPi server end so it needs some testing… 🙂
Have tried commenting out the load-module-suspend-on-idle line in /etc/pulse/default.conf but that stops the whole thing working so clearly doesn’t solve my ‘sleeping sink’ problem where I get stuttering transmit audio occasionally. This is currently worked around by the fact that the next transmission comes across clean so if I spot the problem on the power meter video I can quickly switch back to receive and re-transmit the message cleanly.
Here I ran into some problems decoding PSK signals. Monitoring the audio it sounded OK to the ear but the PSK decode performance wasn’t 100%. RTTY decoding was fine. I have traced this to an old pulseaudio version – at the time of writing, the Raspian distro installs pulseaudio 2.0. PSK decode performance seems to be fixed by running pulseaudio 4.0 or later which I discovered by substituting my netbook running Linux Mint 16. I am now experimenting with Arch Linux on the RPi which installs pulseaudio 5.0 – PSK decoding looks good and I have logged my first two-way contact with this setup so it clearly can work!
According to the Pulseaudio Network Setup page the stream across the network is actually raw PCM so the problem probably isn’t lossy compression but may be network related, sample rate/processing power or reconstruction at the client (resampling method?) Tried wired LAN connection, no better. Trying direct connection of FLDigi to the RPi pulseaudio server, copied the .pulse-cookie file over from the RPi (which might have been the previous problem with this…). Setting FLDigi’s Pulseaudio server setting to the RPi’s IP address says “Pulseaudio error: Connection refused” at fldigi BUT it can be seen connecting to the server at the RPi -vvv terminal output… is it not connecting to the correct sink/source at the RPi…
Trying disabling tsched on the source (add tsched=0 to the alsa-source line) – no improvement
Trying my Samsung netbook as the audio server, perfect audio reproduction at the client… is this a RPi USB/Ethernet streaming limitation then? Time for a BeagleBone Black? Try lowering the sample rate to reduce the traffic? Are the serial or video streams interfering at the client?
Pulseaudio tunnel from RPi is giving PSK errors, tunnel from Linux Mint 16 netbook is good in a direct comparison using two identical soundcards fed with the same audio and A/B switching stream between the two sources. What is the difference? There are a few differences but the pulseaudio version proved to be the deciding factor. As stated above, I am now running Arch Linux (ARM) on the RPi with pulseaudio 5.0 installed and PSK signals are decoding perfectly, see my main project page.
This part of the project may seem a little frivolous but I would like a video feed included in the setup for live monitoring of a cross-needle Power/ SWR meter. This will give me important feedback on the real state of the radio’s transmission and indication if there is any problem with the antenna. I have a Raspberry Pi Camera Module connected to the RPi. Initial tests showed a lot of latency with the raspivid method suggested on the RPi website. I tried some adjustment of resolution and frame rate to try and improve things but internet searches suggested using the gstreamer tools for low latency streaming. I’m no expert here but, after some perseverance, I have this working nicely from the RPi to Linux clients (Linux Mint 14 includes gstreamer1.0 by default, I had to add in a repo, deb http://ftp.uk.debian.org/debian sid main, to get gstreamer1.0 installed on CrunchBang). This page shows how to set up the gstreamer server on the RPi, this page shows a command line for a Mac or Linux client that works for me at least. On the RPi server:
raspivid -t 0 -h 320 -w 480 -fps 25 -hf -b 2000000 -o - | gst-launch-1.0 -v fdsrc ! h264parse ! rtph264pay config-interval=1 pt=96 ! gdppay ! tcpserversink host=YOUR_RPI_IP_ADDRESS port=5000
On the client PC:
gst-launch-1.0 -v tcpclientsrc host=YOUR_RPI_IP_ADDRESS port=5000 ! gdpdepay ! rtph264depay ! avdec_h264 ! videoconvert ! autovideosink sync=false
One thing that remains here is to construct a mount that places the RPi camera at a fixed distance from the power meter. I also need to attach a lens to focus the camera on the meter that will be about 10cm from the camera to fill the field of view. Some people have been successful with cheap macro lenses for mobile phone cameras or even cheap reading glasses so some experimentation is required…