Successful Portland NET simplex exercise!

Hello radio enthusiasts, geeks, etc.! Tonight was my first exercise as a certified Portland NET (Neighborhood Emergency Team) ARO (Amature Radio Operator). We operated on simplex nets tonight throughout the city in order to practice communicating directly with each other and PBEM in the event city wide repeater networks failed during an incident.

I decided to test from my staging area tonight rather than operate from home… last time I was out I couldn’t get Pat Winlink going, and I have some new gear to test tonight: a legit collapsible table and a GoalZero LED lantern! There was supposed to be rain tonight, and the plan to cover myself and the top of the table in a tarp and work under it but alas it wasn’t necessary. The rain stayed away and I didn’t need to test my half-baked idea.

My partner and the doggo came out again and hung out with me as I operated. Most of the photos of the deployed setup and of me operating are hers taken for the blog. I should note that I don’t have her help me do any actual setup or tasks related to station operation. The idea is to make sure that I can manage all aspects of setting up, transporting, and tearing down the station without assistance.

Me sitting at a lamp-lit table with a radio on top at night, the antenna mast is in the background.
Set up at my staging area.

Setting up was pretty smooth today even in the dark. I unloaded the antenna mast and propped it up. The table was then set up and the J-pole was mounted on the non-conductive part of the mast. The second half of the 2m element was attached. After that the feedline was connected to the j-pole and the Kenwood TM-V71 was set up inside my weatherproof backpack along with the wireless access point, Winlink Pi, and 20Ah Bioenno LiFePo4 battery. With that and the ARO binder set up I powered the radio up and the resource net was just beginning.

I managed to check in just fine and the resource net controller and had an excellent signal at 5w (minimum power the radio can do). For this exercise the resource net did directed check-ins by call sign suffix. It was pretty smooth and orderly and net control did a good job. There were quite a few participants from various neighborhoods and I could hear almost every station. After all stations had checked in the subnet controller for each city region would announce their frequency and have all operators in that region move to their regional net as specified in the procedure that was sent out ahead of time. It should be mentioned that I uploaded the procedure for the exercise to the documentation server on the Raspberry Pi ahead of time as well. I was, however, missing the Multnomah County ARES frequency template. I need to make sure I have that on the document server.

Antenna mast made of a speaker stand with a wooden closet hanger deployed at the top. Open stub J-pole antenna is fixed at the top.
Antenna mast and antenna deployed

Once on the regional net we checked in using our tactical call signs. We exchanged signal reports and everyone on the net was a 5 (readability) to me which was very nice, and my signal was a 3 or above to everyone else. It looks like my staging area is pretty good in terms of connectivity to the other stations in my city region (Alameda South). Interestingly one of our operators that generally has a great signal to all stations had some trouble hearing the nearby subnet controller. I suspect there might be some multipath interference between that station and the subnet controller resulting in an unexpectedly poor signal.

Table top lit by LED lantern with a backpack containing a radio, a tablet, and zipped 3-ring binder with a partially filled form 8 and a pen on top.
Table setup with form 6 (ICS 309) in a binder, my tablet, and radio gear in a weather resistant backpack.

As we operated the radios we also filled out a form 6, or ICS 309 to track events and messages on our radios. These forms are used to document events and messages during an incident or exercise. When passing messages we fill out or voice form 8s (ICS 315), but we didn’t actually do one tonight.

Once we concluded talking on our regional nets we checked out of them using our tactical call signs, and then tuned back to the resource net and checked out there as well. It took a while to get checked out as there was a lot of doubling (more than one station transmits on the frequency at the same time interfering with other stations). It’s hard to coordinate stations by call sign suffix arriving on the resource net at random times even though the resource net controller was doing a great job.

Everything was good so far! Now it was time to attempt to send e-mail again after my last failed attempt. This time I managed to use the Winlink host and an Android tablet to send an e-mail to both OH8STN and a friend from my staging area over VHF. I had a lot of trouble sending e-mail at first. While the wifi network and applications worked just fine this time I had some challenges sending e-mail due to odd issues with the content. It seems that if the body of he e-mail or subject is too long there are protocol errors. After a few experiments I was able to finally get the messages out.

