Hamlib and Software Defined Radio

July 2012.  The software discussed below is available here as hamlibserver.py.

Hamlib

Many radios have a serial port that can be used to control or query the radio.  Querying the radio is useful for a logging program, so that the log can show the correct frequency, band and mode.  Controlling the radio with a computer program can be useful for scanning the VHF/UHF bands for repeaters, or for controlling the radio using a PC screen.  The problem is that different radios have different serial port command languages.  Hamlib is software that facilitates writing computer control software for ham radio equipment.  The idea is that a software developer writes code to talk to Hamlib, the user tells Hamlib the model of the radio, and Hamlib figures out how to talk to that radio.   Hamlib 1.1.0 alpha was released in January 2001 with support for three rigs.  Since then support for many more radios has been added, and Hamlib is used by major softwares such as Fldigi, Xlog and WSPR.  Hamlib is a great project, and the developers deserve much credit for furthering the state of the art in ham radio.

The Problem

I use a Software Defined Radio at my shack.  Like many other SDRs, it consists of a hardware box attached to a PC.  The PC generates the transmit signal, sends it as I/Q samples to the hardware box, and the hardware transmits it.  My hardware does not have a serial port, but it has an ethernet connection, and I can write an interface for Hamlib so that Hamlib can query and control my hardware.  Unfortunately that is not very useful.  The problem is that the hardware does not know the information I need.

Suppose I want to know the mode; CW, SSB or AM.  My hardware generates its own CW, so it knows if the mode is CW or not.  But it does not know the difference between SSB or AM because both are sent as I/Q samples, and it just blindly transmits any samples it gets.  Since the frequency is sent to the hardware, it seems that at least it could report the frequency, but even that is incorrect.  The hardware does indeed have the transmit frequency, but it does not know the receive frequency.  It sends samples with a certain bandwidth (perhaps 48 or 96 kilohertz) but the PC can receive any signal within this bandwidth.  The hardware only knows the center frequency of the bandwidth it sends to the PC, not the actual frequency that the PC is decoding.

Since the PC is really in control, we need a way for Hamlib to query and control the PC program.  Only the PC program has all the information we need, and the ability to change the radio modes, frequencies and other settings.  So we need a way for one program (for example a logging, scanning or control program) to talk to another program, the SDR control program.  This is not a new idea.  If you look closely at Fldigi you will see that besides Hamlib control it has a protocol called XML-RPC that is specifically designed to talk to other programs.  I added an XML-RPC client to my Quisk software so that Quisk could work with Fldigi.  But what about programs such as WSPR and Xlog that lack XML-RPC but have Hamlib capability?

Connecting to Hamlib

We need a way to connect a client using Hamlib (for example, a logging program) to Quisk or another SDR control program.  Fortunately Hamlib has two programs to help us out.  The rigctld program was designed to share the serial port among various Hamlib clients.  That is, the user runs rigctld, rigctld connects to the rig using a serial port, and then clients connect to rigctld.  Note that this means the clients are connecting to another program, just what we need.  The client specifies rig 2, manufacturer "Hamlib", model "NET rigctl".  Rig 2 means the program rigctld, and communication is TCP to host "localhost" port number 4532.  Hamlib also provides the rigctl program to test connections to a rig, including rig 2.  Just run "rigctl -m 2 -r localhost:4532".  The rigctld protocol is simple.  For example the "f" command returns the frequency, and the "F 7100000" command sets the frequency to 7.1 MHz.  See the Hamlib documentation for details.

I propose to implement a TCP server in Quisk or other SDR control program that acts like the rigctld server.  The client connects to Quisk using rig 2 and the address "localhost:4575".  Note that the port is different to avoid interfering with rigctld.  If the user runs rigctld, then rigctld can connect to Quisk using this different port.  Different SDR control softwares and rigctld can all run at once provided different ports are used, although I do not see why this would be useful.

The Software

The file hamlibserver.py is a reference implementation of a rigctld work-alike, is released under the GNU General Public License, and is provided in the hope that it will be useful to other SDR software authors.  It is only about 260 lines, and implements the simple and extended rigctld protocols.  See the comments in the file for documentation.  To run the server, open a terminal window and enter "python hamlibserver.py".  To exit the server, type Control-C.  Now you can test the connection with "rigctl -m 2 -r localhost:4575".  Only a few commands are implemented.  Try the "f" and "m" commands to get the frequency and mode.  You can also connect any Hamlib clients you have.  I use Xlog, a logging program, and it connects and works fine.  Of course this program is a toy, and not useful by itself.  I plan to paste it into Quisk, and then Quisk can be controlled by any Hamlib client.

Are We There Yet?

I need to get my Hamlib server into Quisk and test some more clients, but I can see some problems ahead.  I downloaded the currect Windows version of WSPR, and it seems that rig 2 is not available.  I guess rig 2 is new and the Hamlib files in WSPR are old.  It seems that there should be a way for a user to install Hamlib and for clients to use it.  Then the user could update Hamlib and the client would use the new version; but I don't know how to do that.  Hopefully the various Hamlib clients will update their Hamlib files.

Other clients are written to have a menu of serial port choices, but not a way to set the device for rig 2 to "localhost:4575".  In Xlog, you can set the "Attach to Device" box to an arbitrary string, and this works for rig 2.  Other clients may or may not be able to set this device even if rig 2 is available.  In that case, it may be necessary to run the Quisk server on the default port 4532.

There is only minimal information that goes between Quisk and Hamlib for most clients; just the frequency, mode and PTT.  The real problem is sending sound samples between programs.  Clients like Fldigi expect to connect to a sound card, not another program.  So to connect Quisk and Fldigi, you must install a "fake" sound card; a loopback device on Linux, or a VAC on Windows.  Since sound cards are painful on PCs this is undesirable.  And you must throw away your beatiful I/Q samples and send mono audio, adding insult to injury.  There must be a standard way to send/receive stereo audio between two programs, right?  And correct for differences in the clock rates too?


Copyright 2012 by Jim Ahlstrom, N2ADR.  This document is free for public use.