Hamlib and rigctld on Linux — Complete Rig Control Setup and Integration Guide
Hamlib is the universal rig control library for Linux amateur radio software. This complete guide covers installation, connecting your radio via USB and serial, finding your rig's model number, testing with rigctl, running rigctld as a shared rig control daemon, integrating Hamlib with Fldigi, WSJT-X, CQRLog, TLF and other applications, PTT control methods, troubleshooting serial port and permission problems, and a complete model number reference for popular radios.
- What is Hamlib and why it matters
- Installation on Ubuntu and Debian
- Connecting your radio — USB and serial
- Serial port permissions
- Finding your rig's Hamlib model number
- Testing with rigctl
- Running rigctld as a shared daemon
- PTT control methods
- Integration with Fldigi, WSJT-X, CQRLog and TLF
- rigctld as a systemd service
- Model number reference — popular radios
- Troubleshooting common problems
- Frequently asked questions
What is Hamlib and why it matters
Hamlib is a shared library that provides a common programming interface for controlling amateur radio transceivers, receivers, and antenna rotors from Linux software. Without Hamlib every application would need to implement its own radio control code for every supported rig — with Hamlib all applications share the same driver library, so when Hamlib adds support for a new radio every application that uses Hamlib immediately gains support for it too.
In practice Hamlib is the invisible backbone of Linux ham radio. Fldigi, WSJT-X, JTDX, CQRLog, TLF, GQRX, Direwolf, Gpredict, and virtually every other Linux ham radio application that needs to control a radio does so through Hamlib. If your rig works with Hamlib it works with all of these applications.
The two main components you interact with as an operator are:
- rigctl — a command-line tool for sending individual commands to a radio. Used for testing and scripting.
- rigctld — a daemon that runs in the background and provides rig control to multiple applications simultaneously via a network socket on port 4532. This is the recommended way to share a radio between several applications.
Installation on Ubuntu and Debian
Ubuntu 22.04, 24.04 and Debian 11, 12
sudo apt update
sudo apt install libhamlib-utils libhamlib-dev libhamlib4
This installs the Hamlib runtime library, development headers (needed if you build applications from source), and the command-line utilities including rigctl and rigctld.
Build from source (latest version)
The repository version may lag the latest Hamlib release, which can mean missing support for newer radios. Build from source for the most current rig support:
sudo apt install git build-essential libusb-1.0-0-dev \
libtool autoconf automake pkg-config
git clone https://github.com/Hamlib/Hamlib.git
cd Hamlib
autoreconf -fi
./configure
make -j$(nproc)
sudo make install
sudo ldconfig
Verify installation
# Check version
rigctl --version
# List all supported rigs (over 400 models)
rigctl --list | head -30
Connecting your radio — USB and serial
Modern radios with built-in USB (IC-7300, FT-991A etc)
Most modern HF transceivers have a built-in USB interface that presents as a USB serial port on Linux — no drivers needed, plug in the cable and it works. The radio appears as /dev/ttyUSB0 or /dev/ttyACM0:
# List USB serial devices
ls /dev/ttyUSB* /dev/ttyACM* 2>/dev/null
# Or watch for new devices when you plug in the radio
dmesg | tail -20
# Look for lines like:
# usb 1-1.2: New USB device found, idVendor=10c4, idProduct=ea60
# ttyUSB0: USB Serial Device
Older radios with RS-232 serial or USB-to-serial adapter
Radios with RS-232 CAT ports connect via a USB-to-serial adapter (CP2102 or FTDI-based adapters work well on Linux). These also appear as /dev/ttyUSB0. Check which port appeared after plugging in:
# Before plugging in
ls /dev/ttyUSB*
# Plug in the adapter, then:
ls /dev/ttyUSB*
# The new entry is your adapter
Multiple serial devices
If you have multiple USB-serial devices connected (radio, CW interface, rotor controller etc) Linux assigns them in order of connection — /dev/ttyUSB0 for the first, /dev/ttyUSB1 for the second, and so on. The assignment can change on reboot if devices are connected in a different order. Use udev rules to assign persistent names:
# Find your radio's USB VID:PID with: lsusb
# Example for IC-7300 (Silicon Labs CP2102):
SUBSYSTEM=="tty", ATTRS{idVendor}=="10c4", ATTRS{idProduct}=="ea60", \
SYMLINK+="ic7300"
# Now your IC-7300 always appears as /dev/ic7300
# regardless of what other USB devices are connected
sudo udevadm control --reload-rules
sudo udevadm trigger
Serial port permissions
By default Linux serial ports are only accessible to root and members of the dialout group. This is the single most common cause of Hamlib connection failures — your user is not in the dialout group.
Add your user to the dialout group
# Add current user to dialout group
sudo usermod -a -G dialout
# Log out and back in for the change to take effect
# Verify the change worked:
groups
# dialout should appear in the output
Verify port permissions
# Check port ownership and permissions
ls -la /dev/ttyUSB0
# Should show: crw-rw---- 1 root dialout ...
# The group "dialout" must have read-write access (rw-)
Temporary fix without logging out
# This works for the current terminal session only
newgrp dialout
# Verify it worked:
groups
Finding your rig's Hamlib model number
Every radio supported by Hamlib has a unique model number. You need this number when configuring any application that uses Hamlib for rig control.
Search the Hamlib model list
# List all supported rigs
rigctl --list
# Search for a specific manufacturer
rigctl --list | grep -i icom
# Search for a specific model
rigctl --list | grep -i "7300"
# Example output:
# 3073 Icom IC-7300
Model numbers for popular radios
| Radio | Model # | Default baud | Notes |
|---|---|---|---|
| Icom | |||
| IC-7300 | 3073 | 19200 | Most popular Linux radio — built-in USB audio |
| IC-7610 | 3078 | 19200 | Dual receiver, built-in USB audio |
| IC-7700 | 3054 | 19200 | High-end HF/50 MHz |
| IC-7800 | 3060 | 19200 | Flagship HF transceiver |
| IC-9700 | 3081 | 19200 | VHF/UHF/satellite |
| IC-705 | 3085 | 19200 | QRP portable, built-in USB |
| IC-7100 | 3070 | 19200 | All-band including 2m/70cm |
| IC-7200 | 3063 | 19200 | Rugged HF/50 MHz |
| IC-910H | 3035 | 9600 | VHF/UHF satellite rig |
| Yaesu | |||
| FT-991A | 1035 | 38400 | All-band including VHF/UHF |
| FTDX-10 | 1050 | 38400 | SDR-based HF/50 MHz |
| FTDX-101D/MP | 1057 | 38400 | High-end HF transceiver |
| FT-DX3000 | 1039 | 38400 | Mid-range HF |
| FT-897D | 1021 | 9600 | All-mode portable |
| FT-857D | 1020 | 9600 | Compact all-band |
| FT-817/818 | 1015 | 9600 | QRP all-band portable |
| Kenwood | |||
| TS-890S | 2044 | 115200 | High-end with roofing filters |
| TS-590SG | 2033 | 115200 | Popular mid-range HF |
| TS-2000 | 2014 | 9600 | All-band HF/VHF/UHF |
| TS-480SAT/HX | 2023 | 9600 | Remote-head HF mobile |
| TH-D74 | 2051 | 9600 | Dual-band D-STAR handheld |
| Elecraft | |||
| K3/K3S | 2029 | 38400 | High-performance contest radio |
| KX3 | 2031 | 38400 | QRP portable |
| KX2 | 2049 | 38400 | Ultra-compact QRP |
| K4 | 2053 | 38400 | Modern HF transceiver |
| Other popular rigs | |||
| Xiegu G90 | 3085 | 19200 | Budget portable HF |
| Xiegu X6100 | 3087 | 19200 | Portable HF with built-in SDR |
| Flex-6000 series | 1038 | N/A | Via SmartSDR network API |
| Apache Labs ANAN | 1041 | N/A | OpenHPSDR-based SDR |
Testing with rigctl
rigctl is a command-line tool for sending individual CAT commands to your radio. Use it to verify your Hamlib setup before configuring your logging or digital mode software.
Basic rigctl test
# Basic syntax:
# rigctl -m [model] -r [port] -s [baud] [command]
# Get current frequency from IC-7300:
rigctl -m 3073 -r /dev/ttyUSB0 -s 19200 f
# Should return something like:
# Frequency: 14074000
# Get current mode:
rigctl -m 3073 -r /dev/ttyUSB0 -s 19200 m
# Set frequency to 14.074 MHz:
rigctl -m 3073 -r /dev/ttyUSB0 -s 19200 F 14074000
# Set mode to USB with 2400 Hz filter:
rigctl -m 3073 -r /dev/ttyUSB0 -s 19200 M USB 2400
Interactive rigctl session
# Start an interactive session (omit the command at the end)
rigctl -m 3073 -r /dev/ttyUSB0 -s 19200
# In the interactive prompt type commands one at a time:
# Rig command: f ← get frequency
# Rig command: F 7074000 ← set frequency to 7.074 MHz
# Rig command: m ← get mode
# Rig command: q ← quit
Common rigctl commands
| Command | Action | Example |
|---|---|---|
f | Get current frequency | rigctl ... f |
F [freq] | Set frequency in Hz | rigctl ... F 14074000 |
m | Get current mode and passband | rigctl ... m |
M [mode] [bw] | Set mode and passband width in Hz | rigctl ... M USB 2400 |
t | Get PTT status (0=RX, 1=TX) | rigctl ... t |
T [0|1] | Set PTT (0=RX, 1=TX) | rigctl ... T 1 |
l RFPOWER | Get RF power level | rigctl ... l RFPOWER |
L RFPOWER [val] | Set RF power (0.0–1.0) | rigctl ... L RFPOWER 0.5 |
v | Get VFO (A or B) | rigctl ... v |
V [vfo] | Set VFO | rigctl ... V VFOA |
s | Get S-meter reading | rigctl ... s |
Testing PTT
# CAUTION: This will transmit on your current frequency
# Make sure the radio is connected to a dummy load
# or the frequency is clear
# Key the transmitter for 2 seconds
rigctl -m 3073 -r /dev/ttyUSB0 -s 19200 T 1
sleep 2
rigctl -m 3073 -r /dev/ttyUSB0 -s 19200 T 0
Running rigctld as a shared daemon
rigctld is the key to sharing one radio between multiple applications. Instead of each application connecting directly to the serial port (which only one can hold at a time), rigctld holds the serial connection and all applications connect to rigctld via a network socket on port 4532.
Starting rigctld
# Basic syntax:
# rigctld -m [model] -r [port] -s [baud] &
# IC-7300:
rigctld -m 3073 -r /dev/ttyUSB0 -s 19200 &
# Yaesu FT-991A:
rigctld -m 1035 -r /dev/ttyUSB0 -s 38400 &
# Kenwood TS-890S:
rigctld -m 2044 -r /dev/ttyUSB0 -s 115200 &
# Verify it is running:
ps aux | grep rigctld
Connecting applications to rigctld
Once rigctld is running configure each application to use it instead of the serial port directly:
| Application | Rig control setting | Port/address |
|---|---|---|
| Fldigi | Configure → Rig Control → Hamlib → Use rigctld | localhost:4532 |
| WSJT-X | Settings → Radio → Rig = Hamlib NET rigctl | localhost:4532 |
| JTDX | Settings → Radio → Rig = Hamlib NET rigctl | localhost:4532 |
| CQRLog | Settings → TRX Control → rigctld | localhost:4532 |
| TLF | logcfg.dat: RIGCTLD=localhost:4532 | localhost:4532 |
| GQRX | Tools → Remote control settings → port 7356 (separate) | Separate from rigctld |
| Gpredict | Edit → Preferences → Interfaces → Radio → localhost:4532 | localhost:4532 |
Testing rigctld connection
# Connect to rigctld (model 2 = NET rigctl client)
rigctl -m 2 -r localhost:4532 f
# Should return the current frequency
# If it returns an error, rigctld is not running or the port is wrong
rigctld command-line options
| Option | Description | Example |
|---|---|---|
-m | Hamlib rig model number | -m 3073 |
-r | Serial port device | -r /dev/ttyUSB0 |
-s | Baud rate | -s 19200 |
-t | TCP port to listen on (default 4532) | -t 4533 |
-T | Bind address (default 0.0.0.0) | -T 127.0.0.1 |
-v | Verbose — print each command | -v |
-vvvv | Very verbose debug output | -vvvv |
-P | PTT port (if different from CAT port) | -P /dev/ttyUSB1 |
-p | PTT type (RTS, DTR, CAT, CM108) | -p RTS |
PTT control methods
PTT (Push To Talk) tells the radio to switch from receive to transmit. Hamlib supports several PTT methods — the right choice depends on your radio and interface.
PTT via CAT command (recommended for modern radios)
Most modern radios with USB CAT support PTT via the CAT protocol. This is the simplest method — no additional wiring needed.
# The -p CAT flag enables CAT PTT
rigctld -m 3073 -r /dev/ttyUSB0 -s 19200 -p CAT &
PTT via RTS or DTR line
For radios without CAT PTT or when using a separate PTT interface, the RTS or DTR line of a serial port can key a PTT relay. This requires a simple transistor circuit between the serial port and the radio's PTT input.
# PTT via RTS on the same serial port as CAT
rigctld -m 3073 -r /dev/ttyUSB0 -s 19200 -p RTS &
# PTT via DTR on a SEPARATE serial port (when CAT port is busy)
rigctld -m 3073 -r /dev/ttyUSB0 -s 19200 \
-P /dev/ttyUSB1 -p DTR &
PTT via CM108 GPIO (USB audio adapters)
Some USB audio adapters (particularly CM108-based dongles) have a GPIO pin that can key PTT. This is used by interfaces like the Digirig Mobile:
# PTT via CM108 GPIO pin
# The device path is the HID device for the CM108 chip
rigctld -m 3073 -r /dev/ttyUSB0 -s 19200 \
-P /dev/hidraw0 -p CM108 &
PTT via VOX
Set the radio's VOX (voice operated transmit) to key on the audio from the computer. No PTT wiring or software PTT needed — the radio keys automatically when audio starts playing. The downside is VOX introduces a short delay before transmit and a VOX tail delay after transmit, which can cause issues with digital modes that require fast switching.
Testing PTT through rigctld
# Test PTT through rigctld (radio must be on dummy load)
rigctl -m 2 -r localhost:4532 T 1 # Key transmitter
sleep 2
rigctl -m 2 -r localhost:4532 T 0 # Unkey transmitter
Integration with Fldigi, WSJT-X, CQRLog and TLF
The recommended integration architecture
The cleanest setup for a multi-application station is a single rigctld instance that all applications connect to. This avoids serial port conflicts and ensures all applications see the same radio state:
# Physical radio
# ↕ USB serial (CAT)
# rigctld (port 4532)
# ├── Fldigi (connects to localhost:4532)
# ├── WSJT-X (connects to localhost:4532)
# ├── CQRLog (connects to localhost:4532)
# └── TLF (connects to localhost:4532)
Fldigi via rigctld
In Fldigi go to Configure → Rig Control → Hamlib:
- Enable Hamlib rig control
- Rig: select "Hamlib NET rigctl" from the dropdown
- Device: enter
localhost:4532 - Click Initialize
Fldigi now reads frequency and mode from the radio via rigctld. PTT is also controlled via the same connection.
WSJT-X via rigctld
In WSJT-X go to File → Settings → Radio:
- Rig: select "Hamlib NET rigctl"
- Network Server: enter
localhost:4532 - PTT Method: CAT (sends PTT via rigctld)
CQRLog via rigctld
In CQRLog go to Settings → TRX Control:
- Set Rig type to rigctld
- Host: localhost
- Port: 4532
- Click Connect
TLF via rigctld
In your TLF logcfg.dat file:
# Connect TLF to rigctld instead of direct serial
RIGCTLD=localhost:4532
rigctld as a systemd service
For a permanent station setup run rigctld as a systemd service so it starts automatically on boot and restarts if it crashes.
Create the service file
[Unit]
Description=Hamlib rigctld rig control daemon
After=network.target
[Service]
User=hamradiobase
# Change -m, -r, -s to match your radio
ExecStart=/usr/bin/rigctld -m 3073 -r /dev/ttyUSB0 -s 19200 -p CAT -T 127.0.0.1
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable rigctld
sudo systemctl start rigctld
sudo systemctl status rigctld
# View logs
sudo journalctl -u rigctld -f
Using persistent device names in systemd
If your radio's serial port changes between /dev/ttyUSB0 and /dev/ttyUSB1 depending on what else is connected, use a udev symlink (see the Connecting section above) and reference the persistent name in the service file: -r /dev/ic7300.
Troubleshooting common problems
rigctl returns "error = Communication timed out"
- Check that your user is in the dialout group:
groups | grep dialout - Verify the serial port exists:
ls /dev/ttyUSB* - Check the baud rate matches the radio's CAT baud rate exactly — this is the most common cause
- Check the Hamlib model number is correct for your specific radio
- Verify the radio has CAT control enabled in its menu — not all radios have it on by default
- Try running with verbose output to see what is happening:
rigctl -m 3073 -r /dev/ttyUSB0 -s 19200 -vvvv f
rigctl returns "error = No such device"
- The serial port does not exist — check cable connection and try
ls /dev/ttyUSB* - The DVB-T driver may be conflicting with RTL-SDR devices — check udev rules
- Try a different USB port
rigctl returns "error = Permission denied"
- Your user is not in the dialout group — run
sudo usermod -a -G dialoutthen log out and back in - Check port permissions:
ls -la /dev/ttyUSB0— group should be dialout with rw permission
rigctld starts but applications cannot connect
- Verify rigctld is listening:
netstat -tlnp | grep 4532 - Check the bind address — if rigctld started with
-T 127.0.0.1it only accepts connections from localhost - Check firewall rules if connecting from another machine
- Verify the application is configured to use
localhost:4532not a direct serial port
Frequency reads correctly but PTT does not work
- Verify the PTT method is set correctly in rigctld:
-p CATfor CAT PTT,-p RTSfor RTS line - Some radios require a specific menu setting to enable USB PTT — check your radio's manual
- Test PTT directly with rigctl:
rigctl -m 2 -r localhost:4532 T 1 - Check if the application's PTT setting is correctly configured to use CAT/Hamlib rather than a serial port RTS line
Baud rate to use for my radio
The baud rate in Hamlib must match the baud rate configured in your radio's menu exactly. Common values:
- Icom — 9600 or 19200 (set in radio's menu, default varies by model)
- Yaesu — 4800, 9600, 19200, or 38400 (set in radio's menu)
- Kenwood — 9600 to 115200 (set in radio's menu, newer models default high)
- Elecraft — 9600 to 38400 (set in radio's menu)
If unsure, check your radio's operating manual for the CAT baud rate setting. A mismatch between Hamlib and the radio is the most common cause of timeout errors.
Frequently asked questions
What is the difference between rigctl and rigctld?
rigctl is a command-line tool for sending individual CAT commands to a radio — useful for testing and scripting. rigctld is a background daemon that holds the serial port connection and provides rig control to multiple applications simultaneously via a network socket on port 4532. For everyday use rigctld is what you want — start it once and all your ham radio software connects to it rather than fighting over the serial port.
Why does Hamlib keep timing out on my IC-7300?
The most common cause is the baud rate. The IC-7300's default CAT baud rate is 19200 — make sure you are using -s 19200 in your rigctl or rigctld command. Also verify your user is in the dialout group (groups | grep dialout) and that no other application is holding the serial port. Run with -vvvv for detailed debug output to see exactly what is failing.
Can multiple programs use the same radio at the same time?
Yes — run rigctld as a shared daemon and configure all applications to connect to it on port 4532 rather than the serial port directly. rigctld serializes the requests so multiple applications can read frequency and mode simultaneously. PTT is exclusive — only one application should transmit at a time, but rigctld handles the locking for you.
My radio is not in the Hamlib model list — what do I do?
First check whether a newer Hamlib version has added your radio by building from source. If still not listed, check whether your radio uses the same CAT protocol as a similar model from the same manufacturer — many Icom radios use the same CI-V protocol and one model number may work for several related radios. You can also try model 1 (dummy rig) which accepts all commands without error but does nothing, useful for testing applications without rig control. Finally consider filing an issue on the Hamlib GitHub — new rig support is often added within weeks if someone provides the CAT command documentation.
What is the difference between Hamlib and Flrig?
Hamlib is a low-level library — it provides the CAT protocol implementation and is used directly by applications via library calls or the rigctld network interface. Flrig is a graphical rig control application built on top of Hamlib that adds a visual display of radio parameters and a convenient broker between applications. Both serve the same purpose of sharing rig control between applications. rigctld is simpler and works headlessly; Flrig adds a GUI and some additional features like band memories. Most operators use rigctld for server/headless setups and Flrig when they want a visual rig control panel.
How do I control my antenna rotor with Hamlib?
Hamlib includes rotator control alongside rig control. Use rotctl and rotctld (the rotor equivalents of rigctl and rigctld) to control antenna rotors. The rotctld daemon runs on port 4533 by default and accepts azimuth and elevation commands from applications like Predict and Gpredict. Run rotctl --list to see supported rotor controllers — Yaesu GS-232, Easycomm, and many others are supported.