Time to break down and get some dinner! Breaking everything down was super-smooth this time around. There were no issues and everything packed away nicely! I just rolled the wagon back home and unloaded it!

Folding wagon with cloth sides loaded with equipment lit by street light. The collapsed antenna mast is  sticking from the back of the wagon.
The ham hauler loaded up on the way back home.

Lessons learned:

  • A table makes life a LOT easier when doing this sort of deployment.
  • The Goal Zero LED lantern wokred very well. The adjustable light level is very nice, and even with half the lantern on at the lowest possible power was more than enough for the vast majority of tasks I had to perform from setup to operating and filling forms to breaking down. I did increase the light level a couple times for specific tasks, but I didn’t need to keep the light level up.
  • Make sure you have all the documents you’ll need with you including frequency lists.
  • Having exercise-specific and general guides at your fingertips is a good idea. It helped in this exercise.
  • It takes 45 minutes from loading equipment to being on air for my staging area under more-or-less ideal conditions in the dark.
  • Some changes to the J-pole made it work a lot better in the field. I’ll post an entry the modifications I made.
  • My power cabling was really messy. I could do better.
  • It didn’t rain but I need to figure out a shelter that would protect the table top from wind and rain that can fit in the bag with the table.
  • The exercise seems to have gone well broadly. The check-in process was pretty efficient.
  • The check out process was a bit chaotic but maybe we could implement a system whereby net subnet controllers check into the resource net and once that happens the resource net controller adds that subnet controller’s region to a directed checkout by region. We could cycle through regions until all stations check out.

A successful-ish EMCOMM test deployment

Howdy everyone! I wanted to tell the tale of a short walk with a wagon in the rain followed by some radio tests. I decided I’d like to test moving to my staging area during a disaster response scenario. My goals were to test making contacts with my Yaesu FT3DR and do voice as well as Winlink with my Kenwood TM-V71 and portable Winlink setup. This will also be the first deployment of my Arrow OSJ 146/440 open stub dipole. This model has the split 2m element for easier transport.

Cloth-sided wagon containing various equipment and a backpack leaning against the side.
Wagon with the antenna, mast, and a couple folding chairs. Also pictured is my water resistant backpack with the radio gear and feedline.
Wing nuts installed on the antenna's pipe clamp.
Slightly modified Arrow OSJ 148/440. I replaced the stock hex nuts with 1/4″ 20 wing nuts to remove the requirement for a wrench to install the antenna in the field.

After arriving at my deployment site I removed the 1 5/8″ closet rod from the inside of the speaker stand. The long end of the closet rod stays inside the speaker stand tubing for easy transport. The stop for the closet rod is made from three eye screws that double as guy line connection points. The three eye screws are installed just above the top band of purple duct tape (reduces vibration and motion when the closet rod is installed in the end of the speaker stand).

J-pole mounted to a wooden closet rod resting against a speaker stand. The split 2m element is affixed for transport.
J-Pole with the second half of the 2m radiator threaded in place for transport.

The next step is to install the top portion of the open stub J-Pole.

J-pole mounted to a wooden closet rod resting against a speaker stand. The split 2m element is installed for transmission.
Open Stub J-pole atached to closet rod resting against the speaker stand with the 2m element fully assembled.

After the feedline is attached to the J-pole the closet rod with the antenna attached is installed in the speaker stand with the tape end of the closet rod in the top of the speaker stand. The closet rod is resting on the three eye screws that prevent it from slipping down inside the speaker stand tubing. The two telescoping sections of the speaker stand are fully extended and the locking pins are in place.

Fully extended speaker stand with closet rod and antenna attached. The wagon, my partner, and our dog are off to the side.
Antenna fully extended. Also present is my partner and our dog for moral support.
A picure of the feedline velcroed right above the tripod component of the speaker stand.
A velcro wire tie is used to anchor the feedline to the bottom of the antenna mast to prevent it from being pulled over from the top if someone trips on the cable.
Yaesu FT3DR connected to the feedline with the wagon and antenna stand in the background.
My Yaesu FT3DR attached to the feedline with a SMA to PL-259 pigtail.

