In memory of Red PE1RRR, We’ll keep the packets flying. Thanks my friend.
Credits PE1RRR.


WARNING: Cooling

The use of this image is at own risk. Active (fan) or large area heatsink cooling is required to keep the RPI from overheating. For example, a heat sink case such as this one is sufficient if there is adequate airflow around the unit.

While the image does not by default overclock your RPI4, it is necessary to put the RPI into Performance Mode, which will make it run hotter. Overclocking is highly recommended but is a manual step you must take full responsibility for.

Before You Start

  • Network is handled by DHCP. The SSH system is not running by default and this must be manually activated to generate host keys for the system using the raspi-config tool.
  • Having the SSH system enabled will let you log in from a remote system (using PuTTY for example) on your own network, making it a lot easier to transfer copy & paste instructions from this document.
  • You will still need a display, a keyboard and a mouse connected for initial setup.
  • This document is not perfect, it is a work in progress.
  • The image is the first of its kind so it isn’t perfect either.
  • This document has already been updated with additional steps that must be taken to make it fully operational.
  • The image requires at least a 16GB SDCard (8.3GB used) and will auto-resize to the full capacity first on boot up. 16GB is recommended because it is quicker to make a backup of should you wish to do so in the future.
  • Download 2.3GB



Writing the image to SD Card is usually quite well documented by the general Raspberry Pi online documentation. It is possible to use Windows tools such as the RPI Imager, however the image file you download may need to be decompressed first using a tool such as WinRAR or 7zip.


You will need to know which device path your SDCard appears as e.g /dev/sda for the dd command. The image is compressed and will need to be unpacked:

gzip -d rpi4-console-dist.img.gz

Send the image to the SD Card using dd: Be sure that /dev/sdb is your SD card and not your internal hard disk!

sudo dd if=/path-to-the-image/rpi4-console-dist.img of=/dev/sdb bs=16M status=progress

First Boot

Upon first boot the image will resize itself to fit the full capacity of the SD card and then auto-restart the system.

Second Boot

Second boot will eventually present a black screen on the display connected (how useful, this will be addressed possibly in an updated image). If there is no signal then you may have the HDMI connector in the wrong port.

Plug in a mouse and hold right-click on the screen to open the pop up menu. From there, open the Terminal Emulator application.

Will this be a desktop system for you?

This install has been created to be as light as possible on the hardware while keeping plenty of tools available, as such there is no toolbar installed by default, so you may want to install the tint2 package if you wish to actually use this system as a desktop.

sudo apt install tint2

Open /home/pi/.config/autostart.sh, it will not exist.

Fill it with the contents:

# tint2 -- provides panel, systray, clock & taskbar
tint2 &

After installing tint2, a reboot is required for it to run at next logon.

Change the Password

Once logged in you should change the default password to something else using the passwd command on a new terminal line and hit enter. You will be prompted through the process. The current login is: pi and the password is: raspberrypi

Enable Secure Shell (SSH)

By default SSH is disabled as host keys need to be generated for your host that are unique and cannot be shared via an image file. So open up the raspi-config tool and navigate to (3) Interface Options, then select (2) SSH and Enable it.

sudo raspi-config

Bug Fixes

Updated 2023-04-21- There is a bug that needs to be fixed in the provided /home/pi/.asoundrc file, while the system will still function it is necessary to fix this oversight as it will undoubtedly improve performance.

Open the /home/pi/.asoundrc file and find the string ‘44000’, this needs to be adjusted to ‘48000’. The section of code it is in is shown below, marked ‘Correction applied here’

