Archive for August, 2011



Chewing on a rawhide stickIn 1995, I bought a puppy as a present for my wife, who was out of town for a few weeks. I wanted her to have a companion around the house while I was at work or on business trips, someone who could bark and warn her when there were noises in the yard.

I named her “Maggie”, and I set out to train her on the basics of living in a house.

When my wife got home, Maggie and I met her at the airport.  I was disappointed to learn that she and I did not share the same enthusiasm for pet ownership.  Making matters worse, Maggie seemed to be confused about this strange woman who had just shown up and taken all of my attention.  This battle lasted for a couple of years.  Unfortunately, the house-training exercises also took a couple of years.

Maggie stayed with us, and she eventually learned the difference between carpet and grass.  She learned her place in the family. She became a constant companion. She reminded us to go outside and get some fresh air.

She moved with us to new places, including a year and a half in Singapore.  She watched as our family grew, and she dutifully accepted her demotion with each new child.  She slept on our bed, keeping us warm on cold winter nights, and reminding us not to sleep too late on Saturday mornings. She also kept our kitchen floor clean.

As she got older, she became less interested in fetching tennis balls and going for walks, preferring to stay inside, and enjoying her quality nap time. But every day, when I came into the driveway, she would look out the window to see who it was, and she would greet me as I came inside.

A few months ago, she started showing the inevitable signs of age. I could sneak in without her hearing me. She sometimes needed help going up and down stairs.  She fell off of the bed a couple of times, and so was demoted again — to a floor-sleeper.  She started wearing diapers at night.

Shortly after her 16th bithday, Maggie grew weak, not wanting to get up to go outside any more. The vet confirmed that she only had a few more days with us. So I stayed with her at night, comforting her while she slept.  And today, I worked from home so I could be next to her.  This morning, while I worked, she quietly slipped away.

For 16 years, Maggie was a good dog, a close friend, and an essential member of the family. We are grateful that she chose to stay with us for all of that time. She will be sorely missed by all of us.

More photos of Maggie are in our photo gallery.

APRS iGate


When I was working with the NC Nearspace group on our high-altitude balloon, we experimented with two different methods of tracking it once aloft: ham radio APRS, and a commercial system called “SPOT“.

We had some early failures with APRS.  But over time, we have found that it’s a pretty nice technology, if you use the proper equipment.

APRS, or “Automatic Packet Reporting System”, is a system that passes data packets over radios. It can be used for passing text messages, but most people use it for telemetry: tracking a vehicle’s position with a GPS, or on a weather station that broadcasts its weather readings every so often.

Since we have been playing with APRS on our balloons, I wanted to learn more about it. I have been keeping my eyes open for a reasonably-priced handheld radio that can encode and decode APRS packets. Sure, some people use a special radio modem (called a “TNC”) to do the encoding/decoding, but it’s important to me to have the modem and the radio in a single package, so I won’t have a big tangle of wires. This week, one such radio popped up on eBay, and so I bought it. While I waited for it to arrive, I did some homework on APRS and what it could do.

Building an iGate at home

My "mobile" radio at home

I already have two 2-meter radios: a small handheld “handy talkie” and a larger “mobile” radio that is designed to be installed in a car. So I tuned the mobile rig to 144.390 MHz and listened. It was a lot of static, with occasional squawks of data.

Most of the time, if you wanted to decode the squawks, you would buy a packet TNC (modem) to convert the squawks to data, and you’d hook the modem to a computer to use that data. But then I read an article about using your computer’s sound card to encode and decode the packets directly, with no modem at all. Heck, I was sitting around at home waiting for my new handheld-with-built-in-modem to arrive. Why don’t I try to do this modem-less setup?

Look, Ma, no modem!

The first thing I did was hook the speaker output from the radio to my computer’s “audio in”. Optionally, I could have hooked the computer’s “audio out” to the microphone input of the radio. That second step is more complicated than you’d think, because I would also need to hook SOMETHING — maybe a parallel port pin — to the radio’s “push to talk” or “PTT” to turn the transmitter on before it’s ready send a squawk of data over the air.  You really don’t want to just let it transmit all of the time… because other people are using that radio channel, too.

My modest Linux server

I chose the simple receive-only option, setting up my Linux-based server to “listen” to the radio. I downloaded a package called soundmodem, which is a APRS decoder program. It listens to the noise and the squawks, and it outputs a stream of decoded data.

Soundmodem is hard to set up on a headless server, because the normal setup process involves running a graphical configuration program called “soundmodemconfig”.  Since my server is “headless”, I don’t have a monitor or a keyboard or a mouse.  I just connect to it over the network.  So I could not run soundmodemconfig.  So instead, I ran this program on my laptop and I copied the resulting configuration file back to the server. It was a pretty simple XML file that looked like this:


<?xml version="1.0"?>
  <configuration name="KISS">
    <channel name="Channel 0">
      <mod mode="afsk" bps="1200" f0="1200" f1="2200" diffenc="1"/>
      <demod mode="afsk" bps="1200" f0="1200" f1="2200" diffdec="1"/>
      <pkt mode="KISS" ifname="sm0" file="/dev/soundmodem0" unlink="1"/>
    <chaccess txdelay="150" slottime="100" ppersist="40" fulldup="0" txtail="10"/>
    <audio type="soundcard" device="/dev/dsp1" halfdup="1"/>
    <ptt file="none" gpio="0" hamlib_model="" hamlib_params=""/>