I was able to make a couple contacts using the Yaesu HT at 5w and monitored APRS transmissions for a while. So far everything is good.

Hand holding microphone of Kenwood TM-V71. In the background the radio is in a dry bag and sitting on the wagon.
Kenwood TM-V71 connected to the feedline and battery in the backpack. It’s protected from rain by an Ortleib dry bag.

The Yaesu HT is stowed in its bag and the Kenwood mobile radio is connected to battery power and the feedline. It’s also protected from the rain by a 5L Ortleib dry bag. More contacts are made on 2m without issue. I was able to make contacts in Portland, OR, Aloa, OR, Washugal, WA, and Vancouver, WA at 5w. More good news!

Hand holding the Mobinlinkd TNC3 and Raspberry Pi Zero W connected to each other. Radio data connector is also set up.
Winlink host, TNC, and radio connected.

It was finally time to send and receive some e-mail! I connected the Winlink Raspbery Pi to the power supply and the Mobilinkd TNC3 to the data port on the TM-V71. I pulled my phone up, found the generated wireless network, joined it…. and nothing! It partially connects but doesn’t get an IP address. Strange, but no matter. I assigned a manual IP to my phone and tried to connect to the Pi via IP address. The connection still failed. I rebooted the Pi and tried again. The wifi network shows up, I join it, no DHCP IP address. Bummer! All my tests having either been complete or failed it was time to pack up and head home.

At home I boot the Pi and it joins the home wifi network with no issue. I SSH into the Pi and begin reviewing the configuration for Dnsmasq (DHCP/DNS server). Everything looks good and the configuration is valid. I then look at the autohotspot script. It has the default IP address that the script ships with set. Then the “aha!” moment strikes. As part of writing my Winlink host setup guide I re-ran the Autohotspot install script so I could make sure my documentation was right. The fix is now obvious: I just changed the IP address in the Autohotspot script, kicked the Winlink host off my wifi network and restarted it. I’m now able to connect, get an IP address, and connect to Winlink and the documentation server!

Lesson learned… always re-test your setup after you mess with it, and if you re-run a setup script you should verify that your setup runs properly afterward. Fortunately this was not a emergency deployment and was close to my QTH.

Other things I learned from today:

  • The wagon doesn’t negotiate steep curbs well without a bit of finesse.
  • The antenna mast should be lashed in place on the wagon during transport so it doesn’t move in the wagon.
  • The wing nuts on the J-pole can get over-tightened easily making it hard to dismantle the setup.
  • The allthread stub that connects the two parts of the 2m element on the J-pole can be unscrewed easily and lost when the element is being removed. I’ve dropped it 3 times in the first 48 hours of having the antenna. Some red or blue Loctite is probably a good idea to keep the end of the stub fixed in the removable portion of the 2m element. The red (permanent) Loctite will also keep moisture out of that joint.
  • Sometimes the telescoping tubes on the speaker stand stick.
  • I live in NW Oregon and figuring out a wind and rain shelter is probably a good idea.
  • The speaker stand is pretty stable and sturdy. It will probably work without guying in mild wind.

Portable UHF/VHF Winlink host

Howdy! I had recently posted about some Raspberry Pi based systems that can be used in the shack or in the field and those posts received a lot of questions about how they were set up. This post is the first in a series that seeks to explain the design, operation, and setup of these hosts. Some of the work I did here was inspired by Julian, OH8STN’s general off grid/grid down operating philosophy and K1CHN’s blog posts.

A Raspberry Pi W Zero in a clear acrylic case connected to a Mobilinkd TNC3 with a MicroUSB OTG cable, host end connected to the Pi's USB OTG port.
Raspberry Pi Zero W connected to Moblinkd TNC3 using a MicroUSB OTG cable.

