Scripting the Kantronics KPC-3 Plus: Fill-in Digi, KISS, PBBS and Backups
The Kantronics KPC-3 Plus is a classic hardware TNC that still does a fine job as an APRS fill-in digipeater, a KISS modem or a small mailbox. Configuring it by hand, though, means a serial terminal, a 1990s manual and a long list of commands you have to get right every time.
So I wrote kpc3-tools: two small Python scripts that factory-reset the TNC and set it up for a given role with one command, and that back up and restore its full configuration. Everything here was tested on a KPC-3 Plus with firmware 8.3.
What you need
- A KPC-3 Plus connected to a serial port (a USB serial adapter works fine, e.g.
/dev/ttyUSB0) - Python 3 with pyserial
- On Linux, access to the serial port (usually the
uucpordialoutgroup)
git clone https://github.com/edufortes/kpc3-tools.git
cd kpc3-tools
pip install -r requirements.txtOne command per role
kpc3.py takes a mode, your callsign and the serial port:
| Mode | What it sets up |
|---|---|
fillin |
WIDE1-1 fill-in digipeater, no beacon |
fillin-beacon |
WIDE1-1 fill-in digipeater plus an APRS position beacon |
kiss |
KISS mode for Dire Wolf, APRX, kissattach, Xastir… |
pbbs |
Personal mailbox (PBBS) |
show |
Print the current configuration, changes nothing |
./kpc3.py fillin DL7EDU-10 /dev/ttyUSB0
./kpc3.py fillin-beacon DL7EDU-10 /dev/ttyUSB0 --lat 50.1000 --lon 8.6800 \
--comment "WIDE1-1 Fill-in Digi" --interval 30
./kpc3.py kiss DL7EDU-10 /dev/ttyUSB0
./kpc3.py pbbs DL7EDU-10 /dev/ttyUSB0 --pbbs-call DL7EDU-1Each setup run does the same steps:
- Finds the TNC at whatever baud rate it is on. If it is in KISS mode it sends
C0 FF C0to get it out first. - Runs
RESTORE DEFAULT, sends*for the autobaud and answers theENTER YOUR CALLSIGN=>prompt. - Switches from the factory
NEWUSERmode toTERMINALand resets. - Turns the transmitter off (
XMITOK OFF), sets the clock and all the settings for the mode, then turns it back on.
Add --dry-run to see the commands without touching the TNC.
Every setup run starts with a factory reset. Take a backup first (see below).
The fill-in digipeater
These are the settings I use for a WIDE1-1 fill-in:
UIDIGI ON WIDE1-1 only answer WIDE1-1
UIDWAIT ON UI repeats honour DWAIT
DWAIT 0 (--dwait)
DIGIPEAT OFF no plain callsign/alias digipeating
HID OFF no ID packets
PBBS 0 the factory default enables a 100 KB PBBS
CD SOFTWARE (--cd)
MONITOR ON
MRPT ONTwo settings are worth explaining:
CD SOFTWARE: the factory default isCD INTERNAL. With software carrier detect the TNC considers the channel busy when it actually hears packet audio, not just noise.DWAIT: there is no “viscous delay” on the KPC-3 Plus.DWAIT(withUIDWAIT ON) only delays the repeat, up to 2.55 s, but the packet is always repeated. A small value like--dwait 300gives the wide-area digis a chance to go first. If you want a real viscous delay (hold the packet and drop it if another digi repeats it first), run the KPC in KISS mode behind APRX.
A proper APRS beacon
My first attempt used the usual BTEXT and BEACON EVERY 30. It worked, but looking at the monitor output I noticed my beacon went out as:
DL7EDU-10>BEACON: <UI>: !....N/.....E#WIDE1-1 Fill-in DigiOn the KPC, BTEXT beacons are always sent to the destination BEACON. UNPROTO only adds the via path. APRS still decodes it, but it is not clean.
The fix is the location-text beacon, which is what the script uses now:
BEACON EVERY 0
LT 1 !5006.00N/00840.80E#WIDE1-1 Fill-in Digi
LTP 1 APN383 VIA WIDE2-1
BLT 1 EVERY 00:30:00LTP lets you set both the destination and the path, so the beacon now goes out as DL7EDU-10>APN383,WIDE2-1. It works without a GPS connected. The script builds the position string from decimal degrees:
./kpc3.py fillin-beacon DL7EDU-10 /dev/ttyUSB0 --lat 50.1000 --lon 8.6800 \
--comment "WIDE1-1 Fill-in Digi" --interval 15 --path WIDE2-1 --symbol "1#"To change only the beacon of a running digi, without a reset, add --beacon-only.
Backup and restore
kpcbackup.py saves the whole configuration to a text file and can load it back:
./kpcbackup.py backup /dev/ttyUSB0
# saved backups/kantronics-KPC3P-8.3-2026-10-28.txt
./kpcbackup.py restore /dev/ttyUSB0 backups/kantronics-KPC3P-8.3-2026-10-28.txtFirmware 8.3 has no VERSION command, so the backup does a soft RESET and reads the model and version from the startup banner. That is also what goes into the file name.
The restore is the interesting part. The DISPLAY output is not valid command syntax (FRACK 4 (4 sec), BEACON EVERY 30 min, MYALIAS disabled…). So the restore does a factory reset, reads the default values, and only sends the settings that differ, translated back into commands. It refuses to restore a backup from a different model or firmware unless you add --force.
I tested it as a round trip: backup, restore, backup again. The two files are identical, apart from the clock.
Firmware 8.3 quirks
Things I ran into while writing this, useful even if you configure the TNC by hand:
- No
VERSIONcommand. The version only shows in the banner afterRESET. NEWUSERmode after a factory reset refuses some commands (XMITOK, for example) until you setINTFACE TERMINALandRESET.UIDUPEdoes not exist in 8.3; it came with firmware 9.x.DWAITmaximum is 255, that is 2550 ms.- Clearing values is inconsistent.
%clears most parameters (MYALIAS %,BTEXT %,LT 1 %), butGPSHEAD 2 %andCWIDTEXT %store a literal%.GPSHEAD 2with no value clears it. UIFLOOD %disables the alias but keeps the other fields.CTRL A OFF B OFFis ignored. SendCTRL A OFFandCTRL B OFFseparately.- Changing
PBBSorMYREMOTEreboots the TNC. - Error messages vary:
EH?,?...,Input ignored,Value out of range,Command not available in NEWUSER mode.
References
- kpc3-tools on GitHub
- Kantronics for manuals and firmware
- APRX if you want a viscous-delay digipeater with the KPC in KISS mode
73 de DL7EDU