Building and Using a CI-V Command Line Tool for Amateur Radio
Integrating amateur radio equipment with modern computers often starts with the Icom Communication Interface V (CI-V) protocol. While graphical shack-control software is abundant, a dedicated command-line interface (CLI) tool offers unmatched speed, scriptability, and low resource overhead. This article covers the essentials of the CI-V protocol, how to build a lightweight CLI tool in Python, and how to automate your station via the terminal. Understanding the CI-V Protocol
The CI-V protocol relies on a simple serial communication structure. Most Icom transceivers use a shared, single-wire bus (transmitters and receivers connect to the same line), meaning every device hears what every other device sends.
A standard CI-V data frame consists of the following hexadecimal structure:
Preamble (FE FE): Alerts connected devices that a data frame is beginning.
To Address: The hex code of the target device (e.g., 94h for the IC-7300).
From Address: The hex code of the controller (typically E0h for a PC).
Command: The primary action code (e.g., 05h to set frequency).
Sub-command: Optional fine-tuning modifiers (e.g., specific operating modes).
Data: The payload, often encoded in Binary Coded Decimal (BCD) format. End of Message (FD): Signals the completion of the frame. Designing a Python-Based CLI Tool
Python is an ideal language for a CI-V command-line utility due to its cross-platform compatibility and the robust pyserial library. Below is a foundational implementation capable of reading and setting a transceiver’s operating frequency. Prerequisites
Install the required serial communication library via your terminal: pip install pyserial Use code with caution. The Script (civ_tool.py)
import sys import serial import argparse # Default CI-V hex constants PREAMBLE = b’þþ’ EOM = b’ý’ PC_ADDR = b’à’ def frequency_to_bcd(freq_hz): “”“Convert an integer frequency in Hz to a 5-byte Icom BCD array.”“” freq_str = f”{freq_hz:010d}” bcd = bytearray() for i in range(8, -1, -2): pair = freq_str[i:i+2] bcd.append(int(pair, 16)) return bytes(bcd) def send_command(port, baud, radio_addr, cmd, sub_cmd=b”, data=b”): “”“Constructs and transmits a complete CI-V frame.”“” frame = PREAMBLE + radio_addr + PC_ADDR + cmd + sub_cmd + data + EOM try: with serial.Serial(port, baud, timeout=1.0) as ser: ser.write(frame) # Read back the echo (since CI-V is a shared bus) echo = ser.read(len(frame)) # Read the response from the radio response = ser.read_until(EOM) return response except serial.SerialException as e: print(f”Serial Error: {e}“, file=sys.stderr) sys.exit(1) def main(): parser = argparse.ArgumentParser(description=“CI-V Command Line Tool”) parser.add_argument(“-p”, “–port”, required=True, help=“Serial port (e.g., /dev/ttyUSB0 or COM3)”) parser.add_argument(“-b”, “–baud”, type=int, default=19200, help=“Baud rate (default: 19200)”) parser.add_argument(“-a”, “–address”, required=True, help=“Radio hex address (e.g., 94 for IC-7300)”) subparsers = parser.add_subparsers(dest=“command”, required=True) # Frequency sub-command freq_parser = subparsers.add_parser(“set-freq”, help=“Set radio frequency in Hz”) freq_parser.add_argument(“hz”, type=int, help=“Frequency in Hz (e.g., 14200000)”) args = parser.parse_args() radio_addr = bytes.fromhex(args.address) if args.command == “set-freq”: bcd_data = frequency_to_bcd(args.hz) print(f”Setting frequency to {args.hz} Hz…“) # Command 05h sets the frequency response = send_command(args.port, args.baud, radio_addr, cmd=b’’, data=bcd_data) if b’û’ in response: print(“Success (ACK received)”) elif b’ú’ in response: print(“Error (NAK received)”) else: print(“No valid response from radio.”) if name == “main”: main() Use code with caution. Running the Utility
Once the script is saved, you can control your rig directly from your shell environment.
Example: Set an IC-7300 (Address 94h) to 14.200 MHz on Linux
python civ_tool.py -p /dev/ttyUSB0 -b 19200 -a 94 set-freq 14200000 Use code with caution. Example: Set the same radio on Windows python civ_tool.py -p COM3 -b 19200 -a 94 set-freq 14200000 Use code with caution. Advanced CLI Automation Ideas
A command-line interface shines brightest when combined with core operating system tools. Here are a few ways to leverage a CI-V CLI:
Time-Based Scheduled Tracking: Combine your CLI tool with cron (Linux) or Task Scheduler (Windows) to automatically switch your radio to specific shortwave broadcast frequencies or net frequencies at exact times of day.
Rig-State Logging: Expand the script to read the operating frequency (Command 03h) and pipe the terminal output directly into text files or a local database for custom logging applications.
Remote SSH Management: By running this tool on a headless Raspberry Pi physically connected to your rig, you can securely SSH into your shack from anywhere in the world and adjust your radio parameters via a minimal cellular data connection.
Using small, targeted command-line tools allows you to bypass bloated software suites, giving you precise, fast, and highly scriptable control over your amateur radio hardware. If you want to expand this project, let me know: The specific Icom radio model you are targetting.
Which additional commands you want to add (like changing operating modes or reading signal strength).
Your preferred programming language if you want to move away from Python.
I can provide the exact hex mappings and BCD logic needed for those features.
Leave a Reply