TLF on Linux — Complete Contest Logging Setup and Operating Guide
TLF (The Logging Facility) is a keyboard-driven ncurses contest logger for Linux used by serious contesters worldwide. This complete guide covers installation on Ubuntu and Debian, configuration for major contests including CQWW and WPX, CW and voice keying setup, Hamlib rig control, multi-operator networking, Cabrillo export for log submission, and troubleshooting.
- What is TLF and who it is for
- Installation on Ubuntu and Debian
- Basic configuration and logcfg.dat
- Supported contests and setup
- Understanding the TLF interface
- Rig control with Hamlib
- CW keying setup
- Voice keying setup
- Operating guide — contest operating with TLF
- Multi-operator networking
- Cabrillo export and log submission
- DX cluster integration
- Troubleshooting common problems
- Frequently asked questions
What is TLF and who it is for
TLF (The Logging Facility) is a terminal-based contest logger for Linux written by Rein Couperus PA0R and maintained by a dedicated community of contesters. It runs in a terminal using ncurses — no graphical interface, no mouse required. Everything is controlled from the keyboard, which is exactly what serious contesters want during a high-rate pileup where every second counts.
TLF supports all major HF contests including CQWW SSB, CQWW CW, CQ WPX, ARRL DX, WAE, IOTA, and dozens more. It handles CW keying via serial port or sound card, voice keyer integration, Hamlib rig control, real-time DX cluster telnet, multi-operator networking, and exports standard Cabrillo format for electronic log submission.
The learning curve is real — TLF is not intuitive for newcomers and the documentation assumes familiarity with Linux and contest operating. But contesters who invest the time to learn it find it faster and more reliable than graphical contest loggers. Once the keyboard shortcuts are muscle memory the logging speed is exceptional.
Installation on Ubuntu and Debian
Ubuntu 22.04, 24.04 and Debian 11, 12
sudo apt update
sudo apt install tlf
Build from source (latest version)
sudo apt install git build-essential libhamlib-dev \
libncurses5-dev libglib2.0-dev libxmlrpc-core-c3-dev \
libasound2-dev autoconf automake
git clone https://github.com/tlf/tlf.git
cd tlf
autoreconf -i
./configure
make -j$(nproc)
sudo make install
Verify installation
tlf --version
Create a working directory
TLF expects its configuration files in the directory from which it is launched. Create a dedicated directory for each contest:
mkdir -p ~/contests/cqww-2026
cd ~/contests/cqww-2026
tlf
Basic configuration and logcfg.dat
TLF is configured entirely through a plain text file called logcfg.dat in your contest working directory. There is no graphical settings panel — everything from your callsign to the contest rules is set in this file.
Minimum logcfg.dat for getting started
# Your callsign
MYCALL=N0CALL
# Contest name (must match TLF's known contest list)
CONTEST=CQWW
# Operating mode: CW, SSB, or MIXED
BANDMAP
SSB
# Rig control via Hamlib
HAMLIB_DEVICE=/dev/ttyUSB0
HAMLIB_SPEED=19200
RIG=3073
# CW keyer via serial port
# CWDEVICE=/dev/ttyS0
# Your zone and country for scoring
CQ_ZONE=5
COUNTRY=USA
# Exchange sent (zone number for CQWW)
EXCHANGE=5
# DX cluster
CLUSTER=dxspider.co.uk:7300
Key configuration parameters
| Parameter | Description | Example |
|---|---|---|
| MYCALL | Your callsign | MYCALL=N0CALL |
| CONTEST | Contest name from TLF list | CONTEST=CQWW |
| CQ_ZONE | Your CQ zone (1-40) | CQ_ZONE=5 |
| COUNTRY | Your DXCC country | COUNTRY=USA |
| EXCHANGE | Sent exchange | EXCHANGE=5 |
| RIG | Hamlib rig model number | RIG=3073 |
| HAMLIB_DEVICE | Serial port for rig | HAMLIB_DEVICE=/dev/ttyUSB0 |
| HAMLIB_SPEED | CAT baud rate | HAMLIB_SPEED=19200 |
| CWDEVICE | Serial port for CW keying | CWDEVICE=/dev/ttyS0 |
| CLUSTER | DX cluster address:port | CLUSTER=dxspider.co.uk:7300 |
| BANDMAP | Enable band map display | BANDMAP |
| LOGFILE | Log filename | LOGFILE=cqww2026.log |
Country and zone files
TLF uses cty.dat for DXCC entity and zone resolution. It looks for this file in the current directory or system data directory. Keep it updated:
wget https://www.country-files.com/cty/cty.dat \
-O ~/contests/cqww-2026/cty.dat
Supported contests and setup
TLF supports all major HF contests. The contest name in logcfg.dat must match TLF's internal contest identifier exactly.
Major supported contests
| Contest | TLF name | Exchange sent | Exchange received |
|---|---|---|---|
| CQ World Wide DX (SSB/CW) | CQWW | CQ Zone | RST + CQ Zone |
| CQ WPX (SSB/CW) | CQWPX | Serial number | RST + Serial |
| ARRL DX (from USA/Canada) | ARRL-DX | Power (W) | RST + State/Province |
| ARRL DX (from DX) | ARRL-DX-DX | RST + State/Province | Power |
| WAE DX Contest | WAE | Serial number | RST + Serial |
| IOTA Contest | IOTA | Serial + IOTA ref | RST + Serial + IOTA |
| ARRL 10m Contest | ARRL-10 | State/Province | RST + State/Province/Serial |
| CQ 160m (SSB/CW) | CQ-160 | State/Province/Zone | RST + State/Province/Zone |
| EU HF Championship | EU-HF | Serial | RST + Serial |
| Worked All Europe | WORKED-ALL-EUROPE | Serial | RST + Serial |
Contest-specific logcfg.dat examples
CQWW SSB from USA
MYCALL=N0CALL
CONTEST=CQWW
SSB
CQ_ZONE=5
COUNTRY=USA
EXCHANGE=5
CQ WPX CW
MYCALL=N0CALL
CONTEST=CQWPX
CW
CQ_ZONE=5
COUNTRY=USA
# Serial number is sent automatically — no EXCHANGE needed
ARRL DX from USA
MYCALL=N0CALL
CONTEST=ARRL-DX
SSB
CQ_ZONE=5
COUNTRY=USA
EXCHANGE=MN # Your state abbreviation
Understanding the TLF interface
TLF runs in a terminal window using ncurses — a text-mode interface that looks similar to old DOS programs but is extremely functional. The screen is divided into several regions.
Screen layout
- Top line — current band, mode, rig frequency, time, and score summary
- Callsign entry field — where you type the callsign you are working
- Exchange field — where you enter the received exchange
- Log window — recent contacts scrolling upward
- Band map — DX cluster spots shown by frequency (if BANDMAP enabled)
- Score display — current QSO count, multipliers, and score
- Status line — messages, dupe checking results, and alerts
Operating modes within TLF
TLF has two operating modes that you switch between:
- S&P (Search and Pounce) — you are tuning around and calling other stations. Press F1 to send your callsign to the station calling CQ
- Running (CQ mode) — you are calling CQ and stations are calling you. Press F1 to send CQ and log stations as they reply
Switch between modes with the Alt+M key combination or by configuring the default in logcfg.dat.
Rig control with Hamlib
TLF uses Hamlib for rig control, allowing it to read and set your radio's frequency and mode. Configure in logcfg.dat:
# Hamlib model number for your radio
RIG=3073
# Serial port
HAMLIB_DEVICE=/dev/ttyUSB0
# Baud rate — must match radio setting
HAMLIB_SPEED=19200
Hamlib model numbers for popular contest radios
| Radio | Hamlib model | Baud rate |
|---|---|---|
| Icom IC-7300 | 3073 | 19200 |
| Icom IC-7610 | 3078 | 19200 |
| Icom IC-7700 | 3054 | 19200 |
| Icom IC-7800 | 3060 | 19200 |
| Yaesu FT-991A | 1035 | 38400 |
| Yaesu FTDX-10 | 1050 | 38400 |
| Yaesu FTDX-101D | 1057 | 38400 |
| Kenwood TS-590SG | 2033 | 115200 |
| Kenwood TS-890S | 2044 | 115200 |
| Elecraft K3/K3S | 2029 | 38400 |
Serial port permissions
sudo usermod -a -G dialout
# Log out and back in for the change to take effect
CW keying setup
TLF supports CW keying via serial port DTR/RTS lines or via a sound card. Serial port keying is more reliable for contest operating — it has lower latency and does not depend on audio configuration.
Serial port CW keying
# Serial port connected to a CW interface
# DTR line keys the transmitter
CWDEVICE=/dev/ttyS0
# CW speed in words per minute
CQSPEED=28
Sound card CW keying
# Use sound card for CW sidetone and keying
CWDEVICE=SOUNDCARD
CW message macros
TLF sends pre-configured CW messages via function keys. Define them in logcfg.dat:
# F1 — CQ call
F1=#MYCALL TEST #MYCALL
# F2 — exchange
F2=5NN #ZONE
# F3 — his call + exchange (running mode)
F3=#CALL 5NN #ZONE
# F4 — QRZ
F4=QRZ? #MYCALL TEST
# F5 — his call
F5=#CALL
# F6 — TU and log contact
F6=TU #MYCALL TEST
The #MYCALL, #CALL, #ZONE, and other variables are substituted automatically with the appropriate values when the message is sent.
CW speed control during operating
Change CW speed on the fly during contest operating:
- Page Up — increase CW speed by 1 WPM
- Page Down — decrease CW speed by 1 WPM
- Escape — abort current CW transmission
Voice keying setup
TLF supports a voice keyer for SSB operation via the sound card. Pre-record your standard contest messages as WAV files and TLF plays them at the push of a function key.
Recording voice messages
# Record CQ message (5 seconds)
arecord -f cd -d 5 cq.wav
# Record exchange message
arecord -f cd -d 3 exchange.wav
# Record TU message
arecord -f cd -d 2 tu.wav
Voice keyer configuration
# Enable voice keyer
SSB_VOICEKEYER
# PTT via serial RTS line
CWDEVICE=/dev/ttyUSB0
# Voice message files (in current directory)
# F1 sends cq.wav, F2 sends exchange.wav etc
PTT for voice keyer
The voice keyer needs to key your transmitter when playing audio. TLF uses the same CWDEVICE serial port for PTT during voice keyer operation. The RTS or DTR line keys the radio when a voice message plays.
Operating guide — contest operating with TLF
Starting a contest session
- Navigate to your contest working directory:
cd ~/contests/cqww-2026 - Launch TLF:
tlf - TLF reads logcfg.dat and opens with a blank log or continues from where you left off
- Verify rig control is working — frequency shown in top line should match your radio
- Verify DX cluster is connected — you should see spots appearing in the band map
Search and Pounce operating (S&P)
S&P mode is used when you are tuning around working stations calling CQ. The workflow in TLF:
- Tune your radio to a station calling CQ
- Type their callsign in the entry field
- TLF checks for duplicates automatically — a dupe warning appears if you have already worked them
- Press F1 to send your callsign (CW) or speak your callsign (SSB)
- When they come back to you, enter their exchange in the exchange field
- Press Enter to log the contact
Running (CQ) mode
Running mode is used when you are calling CQ on a clear frequency and working stations that answer. In TLF:
- Find a clear frequency and set your radio there
- Press F1 to send CQ (TLF sends "CQ TEST [YOURCALL] TEST" or similar)
- When a station calls, type their callsign in the entry field
- Press F3 to send the exchange (TLF sends "[THEIRCALL] [YOURSENT]")
- Enter their received exchange in the exchange field
- Press Enter to log and TLF sends "TU" and calls CQ again
Duplicate checking
TLF checks for duplicate contacts automatically as you type a callsign. The status line shows:
- DUPE in red — you have already worked this station on the same band and mode in this contest
- NEW MULT in green — this contact counts as a new multiplier
- New band — you have worked them before but not on this band
Band changes
Change band by tuning your radio — if rig control is active TLF detects the band change automatically and updates its display. You can also press the band keys directly: Alt+1 through Alt+7 for 160m through 10m.
Real-time score tracking
TLF shows your running score in the top right of the screen — QSO count, multiplier count, and total score. For CQWW this shows zone multipliers and country multipliers separately. Watch the score update with each new contact to track your progress.
Spot clicking from band map
With BANDMAP enabled and DX cluster connected, spots appear on the right side of the screen sorted by frequency. Use the arrow keys to highlight a spot and press Enter to QSY to that frequency. TLF tunes your radio via Hamlib and pre-fills the callsign from the spot.
Multi-operator networking
TLF supports multi-operator contesting with real-time log sharing between multiple stations on a local network. All stations see each other's contacts and dupes are checked across all operators simultaneously.
Network configuration
# Enable network logging
# All stations must use the same STATION name scheme
STATION=RUN1 # or RUN2, MULT1, etc.
# Network broadcast address for your local network
NETKEYER=192.168.1.255
Multi-op operating considerations
- All stations must have identical logcfg.dat files except for the STATION identifier
- All stations must be on the same local network subnet
- TLF uses UDP broadcast for log sharing — no server required
- One station should be designated as the master for final log consolidation
- The master station exports the Cabrillo log after the contest
Cabrillo export and log submission
After the contest ends export your log in Cabrillo format for submission to the contest organizer. Cabrillo is the standard format accepted by all major contest sponsors.
Exporting Cabrillo from TLF
Press Ctrl+C to exit TLF after the contest, then run the Cabrillo conversion from the command line:
# TLF generates a Cabrillo file automatically
# Look for a .cbr file in your contest directory
ls *.cbr
# Or generate it explicitly
tlf --cabrillo
Reviewing the Cabrillo file
Open the .cbr file in a text editor and review it before submission. Check that:
- Your callsign is correct in the CALLSIGN: header
- The contest name is correct
- Your category is correctly specified (SINGLE-OP, MULTI-SINGLE, etc.)
- The total QSO count looks correct
- A sample of QSO lines look correct — callsigns, times, and exchanges
Adding required Cabrillo headers
Some contests require additional header information that TLF may not fill automatically. Edit the Cabrillo file to add:
START-OF-LOG: 3.0
CALLSIGN: N0CALL
CONTEST: CQ-WW-SSB
CATEGORY-OPERATOR: SINGLE-OP
CATEGORY-BAND: ALL
CATEGORY-POWER: HIGH
CATEGORY-MODE: SSB
CLAIMED-SCORE: 1234567
OPERATORS: N0CALL
NAME: Your Name
ADDRESS: Your Address
ADDRESS: City, State ZIP
COUNTRY: USA
EMAIL: [email protected]
Submitting the log
Each contest has its own submission system. For CQWW submit at cqww.com, for CQ WPX at cqwpx.com. Most contests accept submissions by email or web upload. Submit within the deadline — typically 5–7 days after the contest ends. Late submissions are usually accepted for checklog purposes but not for final scoring.
DX cluster integration
TLF connects to a DX cluster for real-time spot information displayed in the band map. Configure in logcfg.dat:
# DX cluster server and port
CLUSTER=dxspider.co.uk:7300
# Your callsign for cluster login (usually same as MYCALL)
# TLF uses MYCALL for login by default
Using the band map during a contest
The band map on the right side of the TLF screen shows cluster spots sorted by frequency. New multipliers appear highlighted. During a contest:
- Watch for new multiplier spots highlighted in the band map
- Use arrow keys to navigate to a spot and Enter to QSY
- The callsign from the spot pre-fills the entry field automatically
- If the spot is a dupe TLF warns you before you call
Troubleshooting common problems
TLF won't start — logcfg.dat errors
- TLF must be launched from the directory containing logcfg.dat — check your working directory
- Syntax errors in logcfg.dat cause TLF to fail silently or show error messages — check each line carefully
- Make sure contest name matches TLF's expected string exactly — capitalization matters
- Run
tlf --debugfor verbose error output
Rig control not working
- Check dialout group:
groups | grep dialout - Verify serial port:
ls /dev/ttyUSB* - Check RIG= matches your Hamlib model number exactly
- Check HAMLIB_SPEED= matches radio's CAT baud rate
- Test Hamlib independently:
rigctl -m [model] -r /dev/ttyUSB0 -s [baud] f
CW keying not working
- Check CWDEVICE= is set to the correct serial port
- Check dialout group membership for serial port access
- Verify your CW interface hardware is connected correctly
- Try an alternative serial port if available
- Check that another application is not holding the serial port
DX cluster not connecting
- Test the connection manually:
telnet dxspider.co.uk 7300 - Check firewall rules blocking outgoing telnet
- Try a different cluster node
- Verify CLUSTER= syntax is exactly hostname:port with no spaces
Score seems incorrect
- Verify CQ_ZONE= is correct for your location
- Check COUNTRY= matches TLF's expected country identifier
- Update cty.dat in the contest directory to the latest version
- Verify EXCHANGE= is correct for the contest you are operating
Cabrillo file has wrong header information
- Edit the .cbr file directly in a text editor after export
- Add missing CATEGORY-*, NAME, ADDRESS fields manually
- Most contest robot systems validate Cabrillo headers — an incorrect header can disqualify your entry
Frequently asked questions
Is TLF difficult to learn?
Yes — TLF has a real learning curve compared to graphical contest loggers. The text-mode interface and configuration file approach require familiarity with Linux and some patience. Budget a few hours to get a basic setup working before your first contest, and a full practice session in a minor contest before using it in a major one. Contesters who invest the time consistently report that TLF becomes faster than graphical alternatives once the keyboard shortcuts are learned.
Can TLF be used for general logging (not contests)?
TLF can be configured for general logging but it is not designed for it. The interface is optimized for contest operating with serial numbers, exchange fields, and rate displays that do not make sense outside a contest context. For general everyday logging use CQRLog or Xlog — they are much better suited. TLF is the right tool for contest weekends and not much else.
Does TLF work for CQWW?
Yes — CQWW is one of TLF's most thoroughly tested and supported contests. Set CONTEST=CQWW in logcfg.dat and TLF handles the zone multiplier tracking, country multipliers, and serial number exchange correctly. Many serious CQWW competitors use TLF for both SSB and CW weekends. The CQWW exchange (RST + CQ Zone) is handled automatically — just enter the received zone in the exchange field.
Can I use TLF on a Raspberry Pi?
Yes — TLF runs well on Raspberry Pi 3 and 4 running Raspberry Pi OS. Install from repositories with sudo apt install tlf. The text-mode interface means TLF works even over an SSH connection to a headless Pi — useful for remote contest operating. A Pi 4 can comfortably run TLF alongside Hamlib and a DX cluster connection.
How do I submit my TLF log after a contest?
TLF generates a Cabrillo format .cbr file in your contest working directory. Open it in a text editor to verify the header information is correct — add or correct fields like CATEGORY-OPERATOR, CATEGORY-POWER, NAME, and ADDRESS as required by the specific contest. Then submit the file to the contest's log submission system — usually by email or web upload. Each major contest has its own submission system; check the contest website for current submission instructions.
What is the difference between TLF and CQRLog for contesting?
TLF is a dedicated contest-only logger optimized for maximum operating speed — keyboard-first, no mouse required, extremely fast duplicate checking, built-in CW and voice keyer, and multi-operator networking. CQRLog is primarily a general everyday logger with contest features added — it has a graphical interface, is easier to learn, and works well for casual contest participation. For serious contest operating where every minute matters TLF is faster. For operators who contest occasionally and do not want to maintain a separate contest setup, CQRLog's contest mode is perfectly adequate.