So, what are we talking about here?

  • A Raspberry Pi Zero W / Raspbian based Pat Winlink host.
  • Designed to work with packet on UHF/VHF radios.
  • Compatible with a wide range of radios.
  • Runs on USB or 12v and has typical 45A Anderson PowerPole connectors in a “right hand red” configuration when running on 12v. This matches my off grid power setup and the ARES + RACES standards.
  • Uses a Mobilinkd TNC3 to work with a variety of UHF/VHF radios and to offload signal processing to a TNC. That means we don’t need as much processing power on the compute node. Multiple adapter cables are sold on the Mobilinkd store and you can make your own.
  • Automatically sets up and tears down the AX.25 port and connection based on the status of the TNC’s USB connection.
  • Nice, tidy web interface that can be used by any device with wifi capabilities and a fairly modern browser to send and receive e-mail.

Parts list:

  • Raspberry Pi Zero W and power supply
  • MicroSD card
  • Optional Pi Zero W case
  • Mobilinkd TNC3
  • Appropriate cable, purchased or constructed to connect from the TRRS jack on the TNC3 to your UHF/VHF radio
  • MicroUSB OTG cable for the Pi to TNC3 connection.
  • Optional USBBuddy (12v to 5v USB down converter)
  • Optionally short USB A to MicroUSB cable to cut down on voltage drop.
  • UHF/VHF radio of choice. This setup has been tested with a Baofeng UV-5R, Yaesu FT-857D, Yaesu FT-3DR, Kenwood TM-D710G, and a Kenwood TM-V71 but should work with many others. The Mobilinkd TNC3 was designed to work with a broad range of radios.

Theory of operation:

Block diagram showing control flows between and connections between the operator, radio, devices, and between the TNC and Raspberry Pi. The diagram also depicts the control flows between the TNC, ax25.service, Linux AX.25 subsystem, and Pat Winlink. Flow charts depict AX.25 service flows and a wifi flow chart describing when the system decides to host its own wifi.
Block diagram showing various system components and their interactions. Flow charts for managing the AX.25 service and self-hosted wifi.

The Pi leverages a number of smaller subsystems to provide e-mail access.

  1. Scripts and applications that provide AX.25 setup and teardown as the TNC is connected or disconnected. These scripts leverage udev and systemd to detect state changes on the TNC. While you can use Bluetooth to maintain these connections it’s easier and more simple to control connections to the TNC using its USB connection status.
  2. A set of scripts, services, and utilities that automatically provide a functional wireless network in the event the Pi is unable to connect to a known network. This includes DNS and DHCP.
  3. Pat Winlink is run as a systemd service so the operator doesn’t have to worry about starting and stopping the service. It can run in the background whether or not the TNC is connected, but it can’t send or recieve e-mail without the TNC connected.
  4. Pat Winlink is accessed via a web interface. You need a phone, tablet, or computer that can connect to the wireless network generated by the Pi, or is on the same network as the Winlink server. This allows an operator to use Winlink.

Setup process

Start by installing Raspbian on your MicroSD card and getting your Raspberry Pi up and running. The steps here should work. Make sure you give your pi a hostname like “winlink” or whatever you’d like. If you configure dnsmasq this becomes important. Once your Pi is up and running with an Internet connection we can pre-install needed utilities and software so we don’t have to do it later. We’ll also make sure dnsmasq and hostapd don’t start automatically (more on this later). These commands can be done from the Raspberry Pi’s terminal application or from an SSH session if you’ve enabled it:

sudo apt-get update -y && sudo apt-get upgrade -y
sudo apt-get install libax25 libax25-dev ax25-apps ax25-tools dnsmasq hostapd git
sudo systemctl disable hostapd
sudo systemctl disable dnsmasq

Once we have all that installed we’ll install and configure Pat Winlink. Download the latest Pat Winlink release from GitHub. You’ll want to make sure you choose the armhf (Raspberry Pi) .deb file. Make sure you note the name of the file as it will be important when running the install command. When you’re ready to upgrade Pat Winlink in the future you can download the newest version of the .deb file from the same page. Assuming you’ve downloaded the file to the Downloads folder you can run the following command to install Pat Winlink, replacing “pat_0.10.0_linux_armhf.deb” with whatever file name you downloaded:

sudo dpkg -i ~/Downloads/pat_0.10.0_linux_armhf.deb
mkdir ~/.wl2k

After we configure our AX.25 settings we can come back to configuring Pat Winlink as we’ll need some values from that setup.