pcm.dmix0 {
    type dmix
    ipc_key 60000
    ipc_key_add_uid false   # let multiple users share
    ipc_perm 0666           # IPC permissions for multi-user sharing (octal, default 0600)
    slave {
        pcm "hw:3,0"
        rate 48000          # Correction applied here.


If you do have adequate cooling, it is highly recommended to overclock to get the best performance, editing /boot/config.txt to set it to 2GHz which is from experience so far, safe and stable. Locate the #arm_freq parameter in the config.txt file and add the following below it:


Performance Mode

And edit /etc/rc.local to force performance mode at boot:

sudo nano /etc/rc.local

Insert the following one-liner BEFORE the ‘exit 0’ line in /etc/rc.local

echo performance | sudo tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor

Enable Realtime Thread Priority

Tweaks to the host operating system file /etc/security/limits.conf

@audio - rtprio 95
@audio - memlock 512000
@audio - nice -19

The rtpriosetting is the maximum priority a user of the audio group can run a task. The memlock setting is the maximum amount of memory that a member of the audio group can lock with a realtime task. This should be less than the maximum physical amount of memory, some recommend it to be half. nice is the minimum “nice level” a task can be run as (the willingness of a task to give up it’s cpu time).

ALSA Project (https://www.alsa-project.org/wiki/Low_latency_howto)

If not using ‘pi’ user, ensure that your user ID is in the audio group in /etc/groups

After a reboot, verify that the new limits are working with:

ulimit -r

pi@raspberrypi:~/bin $ ulimit -r

VARA and ARDOP realtime Thread Priority

Background: Launch VARA with highest priority (99)- is required to compensate for some since discovered latency issues.

When issued as root, the chrt tool overrides the policy set earlier in the limits.conf, running the process as rt (realtime) which will reflect in the indicated priority listing when displayed in the top process monitor program.


sudo chrt -p 99 `pgrep VARA.exe`

Will modify the thread priority to realtime, on the fly. Using ‘top’, look at the PRI column and it should now be ‘rt’ instead of default ‘20’.

A modified script that will fork chrt into a background subshell, wait 20 seconds while VARA is launched, and then adjusts the process priority of VARA.exe is required.

The following script tweak is needed for the RPI4 TNC image for both the ARDOP and VARA TNCs:

File: /home/pi/bin/startvara 

cd /home/pi/bin
export DISPLAY
(sleep 20; sudo chrt --pid 99 `pgrep VARA.exe` ) &
/usr/local/bin/wine /home/pi/.wine/drive_c/VARA/VARA.exe

File: /home/pi/bin/startardop

cd /home/pi/bin/
(sleep 10; sudo chrt --pid 99 `pgrep piardopc` ) & /home/pi/bin/piardopc 8515 ARDOP2IN ARDOP2OUT

Enable the TNCs

By default, none of the TNCs are started automatically, but can be enabled to do so:

sudo systemctl enable vara
sudo systemctl enable ardop
sudo systemctl enable ardop-gui
sudo systemctl enable qtsm

sudo service vara start
sudo service ardop start
sudo service ardop-gui start
sudo service qtsm start

View the TNCs

To view the running TNCs, attach VNC Viewer to Display “2”.

So long as you have RealVNC client installed on a remote system, such as another Raspberry Pi, or an iPad you can connect to the screen running the TNCs for monitoring purposes. You don’t have to keep the VNC open, they will run happily in the background.

From Terminal: Note: omit the brackets if providing an IP address.

vncviewer [optional IP address]:2 

Login is “pi“, the password is “raspberrypi” unless you have already changed it)

VNC Idle Timeout

By default the VNC will timeout after 3600s (an hour) which can be annoying if you want to leave it open on another desktop to monitor. If you have the tint2 toolbar installed it will be possible to locate annd open the VNC server UI on the desktop and then open up Expert settings to adjust IdleTimeout to 0.

Alternatively, open /home/pi/.vnc/.config.d/Xvnc and append the following line:


Configuring the QtSoundModem TNC

Due to an oversight on my part, QtSoundModem.ini has the CWID setting enabled with my callsign so you will need to set the timer from 15 minutes to 0. This will be fixed in the next release of the image.

Additionally good info to know beforehand- due to how QtSoundModem GUI config dialog saves settings, the manually configured sound devices do not appear in the dropdown lists because they are “virtual”, therefore the dsnoop/dmix devices that come preconfigured with the image will be overwritten if the dialog is used to change any configuration parameters(!)

The best practice is to edit the ini file in a text editor manually.

To recap, the QtSoundModem.ini file is read-only on purpose. The application tries to write back to the file on each shutdown/closure which causes problems for our special audio sharing setup between the different TNCs, so editing the file must be done by hand, not via the GUI.

With editors like vim, a force-write !wq will write-quit & ignore read-only warning. Easy peasy.

I don’t use nano myself but I know a lot of people do, BUT I don’t know if it i will allow you to do this the same way. If not offered the option when you attempt to overwrite a read-only file, then you can temporarily change the file permission level after stopping the service:

sudo service qtsm stop

cd /home/pi/bin

chmod 644 QtSoundModem.ini

nano QtSoundModem.ini

Make the edits to:


Save and close, then change the permissions back to read-only.

chmod 444 QtSoundModem.ini

Then restart the QtSoundModem’s service:

sudo service qtsm start

TCP Port Defaults

Bear in mind that my ‘defaults’ here are in fact not factory setting defaults.

By default my following ports are set:


  • KISS: 7777
  • AGW: 6666


  • 8015


  • 8300
  • 8301 (data)



It’s not a typo, Winelink: VARA on Linux was accomplished courtesy of The Winelink Project on GitHub.

VARA HF 4.7.3 introduced anti-piracy obfuscation to the build which as added so much overhead that it will no longer work on Linux. It is therefore advised to not update to this version.

As of VARA HF version 4.7.5, the aforementioned was removed from the code and functionality has been restored.

[optional] Disable Paket61 socat for TNC2 emulator

sudo systemctl disable paket
sudo service paket stop

[optional] flrig – Radio Head Control

TODO – building and installing.

The source code is located in /home/pi/src, it is already pre-built, so you can already install it with sudo make install from the flrig-version’s subdirectory.

However, because its an old alpha build by now, a fresh build from new source would be better. If you do go ahead an install the tool, it will begin to auto-start due to the systemd service powering it up as soon as it finds /usr/local/bin/flrig binary.

You can stop/start FLRig with sudo service flrig stop/start

QtTermTCP – Packet Terminal

Edit /home/pi/bin/startqtterm and change the DISPLAY variable to the desktop which you need, usually :0 if a local monitor connected to HDMI, in our use case you can direct the display to the virtual TNC’s desktop which is running on desktop :2.

See QtTermTCP for a tutorial video for setting it up with a node.

You can start the program as a service. If QtTermTCP crashes or you close it, systemd will auto-restart the application.

sudo service qtterm start

To have QtTermTCP auto-start on every boot:

sudo systemctl enable qtterm


Now just go to your BPQ32 node and define all the ports to each of the TNCs with the appropriate drivers for each TNC type. Good luck! If you get stuck, ask on the groups.io, or try this Google magic search keyword term for official documentation:

cantab uz7ho
cantab qtsoundmodem
cantab VARA 

Ok Ok I will get around to making that document soon. Bookmark my website please and also – consider a donation to my beer/host fund if you feel like it. This document took many hours to write and hours of testing and its still not finished!



Not meant for 3rd Parties – provided for educational purposes only.

Please note that there is no toolbar installed, you may want to install the tint2 package if you wish to actually use this system as a desktop.

sudo apt install tint2

How it works

As this image is dual-purpose, this image is also capable of running old packet applications for fun, but due to performance requirements must not be used if running the system as a TNC-bank.

On this image is DOSBOX with various packages preconfigured to use a virtual serial port pipe to the box with a BPQ32 node running on the local network This is downright complicated and because of this, it is not really recommended for 3rd party use but tinkerers might like it.

Each program such as “superpacket” or “winpack” relies on a listening serial device on a remote BPQ32 based node. Each application has a unique TCP port put aside, and reciprocal listeners must be set up for each port on the remote node box.

The TCP listeners direct the traffic to a pseudo serial device that the node is configured to attach to when it is started. It then talks to the socket using KISS mode, and the applications on the other end are doing the same, with a couple of exceptions.


If you leave a BPQ32 node with KISS ports enabled linked to socat pseudo serial services, the node will assume traffic is being sent to them and will then wait for responses. If you run the node long enough with the reciprocal applications themselves not running, this will cause that port’s KISS buffer in the node to get full and cause the whole node to stop responding entirely. Eek. So don’t leave the ports configured on the node if you had enough of running the DOS apps!


Here are some examples for BPQ32:

        ID=TCP KISS port 8004      
        QUALITY=192             ; Quality factor applied to node broadcasts heard on
                                        ; this port, unless overridden by a locked route
                                        ; entry. Setting to 0 stops node broadcasts
        FRACK=5000                      ; Level 2 timout in milliseconds
        RESPTIME=1000           ; Level 2 delayed ack timer in milliseconds
        RETRIES=5                       ; Level 2 maximum retry value
        MAXFRAME=6                      ; Max outstanding frames (1 thru 7)
        PACLEN=128                      ; Default max packet length for this port.
                                        ; PACLEN is ignored for APRS packets
        L3ONLY=0                        ; 1=No user downlink connects on this port
        DIGIFLAG=1                      ; Digipeat: 0=OFF, 1=ALL, 255=UI Only
        USERS=10                        ; Maximum number of L2 sessions, 0 = no limit
        ID=TCP KISS port 8006       
        QUALITY=244             ; Quality factor applied to node broadcasts heard on
                                        ; this port, unless overridden by a locked route
                                        ; entry. Setting to 0 stops node broadcasts
        FRACK=8000                      ; Level 2 timout in milliseconds
        RESPTIME=2000           ; Level 2 delayed ack timer in milliseconds
        RETRIES=10                      ; Level 2 maximum retry value
        MAXFRAME=3                      ; Max outstanding frames (1 thru 7)
        PACLEN=100                      ; Default max packet length for this port.
                                        ; PACLEN is ignored for APRS packets
        L3ONLY=0                        ; 1=No user downlink connects on this port
        DIGIPORT=0                      ; Port on which to send digi'd frames (0 = same port)
        USERS=10                        ; Maximum number of L2 sessions, 0 = no limit

The serial port listeners on the node box (remote) are run from some start scripts, for example:

For PORT 17 (tcp 8004):

socat -d -d PTY,raw,echo=0,link=/home/pi/port-8004-stay PTY,raw,echo=0,link=/home/pi/port-8004 &
while true
socat -d -d open:/home/pi/port-8004-stay,nonblock,echo=0,raw TCP4-LISTEN:8004,reuseaddr,fork
sleep 1
# End

For PORT 18 (tcp 8006):

socat -d -d PTY,raw,echo=0,link=/home/pi/port-8006-stay PTY,raw,echo=0,link=/home/pi/port-8006 &
sleep 3
while true
socat -d -d open:/home/pi/port-8006-stay,nonblock,echo=0,raw TCP4-LISTEN:8006,reuseaddr,fork
sleep 1
# End


The image has the reciprocal couplings for each of these tcp ports provided as linux services, these can be turned on automatically.

The following ports with self explanatory service names are available:

port-2704  port-8004  port-8005  port-8006  port-8007  port-8009  port-8011

Each has a script in /home/pi/bin/ and needs modifying to change the IP address to the one of your BPQ32 node box.

The above services corrleate to the the various different preconfigured dosbox packages that I have set up for different packet radio applications.

They all run on different TCP ports so that it is actually possible to interconnect the applications through the node. e.g. connect from Winpack to the node, then from the node connect to the SuperPacket application (if it is also running).


It is not wise to configure too many kiss-TNC ports as it can have a detrimental effect on the node, sometimes causing BPQ32 to lock up intermittently if you leave the applications closed for a measure of time.

For the purposes of this document I have limited examples to just two:

Port 17 (tcp 8004) and 18 (tcp 8006) respectively for “superpacket” and “winpack”, but there are others defined in the system services already that can be enabled and used if you chose to add extra ports to the node using Port 17 or 18 as examples to iterate up to maximum of Port 32.

For reference

Serial Port Tunnels (client side) – enable and start syntax:

sudo systemctl enable port-8004
sudo systemctl enable port-8006
sudo service port-8004 start
sudo service port-8006 start


Each port that is started opens a ‘screen’ session for debugging. Each screen session is easily identifiable using “screen -r”

pi@console:~ $ screen -r
There are several suitable screens on:
	5915.Port8004	(07/23/2022 11:16:56 AM)	(Detached)
	5093.Port8006	(07/23/2022 11:08:14 AM)	(Detached)

To view the console’s output:

screen -r Port8006

CTRL-A then D will detatch the console.



Winpack is configured to use DOS BPQ as the communications layer, and utilizes the KISS interface to talk to my remote node. The node’s “socat” serial port is listening on TCP port 8006, using the socat setup described above. This allows the DOSBOX instance to communicate with the node that is on a remote host. The nodes talk to each other via NETROM, the example port setup shown earlier in the document demonstrates that NETROM is enabled and is sending as many nodes as possible on that port. When successfully linked, the Winpack terminal should show a lot of NETROM activity from broadcasts.

The schametic is like this:

LinBPQ Node -- [Kiss Port 17] -- [Serial Socat Listener Port 8006] <-network-> [Remote Serial Socat Connector] <—-> [DOSBOX-Staging] <—-> [DOS BPQCODE.DLL] <--> [Windows 3.11] <--> [Winpack 6.80]

To configure your own callsign you must edit the following file:


When the ‘winpack‘ script is run it will launch DOSBOX and run the BPQCFG.EXE automatically before auto-booting Windows, this converts the configuration TXT into binary for the BPQCODE to use. Winpack is preconfigured to use the resident BPQ node.

Winpack’s own callsign configuration is pretty straight forward and self explanatory.


Superpacket, on the other hand, is a complex RTFM situation, only for those with the edge! You’re on your own. But it is damn near perfect for multitrack train drifting, on packet radio.

The Other Apps

Apps confirmed and preconfigured to work in the image:

  • Paket 6.1 (paket) – requires the TNC2 emulator port setup, see below.
  • Baycom (baycom) – works via a TFPCX KISS emulator TSR
  • Winpack 6.80 (winpack) – uses NETROM, use the examples given in this document.
  • SuperPacket 9.2 (sp) – uses KISS, see the examples given in this document
  • New Packet Generation 2.0 (npg)
  • TST Host (tsthost)
  • BPQ 4.09 (DOS) – is called by Winpack and will require separate configuration.
  • TheDraw has been included to provide access for text drawing.
  • EasyTERM PMS (DOS based frontend for BPQ from circa 1994, not to be confused with UZ7HO software) Requires DOSBOX config to be updated- see download below:

Take a look in /home/pi/.config/dosbox for the various config files for the applications.

To recap, each DOS application requires a unique BPQ KISS port (or TNC2 emulator) to be configured.

For KISS, see the Ports examples above, they can be used as templates to enable the other applications.

I was able to get Winpack, Superpacket, Baycom, TSTHost, NPG and Paket61 all talking at the same time. It was insane and I am sure the RPI4 cried for mercy.

Enable Paket61 socat for TNC2 emulator

Example TNCPORT for Paket (find a clear spot in the bpq32.cfg configuration file).


Enable and start the socat services for Paket61

sudo systemctl enable paket
sudo service paket start

Jnos and QtSoundModem

Today I was playing with Jnos, on my main system I have BPQ32 running with Direwolf and QtSoundModem. BPQ32 uses the Kiss port on Direwolf and the AGW port on QtSoundModem. Now I know that Jnos can easily handle the AGW interface/driver, so I linked Jnos with the AGW poort of Direwolf.

attach agwpe agw 8000
ifconfig agw description "AGW - 1200 baud port"
ax25 hport agw on
trace agw 0111

Direwolf is running on 144.850Mhz 1k2 and 430.950Mhz 9k6

Now I thought it would be nice to hook Jnos to QtSoundModem as well. But BPQ32 already uses the AGW port of QtSoundModem. Now I had read that Maiko VE4KLM had written a Kiss over tcp/ip for Winrpr. Who doesn’t dare don’t win. Here we go.

QtSoundmodem is running on 14.102Mhz 300Baud with 1100Hz on the left channel and 2000Hz on the right channel.


attach winrpr qt0 8105
attach kiss qt0 1 qt1
ifconfig qt0 description "Kiss tcp/ip port 14.102Mhz 1100Hz"
ifconfig qt1 description "Kiss tcp/ip port 14.102Mhz 2200Hz"
trace qt0 0x211 qt0.log 1000
trace qt1 0x211 qt1.log 1000
ax25 hport qt0 on
ax25 hport qt1 on

The winrpr is the kiss over tcp/ip driver of Jnos. It`s written to use with Winrpr.

jnos> ifconfig  
qt1      IP addr MTU 256 Link encap AX25
         Link addr PD9Q-1   BBS PD9Q   Paclen 256   Irtt 5000
         BCText: PD9Q Jnos Packet BBS/Gateway
         flags 0xcb0 trace 0x211 netmask 0x00000000 broadcast
         sent: ip 0 tot 0 idle 0:00:01:51
         recv: ip 0 tot 0 idle 0:00:01:51
         descr: Kiss tcp/ip port 14.102Mhz 2200Hz
qt0      IP addr MTU 256 Link encap AX25
         Link addr PD9Q-1   BBS PD9Q   Paclen 256   Irtt 5000
         BCText: PD9Q Jnos Packet BBS/Gateway
         flags 0x400 trace 0x211 netmask 0x00000000 broadcast
         sent: ip 0 tot 0 idle 0:00:01:51
         recv: ip 0 tot 0 idle 0:00:01:51
         descr: Kiss tcp/ip port 14.102Mhz 1100Hz

Some trace of the tun0 interface, there is traffic back and forward from Jnos to the remote QtSoundModem.

Mon Feb 21 15:34:09 2022 - tun0 sent:
IP: len 40> ihl 20 ttl 254 prot TCP
TCP: 1025->8105 Seq x1040001 Ack x3bf15fb1 ACK Wnd 5840

Mon Feb 21 15:34:13 2022 - tun0 recv:
IP: len 159> ihl 20 ttl 64 DF prot TCP
TCP: 8105->1025 Seq x3bf15fb1 Ack x1040001 ACK PSH Wnd 64240 Data 119
0000  ....n......b...a..033  .IR2UFV-15  00:00:06:12  14.1033  .IW7DVM
0040       00:00:08:37  14.1033  .SM7PET+    00:00:12:36  14.

Mon Feb 21 15:34:13 2022 - tun0 recv:
IP: len 159> ihl 20 ttl 64 DF prot TCP
TCP: 8105->1025 Seq x3bf15fb1 Ack x1040001 ACK PSH Wnd 64240 Data 119
0000  ....n......b...a..033  .IR2UFV-15  00:00:06:12  14.1033  .IW7DVM
0040       00:00:08:37  14.1033  .SM7PET+    00:00:12:36  14.

Mon Feb 21 15:34:13 2022 - tun0 sent:
IP: len 40> ihl 20 ttl 254 prot TCP
TCP: 1025->8105 Seq x1040001 Ack x3bf16028 ACK Wnd 5840

Here is a trace of the log file (trace qt0 0x211 qt0.log 1000)

Mon Feb 21 15:25:03 2022 - qt0 recv:
KISS: Port 0 Data
AX25: UT1HZM->SM7PET I(P) NR=2 NS=3 pid=Text
0000  00 a6 9a 6e a0 8a a8 e0 aa a8 62 90 b4 9a 61 56  .&.n .(`*(b.4.aV
0010  f0 4d 69 6e 65 2c 20 4c 3e 20 43 61 6c 6c 2c 20  pMine, L> Call, 
0020  4c 3c 20 43 61 6c 6c 2c 20 4c 40 20 3d 20 4c 69  L< Call, L@ = Li
0030  73 74 20 74 6f 2c 20 66 72 6f 6d 20 6f 72 20 61  st to, from or a
0040  74 0d 20 20 20 4c 4c 20 6e 75 6d 20 3d 20 4c 69  t.   LL num = Li
0050  73 74 20 6d 73 67 20 6e 75 6d 2c 20 4c 20 6e 75  st msg num, L nu
0060  6d 2d 6e 75 6d 20 3d 20 4c 69 73 74 20 52 61 6e  m-num = List Ran
0070  67 65 0d 20 20                                   ge.

Mon Feb 21 15:25:17 2022 - qt0 recv: 
KISS: Port 0 Data 
AX25: IW7DVM->APRS v WIDE3-3 UI pid=Text
0000  00 82 a0 a4 a6 40 40 e0 92 ae 6e 88 ac 9a 60 ae  .. $&@@`..n.,.`.
0010  92 88 8a 66 40 67 03 f0 21 34 30 32 33 2e 32 38  ...f@g.p!4023.28
0020  4e 5c 30 31 37 31 37 2e 31 31 45 2d 48 46 20 42  N\01717.11E-HF B
0030  65 61 63 6f 6e 20 31 34 2e 31 30 35 20 4c 53 42  eacon 14.105 LSB
0040  20 33 30 30 62 64 20 2d 20 54 61 72 61 6e 74 6f   300bd - Taranto

Connect from my Jnos system to UT1HZM on port qt0 (qtsoundmodem 300Baud 1100Hz port)

Mon Feb 21 15:08:33 2022 - qt0 recv:
KISS: Port 0 Data
AX25: UT1HZM->PD9Q-15 I(P) NR=0 NS=0 pid=Text
0000  00 a0 88 72 a2 40 40 fe aa a8 62 90 b4 9a 61 10  . .r"@@~*(b.4.a.
0010  f0 55 54 31 48 5a 4d 7d 20 57 61 69 74 2e 2e 2e  pUT1HZM} Wait...
0020  0d                                               .

Mon Feb 21 15:08:33 2022 - qt0 sent:
KISS: Port 0 Data
AX25: PD9Q-15->UT1HZM RR(F) NR=1
0000  00 aa a8 62 90 b4 9a 60 a0 88 72 a2 40 40 ff 31  .*(b.4.` .r"@@.1

Mon Feb 21 15:08:38 2022 - qt0 recv:
KISS: Port 0 Data
AX25: UT1HZM->PD9Q-15 I NR=0 NS=1 pid=Text
0000  00 a0 88 72 a2 40 40 fe aa a8 62 90 b4 9a 61 02  . .r"@@~*(b.4.a.
0010  f0 4b 52 53 3a 55 54 31 48 5a 4d 2d 35 7d 20 43  pKRS:UT1HZM-5} C
0020  6f 6e 6e 65 63 74 65 64 20 74 6f 20 42 42 53 0d  onnected to BBS.

Mon Feb 21 15:08:39 2022 - qt0 sent:
KISS: Port 0 Data
AX25: PD9Q-15->UT1HZM RR NR=2
0000  00 aa a8 62 90 b4 9a 60 a0 88 72 a2 40 40 ff 41  .*(b.4.` .r"@@.A

Now the trace of port qt1 (tail -f qt1.log)

Mon Feb 21 15:22:31 2022 - qt1 sent:
KISS: Port 1 Data
0000  10 a8 8a a6 a8 40 40 e0 a0 88 72 a2 40 40 7f 3f  .(.&(@@` .r"@@.?

Mon Feb 21 15:22:31 2022 - qt1 sent:
KISS: Port 1 Data
0000  10 a8 8a a6 a8 40 40 e0 a0 88 72 a2 40 40 7f 3f  .(.&(@@` .r"@@.?

Boooommm Crashed……dammmm

It went so well. But now Jnos crashed. The winrpr driver is probably not written for two ports. Receiving is fine, but a packet that leaves the system on port qt1, Jnos can’t handle that.

So I removed this line (attach kiss qt0 1 qt1) from autoexec.nos and Jnos is running just fine. It is a pity that it only runs on 1 port, and that is the same as the AGW port. Maybe Maiko VE4KLM will look at it again.

MHSave and Python

Today I am playing with Python and Matplotlib. In BPQ32 you have the option to save the Most Heard list (MH) when you close BPQ32. This contains a lot of data that you can use. Above I made a plot of the received stations and the number of packets I received at 14.1022Mhz + 1000Hz at 300Baud. Now I am not a world programmer, so this could probably be easier or different. Below the script I have written and used.

import re, csv, zlib
import matplotlib.pyplot as plt
import numpy as np

#First get the data form the right port. 14.1022Mhz 300 Baud HF Packet

port4 = []

with open("MHSave.txt") as f:
        found_port4 = False

        for line in f:
                if line.startswith("Port:4"):

                        found_port4 = True

                if found_port4:
                        if line.startswith("Port:5"):
                                mod_string = line.replace('||', '')
                                mod_strings = re.sub("via.*$", "", mod_string)

with open('port4.txt', 'w') as fout:


# Convert it to a csv file
with open('port4.txt', 'r') as in_file:
    lines = in_file.read().splitlines()
    stripped = [line.replace(","," ").split() for line in lines]
    grouped = zip(*[stripped]*1)
    with open('port4.csv', 'w') as out_file:
        writer = csv.writer(out_file)
        writer.writerow(('Epoch', 'Pack-rev', 'Call', 'Month', 'Day', 'Time'))
        for group in grouped:

# Matplotlib create a nice Plot of the received calls

filename = 'port4.csv'
with open(filename) as f:
    reader = csv.reader(f)
    header_row = next(reader)

    #Get Packets and Calls received
    packs, calls = [], []
    for row in reader:
        pack = int(row[1])
        call = str(row[2])

x = np.arange(len(calls))

fig, ax = plt.subplots()

ax.barh(x, packs, align='center')
ax.set_title("Call and Packets received on PI1LAP")
ax.set_xlabel('Received Packets')
ax.set_ylabel('Station Callsigns')
ax.set_xticks(packs, minor=True)

Kantronics KPC4

Today I have been working on a Kantronics KPC4 which I bought from PD4R. I am very happy that I can add it to the collection.

Kantronics KAM_KPC-1-2-4-2400_Installation Manual
Kantronics KAM_KPC-1-2-4-2400_Operations Manual

Kantronics KPC4 Firmware

The nice thing is that such modems can also be accessed from BPQ32. Here is a small example.

 ID=Serial TNC KPC4

Bpq32 with QtSoundModem and Hamlib

Yesterday I added 2 HF ports to my Bpq32 Node / BBS. I have chosen to use QtSoundModem and Hamlib. QtSoundModem is a Linux port or Soundmodem from UZ7HO. I use Hamlib/rigctld to take control of the Tranceiver. QtSoundmodem and Hamlib run on a different Raspberry than the BBS and Node.

After some testing I found out that I need Hamlib version 3.3 to control the icom 7300. The versions 4.0 and 4.1 do not work for me. Apparently the icom 7300 is not being initialized. Can’t actually find out why this is. With the command “rigctld -l” you get a list of which tranceivers are supported.

So I need number 373 for the Icom 7300.

/usr/local/bin/rigctld -m 373 -r /dev/ttyUSB0 -s 19200 -T -t 4532 &

In the QtSoundModem.ini I have in the [Init] section.


Now the bpq32.cfg

 ID=14.1022 +1100Hz
  ADDR 8101 ; AGW port of QtSoundModem

 ID=14.1022 +2000Hz
  ADDR 8101 ; AGW port of QtSoundModem

With Hamlib it is also possible to control the TRX from Bpq32. I immediately added a Robust 300 packet port to Bpq32 with rig control. Here is an example.

 ID=Robust 300 ;(RPR Packet)
WL2KREPORT PUBLIC, api.winlink.org, 80, PI8LAP-10, JO11VN, 00-23, 14102200, ROBUST, 25, 35, 3
WL2KREPORT PUBLIC, api.winlink.org, 80, PI8LAP-10, JO11VN, 00-23, 14102200, PKT300, 25, 35, 3
WL2KREPORT PUBLIC, api.winlink.org, 80, PI8LAP-10, JO11VN, 00-23, 144850000, PKT1200, 10, 20, 5, 0
WL2KREPORT PUBLIC, api.winlink.org, 80, PI8LAP-10, JO11VN, 00-23, 430950000, PKT9600, 10, 20, 5, 0
  O 4                   ; MAXFRAME
  F 190                 ; FRACK
  T 8                   ; TX Delay
  USEAPPLCALLS          ; Accept connects to all APPLCALLS
  BEACONAFTERSESSION    ; Beacon after session
  %L 1500               ; Centre Freq for Normal Packet (Default is 1500)
  @I 64                 ; Paclen = 60
  %T 1                  ; TX Autotracking 1 = on
  %N 10
  %B 300


Apr  4 16:34:41 pi1lap : Initialising Port 01     TCPKISS IP Port 8001 Chan A
Apr  4 16:34:41 pi1lap : Initialising Port 02     TCPKISS IP Port 8001 Chan B
Apr  4 16:34:41 pi1lap : Initialising Port 03     SCSTRK /dev/ttyUSB0
Apr  4 16:34:41 pi1lap : Initialising Port 04     UZ7HO Host Port 8101 Chan A
Apr  4 16:34:41 pi1lap : Initialising Port 05     UZ7HO Host Port 8101 Chan B
Apr  4 16:34:41 pi1lap : Initialising Port 06     ASYNC /dev/ttyUSB1 Chan A


Aprs Weather Beacon

Today I’ve been messing around with an APRS weather beacon. Now Direwolf and Linbpq and Jnos can send an aprs weather beacon. It turns out that this is quite precise, with the format of the beacon.

# The weather beacon have to look like this....
# @220424z5057.81N/00729.37E_094/002g005t043r000p006P006h89b09783
# !5133.52N/00348.15E_073/013g...t048h85b10040wWXD
# Jun 01 2003 08:07
# 272/000g006t069r010p030P020h61b10150
# ***********************************************************
# 272 - wind direction - 272 degrees
# 010 - wind speed - 10 mph
# g015 - wind gust - 15 mph
# t069 - temperature - 69 degrees F
# r010 - rain in last hour in hundredths of an inch - 0.1 inches
# p030 - rain in last 24 hours in hundredths of an inch - 0.3 inches
# P020 - rain since midnight in hundredths of an inch - 0.2 inches
# h61 - humidity 61% (00 = 100%)
# b10153 - barometric pressure in tenths of a MILLIBAR - 1015.3 MILLIBARS

My weather station uploads its data to wunderground.com. Now wunderground has the option to read this again with an api key.


You can read here how and what.

After a lot of messing around with a bash script, I am able to create the correct format.

TEMP=-4.9°C Temperature degrees Celsius
WPK=29.4km/h Wind speed in Kilometers per hour
WGK=39km/h Wind guts in Kilometers per hour
GRD=58° Wind direction in degrees
RAIN=0mm Rain in the last hour in mm
RAIN24=0.42065mm Rain in the last 24 hour in mm
RAIN12=0.214mm Rain in the last 12 hour in mm
HUM=74% Humidity in procent
Bar=1004mb Barometric pressure in millibars
FAH=023F Temperature degrees Fahrenheit
WPM=018mph Wind speed in miles per hour
WGM=024mph Wind guts in miles per hour
RNI=000inch Rain in the last hour in inches
RNI=001inch Rain in the last 24 hour in inches
RNI=000inch Rain in the last 12 hour in inches

The file I need to broadcast an APRS Weahter Beacon looks like this.

pd9q@pancake:~/linbpq/wx-project $ cat ~/linbpq/current.txt
Feb 09 2021 13:00

The config file for Linbpq looks like this, this is in the aprs section of bpq32.cfg

WXComment=/Weather Station JO11VN
WXPortList=1,5,IS        ; comma separated list 
WXInterval=10            ; mins

For Jnos in the autoexec.nos in the aprs section

aprs wx call PD9Q-7
aprs wx stat "Weather Station JO11VN"
aprs wx pos "5133.52N/00348.15E_METEO
aprs wx data "/home/pd9q/jnos/wx/current.txt"
aprs bc rftimer 10

For direwolf in the file direwolf.conf

PBEACON LAT=51^33.52N LONG=03^48.15E SYMBOL=”weather station” COMMENTCMD=”tail -1 /home/pd9q/linbpq/current.txt”

Direwolf Aprs packet look like this.


BPQ32 Aprs packet look like this.

0h75b10007/Weather Station JO11VN

Learned a lot.

BPQ32 Yapp file transfer

BPQ32 and QTermTCP support the Yapp Protocol. Let’s take a look at how that works.

First we have to great a Directory  ” Files”  in the root dir of Linbpq. The user Pi must be the owner of the Directory.

cd /home/pi/linbpq
mkdir Files
ls -l
drwxr-xr-x 2 pi pi    4096 nov  1 12:10 Files
* If the user Pi does not own the directory "Files", you can change that with.
sudo chown pi:pi Files

Now we can set QTermTCP to use the directory “Files” for uploads and downloads. In the top menu choose ” Yapp” , ” Set Receive Directory” and choose the correct directory (Files).

First we need to connect to a local BBS that supports the YAPP protocol. Now I have set up a BBS here for this test. As modems I use two Ninotnc`s connected with a null modem cable.
Now we are ready to send a file. Again choose in the top menu “Yapp” and “Send File” Now you can choose which file you want to send.

Here we go…..

Monitor screen from Linbpq BBS.

File compleet.

The same file but compressed.

NinoTnc progress

Boy, I can hit my head against the wall. I made a very rookie mistake. I had  soldered a number of Leds the wrong way round.  Tsss before I finally invented that. Very stupid.
But when I finally found out (it’s even in the description on the tarpn website) it now works the way it should.

Let’s test how the reception is. (aprs on 144.800Mhz @ 1200 Baud)

I feel like he is a little deaf. Looks like he’s missing some frames. Maybe it’s the setup I’m using. I am using a Yaesu ft7800 with the NinoTnc directly on the Mini Din of the radio. I have to figure this out, I will read the Tarpn website one more time.

First let’s update the flash.

Mmmmm, let’s give it a go.


A Linbpq configuration example



I am very happy to be able to add this (Nino)TNC to the collection.

Linux Port of UZ7HO’s Soundmodem

Very good news, John G8BPQ has ported Soundmodem from UZ7HO to Linux.

Mail from John G8BPQ.

Andy UZ7HO has allowed me to port his Soundmodem to C so that it can be run run Linux systems. See


This is pre-Beta software. It has been tested by several people but is likely to still have bugs.

John G8BPQ