The important parts are where it says it’ll read the audio device /dev/dsp1 and it’ll create a KISS-mode packet device called /dev/soundmodem0.

To start the APRS decoder program, I just run /usr/sbin/soundmodem /etc/ax25/soundmodem.conf &. If it all works, then I can just do tail -f /dev/soundmodem0 and see some packets on the screen, with some header garbage and then some readable payload data with a bunch of callsigns.  That is enough of an indication that the decoding is working correctly.

The iGate software

The second piece of software I installed was a digipeater package called APRS4R. I had read a story about a guy who put a small TNC (radio modem) board inside of a Linksys WRT54G router and turned it into a very small portable digitpeater. He ran APRS4R on the router, and so I figured that this program must be pretty lightweight. So I should be able to run it on my modest Linux server.

APRS4R is written in Ruby (that’s what the “for R” ending means), and it is configured using a single text file. Here is the configuration file that I came up with.

--- !ruby/object:APRS4R::APRS4RConfiguration
version: 1.0.2
  device0: !ruby/object:APRS4R::AX25SocketConfiguration
    name: rf0
    type: AX25Socket
    enable: true
    call: KR4JB
    device: /dev/soundmodem0
    baudrate: 9600
    mode: kiss/tnc2/northlink
    duplicatePeriod: 20
    parameters: !ruby/object:APRS4R::KISSDeviceConfiguration
      name: kiss port
      type: KISSDevice
      enable: true
      remote: false
      deprecated: false
      device: /dev/soundmodem0
      baudrate: 9600
      speed: 1200
      timeout: 300
  device1: !ruby/object:APRS4R::ISSocketConfiguration
    name: is0
    type: ISSocket
    enable: true
    hosts: []
    port: 14580
    username: KR4JB
    filter: "# filter m/100"
    duplicatePeriod: 20
    timeout: 60
  plugin1: !ruby/object:APRS4R::BeaconPluginConfiguration
    name: igate is beacon
    type: BeaconPlugin
    enable: true
    device: is0
    period: 1200
    offset: 30
    message: !ruby/object:APRS4R::APRSMessage
      source: KR4JB
      destination: AP4R10
      path: []
      payload: "!3546.30N/07852.07W-&APRS4R CARY NC"
  plugin10: !ruby/object:APRS4R::GatewayPluginConfiguration
    name: rf02is0 Gateway
    type: GatewayPlugin
    enable: true
    inDevice: rf0
    outDevice: is0

My house on the map at APRS.FI

It’s kind of verbose, but it basically defines two devices called “rf0” (the radio) and “is0” (the internet).

Then it defines a few “plug-ins”, which are actions. I use two actions: a beacon that sends my call letters and position to the APRS internet site, and a gateway that forwards (some) packets from the radio to the internet.

If I had hooked up my radio to transmit as well as receive, then I would have also transmitted a beacon on the rf0 channel, and probably forward some of the incoming internet packets to the radio.

The only tricky bits in this file were:

  • For the “is0” destination, I chose a random host from a list that I saw in example files. Mine is “”.
  • The “destination” in the beacon is AP4R10. That is the code for the APRS4R software package. I have no idea why I send my beacons TO some oddly-named station to signify that I am using this digipeater software package.
  • The “payload” string in the beacon is "!3546.30N/07852.07W-APRS4R CARY NC". It consists of a few parts: a bang, my latitude, slash (means “primary icon set”), my longitude, minus (means “house icon” in the primary icon set), and the rest is a comment with my software package name and my location city and state.
  • I had a hard time choosing which SSID (dash number after my callsign) to use. I finally decided that it does not really matter, because there are several conflicting conventions. But I like using “KR4JB” with no suffix to mean “home”. I will use “-1” for my new handheld and “-2” on the (internet-only) OpenAPRS app my iPhone.  If I buy more toys, they will get higher numbers.  Balloons typically use “-11”.

Stuff I didn’t do – and why

There were other APRS4R plugins that did stuff like full two-way digipeating and sending beacons on the radio. But my station is a one-way iGate, so I did not need them. My station forwards packets that it hears on the radio to the internet. It does not forward internet packets to the radio.

And my station is not a digipeater, it does not retransmit packets that it has heard on the air.

I run my station as a receive-only iGate for two reasons:

  • Most immediately, I did not have a cable to hook into the microphone jack of my mobile radio, and rigging up the PTT looks like a hassle.
  • More importantly, you need to coordinate with other digipeaters and gateways around you before you start transmitting packets over the air.

This has all been a lot of fun, and I have learned a lot about packet radio.  Since I went down a few wrong paths, I learned a lot of stuff that was not immediately applicable.  But in this article, I have summarized the parts that got my receive-only iGate working in a single afternoon.

Now I am waiting for my new APRS-capable radio to show up!

Go to Top