Next we’ll edit /etc/ax25/axports. This file configures our AX.25 ports that get used to build connections to packet Winlink gateways. Mine looks like this. You’ll of course want to replace my callsign with yours. The port we configure below will be called wl2k. This will be needed for the Winlink configuration in a number of spots.

# /etc/ax25/axports
# The format of this file is:
# name callsign speed paclen window description
wl2k K7JLX 9600 255 7 Winlink (9600)

In the next step we’ll create three files – a script that manages AX.25 port connections, a systemd service that manages the AX.25 port, and finally a udev rule that starts and stops that systemd service when the Mobilinkd TNC3 shows up as a USB serial device or is disconnected.

First, let’s install ax25-up, a script in the Winlink project that manages AX.25 connections. Our systemd unit depends on it. The commands in this step come from here, but are slightly modified to put the script in a different location on the Pi.

sudo curl -o $bin
sudo chmod +x $bin

Next we’ll add the udev rules that work with systemd to start and stop the service. Add the following contents to /etc/udev/rules.d/99-hamradio.rules:

# Mobilinkd TNC3
ACTION=="add", ATTRS{idVendor}=="0483", ATTRS{idProduct}=="5740", ATTRS{manufacturer}=="Mobilinkd LLC", SYMLINK+="ttyTNC", TAG+="systemd", ENV{SYSTEMD_WANTS}="ax25.service"
ACTION=="remove", SUBSYSTEM=="usb", ENV{PRODUCT}=="483/5740/200", TAG+="systemd"

We’ll now create our systemd unit file which should be: /usr/lib/systemd/system/ax25.service Note the ExecStart command where we use our wl2k port, and /dev/ttyTNC as created by our udev rules. That device is created in the event we attach another USB serial device to create a predictable name no matter what the proper udev name of the device is.

Description=AX.25 KISS interface
ExecStart=/usr/sbin/ax25-up /dev/ttyTNC wl2k 9600
ExecStop=killall kissattach

Configuring and setting Pat Winlink up as a service

