From 08f3ae8b9911a8725146a02a771d7177d948dc14 Mon Sep 17 00:00:00 2001 From: Evan Pratten Date: Thu, 30 Nov 2023 16:38:12 -0500 Subject: [PATCH] Add a tuning utility --- scripts/kxfilter | 23 ++++++++++------- scripts/kxtune | 67 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 81 insertions(+), 9 deletions(-) create mode 100755 scripts/kxtune diff --git a/scripts/kxfilter b/scripts/kxfilter index 68ae056..3546487 100755 --- a/scripts/kxfilter +++ b/scripts/kxfilter @@ -12,7 +12,8 @@ def set_apf(s: serial.Serial, state: str) -> None: s.write(b"AP1;") elif state == "off": s.write(b"AP0;") - + + def set_nb(s: serial.Serial, state: str) -> None: if state == "on": s.write(b"NB1;") @@ -21,22 +22,26 @@ def set_nb(s: serial.Serial, state: str) -> None: else: s.write("NL{:0>2}00;".format(state).encode("ascii")) s.write(b"NB1;") - + + def set_preamp(s: serial.Serial, state: str) -> None: if state == "on": s.write(b"PA1;") elif state == "off": s.write(b"PA0;") - + + def set_attenuator(s: serial.Serial, state: str) -> None: if state == "on": s.write(b"RA01;") elif state == "off": s.write(b"RA00;") - + + def set_filter_bandwidth(s: serial.Serial, bandwidth: float) -> None: s.write("BW{:0>4};".format(int(bandwidth * 100)).encode("ascii")) + def main() -> int: # Handle program arguments ap = argparse.ArgumentParser( @@ -106,27 +111,27 @@ def main() -> int: # Connect to the radio logger.debug(f"Connecting to radio: {args.device}") serial_conn = serial.Serial(args.device, args.baud) - + # Handle APF if args.audio_peaking_filter: logger.info(f"Setting APF: {args.audio_peaking_filter}") set_apf(serial_conn, args.audio_peaking_filter) - + # Handle NB if args.noise_blanker: logger.info(f"Setting Noise Blanker: {args.noise_blanker}") set_nb(serial_conn, args.noise_blanker) - + # Handle PA if args.pre_amp: logger.info(f"Setting Pre-Amp: {args.pre_amp}") set_preamp(serial_conn, args.pre_amp) - + # Handle RX ATT if args.attenuator: logger.info(f"Setting RX Attenuator: {args.attenuator}") set_attenuator(serial_conn, args.attenuator) - + # Handle filter bandwidth if args.filter_bandwidth: logger.info(f"Setting Filter Bandwidth: {args.filter_bandwidth}") diff --git a/scripts/kxtune b/scripts/kxtune new file mode 100755 index 0000000..b5ef0b1 --- /dev/null +++ b/scripts/kxtune @@ -0,0 +1,67 @@ +#! /usr/bin/env python3 +import argparse +import sys +import logging +import serial + +logger = logging.getLogger(__name__) + + +def main() -> int: + # Handle program arguments + ap = argparse.ArgumentParser( + prog="kxtune", description="Tune a KX2 or KX3 to a new frequency" + ) + ap.add_argument("frequency", help="Frequency to tune to in KC", type=float) + ap.add_argument("--vfo", help="VFO to tune", choices=["a", "b"], default="a") + ap.add_argument( + "--mode", + help="Radio mode", + choices=["lsb", "usb", "cw", "fm", "am", "data", "cw-r", "data-r"], + ) + ap.add_argument("--device", "-d", help="Serial device", default="/dev/ttyUSB0") + ap.add_argument("--baud", "-b", help="Serial baud rate", default=38400, type=int) + ap.add_argument( + "-v", "--verbose", help="Enable verbose logging", action="store_true" + ) + args = ap.parse_args() + + # Configure logging + logging.basicConfig( + level=logging.DEBUG if args.verbose else logging.INFO, + format="%(levelname)s: %(message)s", + ) + + # Convert to Hz + frequency = int(args.frequency * 1000) + + # Connect to the radio + logger.debug(f"Connecting to radio: {args.device}") + serial_conn = serial.Serial(args.device, args.baud) + + # Send the tune command + cmd = f"F{args.vfo.upper()}{frequency:011d};" + logger.debug(f"Sending command: {cmd}") + serial_conn.write(cmd.encode("ascii")) + + # If we have a mode, set it + mode_id = { + "lsb": "1", + "usb": "2", + "cw": "3", + "fm": "4", + "am": "5", + "data": "6", + "cw-r": "7", + "data-r": "9", + }.get(args.mode) + if mode_id: + cmd = f"MD{mode_id};" + logger.debug(f"Sending command: {cmd}") + serial_conn.write(cmd.encode("ascii")) + + return 0 + + +if __name__ == "__main__": + sys.exit(main())