First we’re going to put in a configuration for Pat Winlink. We’ll do that by editing ~/.wl2k/config.json. You’ll want to replace the values I have in my configuration with your own. I’m connecting to a station called W7LT-10 most of the time. You’ll also want to remove your password until you’ve set one. Follow these instructions for that process. Replace your callsign and grid square locator with your own. You may also want to add your own connect_alias entries. These can be various Winlink stations you want to “bookmark” for quick connection. I’ve added a number of them for use while I’m out camping. In that list you might have noticed the one beginning with “!W7LT-10”. Since I use that one most commonly I added an ! to the front of the name to keep it at the very top of the list when it’s alphabetized by the Pat Winlink application. The http_addr directive tells Pat Winlink to listen on any address on port 8080. This will be important when constructing the URL to access Pat Winlink with. You may also notice that I’ve configured this to listen on ax.25 and telnet. This allows the Pat Winlink application to listen in peer-to-peer mode for incoming connections. You don’t have to switch between peer-to-peer and CMS mode manually like you would using Winlink Express. You may want to assign a new telnet password if you want to keep the listen entry for telnet.

  "mycall": "K7JLX",
  "secure_login_password": "VerySecret",
  "http_addr": "",
  "listen": ["ax25", "telnet"],
  "locator": "CN85qm",
  "motd": ["K7JLX Pat Winlink stn"],
  "connect_aliases": {
    "!W7LT-10, 144.910MHz, PDX": "ax25:///W7LT-10?freq=144910",
    "K7HWY-11, 145.030MHz, La Pine, OR": "ax25:///K7HWY-11?freq=145030",
    "KB7EOC-10, 144.950, Tillamook, OR": "ax25:///KB7EOC-10?freq=144950",
    "KG7AV-10, 145.030MHz, Bend, OR": "ax25:///KG7AV-10?freq=145030",
    "W7EUG-10, 145.030MHz, Eugene, OR": "ax25:///W7EUG-10?freq=145030",
    "W7GC-11, 144.950, Hebo Lake, OR": "ax25:///W7GC-11?freq=144950",
    "WC7EOC-10, 144.980MHz, Hillboro, OR": "ax25:///WC7EOC-10?freq=144980",
    "WW7CH-10, 145.050MHz, Eatonville, WA": "ax25://WW7CH-10?freq=145050",
    "N7GWK-10, 145.630MHz, Centrailia, WA": "ax25://N7GWK-10?freq=145630",
    "N7DEM-10, 144.920MHz, Longview, WA": "ax25://N7DEM-10?freq=144920",
    "W7BO-10, 144.920MHz, Woodland, WA": "ax25://W7BO-10?freq=144920",
    "KA7CTT-10, 144.920MHz, Vancouver, WA": "ax25://KA7CTT-10?freq=144920",
    "W6TQF-10, 145.055MHz, Underwood, WA": "ax25://W6TQF-10?freq=145055",
    "N7YRC-10, 144.930MHz, Yakima, WA": "ax25://N7YRC-10?freq=144930"
  "ax25": {
    "port": "wl2k"
  "telnet": {
    "listen_addr": ":8774",
    "password": "AlsoVerySecret" 

Now that we have a solid initial configuration let’s set Pat Winlink up as a service that starts automatically when the Pi boots. The first step is creating a new systemd unit at /lib/systemd/system/pat.service which will run as the standard pi user that ships with Raspbian. The contents of that systemd service are as follows:

Description=Pat Winlink HTTP server
ExecStart=/usr/bin/pat http

Now we start and enable the service by running some commands in the terminal. The last command should show Pat up and running with a green “active” status. You can press “q” to quit the status display.

sudo systemctl enable pat
sudo systemctl start pat
sudo systemctl status pat

To test all the work we’ve done thus far reboot your Raspberry Pi using the GUI or by issuing the following command in the terminal:

sudo shutdown -r now

Once your Pi is back up and you’re logged back in as the pi user we’ll connect the Mobilinkd TNC3 to the Pi using the MicroUSB OTG cable. The host side connects to the Pi’s USB port, not the power port. After plugging the cable in press the connect button on the Mobilind TNC3. You’ll see a yellow flash on the TNC’s status LED. This momentary button press should trigger the ax.25 systemd service to start. We can check on that by running the following command:

sudo systemctl status ax25

If you see that the service is active and green you’re good to go on the base Winlink functionality. The only thing left to do is connect to it. Use your browser connect access Winlink with a URL derived from this template: http://<your winlink hostname or IP>:8080

If you want an automatic hotspot proceed to the next step.

Automatic hotspot

For this part of the guide just follow the steps that Raspberry Connect lists. You can modify their scripts to create IP addresses and wireless network names/passwords as needed. You can modify the /usr/bin/autohotspotN script and set the IP address there. In the createAdhocNetwork() function modify the ip a add line with the desired IP and subnet mask.

After the scripts scripts have been run and things have been configured you can optionally set up DNS records in dnsmasq. My configuration looks like this but yours will certainly vary. The static IP addresses and DNS records help Android devices or other systems that don’t work well with MDNS find your winlink service. You can use any network you want. The dhcp-host line for winlink.local is commented out because the host we’re running won’t get a DHCP address from itself. The additional entries help other Raspberry Pis or other devices get static IPs and allow them to be found by hosts. In this way we can make sure any devices that connect to your network that offer services show up. Make sure the ‘address’ line matches the hostname of your pi, and that the IP matches the one you set after the RaspberyConnect’s script run in the previous steps.


Multicast DNS (MDNS)

To help devices that support MDNS automatically discover the winlink service we can add a configuration file to Avahi. To do that create a file at /etc/avahi/services/winlink.service:

<?xml version="1.0" standalone='no'?>
<!DOCTYPE service-group SYSTEM "avahi-service.dtd">
  <name replace-wildcards="yes">Winlink on %h</name>

Now restart Avahi using the following commands:

sudo systemctl restart avahi

At this point if your pi can’t reach a known wifi network it should start its own. Make sure you test it before you need it to work in a real-life situation.

As a bonus you can create a document server on the Pi to make sure you have information, forms, manuals, etc. when you need them in the field.

Updates to this blog entry:

4 Sep, 2021 – The Pat Winlink configuration section was updated to reflect changes I’ve made since the original draft of this entry.