Using offline maps with

One of the great things about the APRS system is that it can function in areas where the Internet doesn’t reach. But, with many APRS clients, even though you can receive the coordinates of various stations and objects, it can be difficult to visualize these items without the benefit of a map underneath. And so, the quest to use maps without Internet is born.

The most popular mapping systems today are those provided by Google, Apple, and OpenStreetMap. The way that most of these systems work is that there is are clusters of servers on the Internet that have large amounts of storage. The mapping data is pre-rendered into a series of tiled images at different zoom levels. As you pan and zoom around the map, your mapping application will fetch the appropriate tiles from the tileserver.

Of course, without an Internet connection, your mapping application cannot contact the tileservers in order fetch the tiles. This results in blank areas of the map. So how do we get these tiles when we’re offline?

Enter OpenStreetMap.

OpenStreetMap is built by a community of mappers that contribute and maintain data about roads, trails, cafés, railway stations, and much more, all over the world.

The challenge is that the OSM project maintains its maps as a database of map elements; it’s not a set of images that can be displayed on screen. In fact, the OSM source data does not even specify what these mapping features, roads, waterways, etc, should look like; the OSM maps that we see on the web are the result of applying particular styling information.

What we need is a way to render the source OSM data into a set of tiles, but in a local manner, not relying on the online tiles. I had considered building this rendering functionality directly into, but ultimately decided to keep it external to QTH.ap. This has a least a couple advantages: 1) The functionality can be changed without having to update and 2) multiple installations can potentially share a tileserver. More on that later.

The team over at Switch2OSM have developed a way to run the same tileserver technology found on the Internet on your local machine.

To do this, we’ll be using Docker Desktop. Docker is a technology that allows a packaged set of programs to run inside a “container”. This makes it easier to start, stop, and move around this container and keeps it separate from the rest of your machine.

I am going to assume that you are installing the tileserver on the same machine that your are running, so the instructions are for macOS. Also, you will see several commands to run; these should be run in the

Setting up the Docker tileserver

    1. The first step is to install Docker Desktop for macOS.
      • While Docker is running, there should be an icon that appears on your menu bar that allows you to view the dashboard and start and stop the Docker engine.
    2.  Next, we will create a volume in Docker that will provide storage space for the database
      • docker volume create openstreetmap-data
    3. Make a directory to download the OSM data to. I chose to create a folder called “osm” in my home directory
      • mkdir ~/osm
    4. Download a subset of the OSM dataset in the “Protocolbuffer Binary Format” (PBF).
    5. Import the dataset into the Docker container’s database
      • docker run \   
        	-v /Users/weston/osm/michigan-latest.osm.pbf:/data.osm.pbf \
        	-v openstreetmap-data:/var/lib/postgresql/12/main \
        	overv/openstreetmap-tile-server \
      • Let’s break this command down:
      • The -v parameters tells Docker to mount a volume, where the format is [location_on_the_host]:[location_inside_the_container]
      • The first -v in the example mounts the .pbf file into the container. You will need to change the path to the .pbf file to reflect wherever you downloaded it.
      • The second -v in the example mounts the openstreetmap-data volume that was created earlier to the correct path for the PostgreSQL database inside the container.
      • The overv/openstreetmap-tile-server is the name of the Docker container to run. Docker will automatically download the container. If you would like more details on this container, go to
      • The last part, specifies what command to run inside the container. In this case, we want to import the data.
      • This command will take several minutes to run, depending on the size of the dataset to import. When the import is complete, the container will terminate.
    6. Run the tileserver
        • docker run \
          -p 8080:80 \
          -v openstreetmap-data:/var/lib/postgresql/12/main \
          -d overv/openstreetmap-tile-server \
      • Again, breaking the command down:
      • The -p parameter sets up a port mapping, where the format is [port_on_the_host]:[port_inside_the_container]
      • The web server inside the Docker container will be running on port 80. On your machine, though, you will want to choose a different port, like 8080. Whatever port you choose, you will need to remember it for later.
      • Again, the -v parameter mounts the openstreetmap-data volume for the database.
      • The -d parameter causes the container to detach from the terminal session and run in the background.
      • Same docker container as before
      • The run command starts the programs necessary for running the tile server.
    7. Test it!


  1. In, go to ViewNew LayerLocal Tile Server
  2. The URL Template should be http://localhost:8080/tile/{z}/{x}/{y}.pngYou should adjust the port number if you chose a different one above.
  3. Click Ok
  4. That’s it! You should now see the tiles start to appear in

Advanced Configurations

In the above example, the tileserver is running on the same machine that is running However, this is not required; the tileserver can run on any other machine that is capable of running Docker and that your Mac can access.

  • You could run the tileserver on a Raspberry Pi running Linux
  • You could share the tileserver among several client machines

Of course, any time you separate and the tileserver, there will need to at least be a TCP/IP connection between the two. An example scenario of where this might be desirable is you had a field operations center where you were running a search and rescue operation or a race and you wanted several workstations monitoring the situation with You could either have one of the Macs set up an ad-hoc WiFi network or use a wireless router. Keep in mind that if the tileserver is running somewhere else, you will need to change the ‘localhost’ in the URL Template to the appropriate hostname or IP address of the tileserver.

Good luck and happy mapping!

Using Your Phone as a GPS in

By default, uses the built-in Location Services on macOS to determine your location in order to beacon your position to the APRS network. While this is more convenient than having to manually enter your location, it has some drawbacks.

According to Apple,

Your approximate location is determined using information from local Wi-Fi networks, and is collected by Location Services in a manner that doesn’t personally identify you.

I confess, the manner in which it truly works is still a mystery to me. But, what is clear is that:

  1. Location Services on macOS uses WiFi to determine your location
  2. The MacBook laptops, while portable, do not contain GPS receiver hardware inside them, like an iPhone does

When added up, it’s clear that if you are traveling down the road in a vehicle, Location Services is not going to give you accurate position information. For that, you really need a GPS device.

Ok, but what if you don’t have a GPS?

Do you have an iPhone?

If you have an iPhone, you have a GPS device. The tricky part is getting the data from the iPhone to the MacBook, where can make use of it. Fortunately, as they say, ‘there’s an app for that’.

The app in question, is GPS2IP from Capsicum Dreams.

You will likely want to purchase the full edition, because the free edition is time limited, but the free edition can be used to try it out.

To use this app with, here are the steps:

  1. Open GPS2IP and tap Settings
  2. Under ‘Network Selection’, choose ‘Bluetooth’
  3. Tap ‘Done’
  4. Back on the main screen, use the toggle switch to turn GPS2IP on
  5. In, add a new “Bluetooth LE GPS” connection.
  6. When GPS2IP is running, you should see the name of your iPhone appear in the drop down list. Choose it.
  7. Click Ok
  8. Start the connection will begin receiving location updates from you phone just as if you had connected a serial GPS device!


Decoding APRS packets with an SDR

One minor goal I had when creating was to make it inexpensive and easy to get started with APRS on a Mac. In this post, I’ll show you how to set up what I think might be the least expensive setup for receiving APRS packets over radio, beyond the cost of the Mac itself, of course.

I’m going to be focusing on the receive aspect of APRS. To transmit, you will likely want to invest a bit more money in a quality radio.

Most hams these days have one or more Baofeng radios on hand, and, while you can get your hands on them starting at $35, you would still need a way to interface it to your computer. To do that properly, you probably will need something like a Mobilinkd TNC3 or a SignaLink USB, both of which cost over $100.

However, you can get a RTL-SDR dongle for around $36, plug it into an available USB port and start receiving radio signals.

Step 1: Installing an Audio Router

This is the “secret sauce” to the whole setup. An audio router is a special macOS audio driver that allows you to pipe the audio output from one application to the audio input of another app.

There are two free options:

Both of these function pretty much the same. In my experience, Soundflower implements more of the audio driver API so you get less error messages when it comes to setting volume and such, but it has more trouble keeping up with Mac releases in its support history. It was originally supported by Rogue Amoeba, but is now in the hands of the original author. If you would like a commercially supported option, check out Loopback from Rogue Amoeba.

Choose an option and install it using their instructions. When you are done, you will see a new audio device in your System Preferences → Sound, in both the Output and Input tabs.

Here you can see what my Input tab looks like, with both BlackHole and Soundflower installed:

Step 2: Converting FM to Audio

APRS signals are transmitted as AFSK (Audio Frequency-Shift Keying), which means that audio tones are transmitted using FM modulation. If you’ve ever listened to an APRS packet, you’ll know that it sounds like an old-school modem, because, well, it basically is.

A Software Defined Radio (SDR) like the RTL-SDR captures a portion of the radio spectrum and sends this data via USB as a sequence of I/Q samples. We need to do two things to this stream of data before can process it: it needs to be converted from I/Q format and processed by an FM demodulator.

Fortunately, there are a number of applications out there that do this, a subset, of course, that run on macOS:

  • rtl-sdr – command line app. You would need to run rtl_fm and pipe the output to an audio player, like SoX‘s play command
  • GNU Radio – it should be possible to assemble a flowgraph in GRC that reads data from the SDR, processes the signal with a FM demodulator block, and sends the output to an audio device.
  • CubicSDR
  • GQRX

For the purposes of this post, I’ll be using CubicSDR, because I found it to be the easiest to use of all the options.

  1. When CubicSDR starts, choose the RTL-SDR and click Start
  2. Tune the SDR to the national APRS frequency, 144.39 MHz. I made a bookmark in the lower left panel so that I can instantly jump to the right frequency.
  3. Select the FM modem in the upper left panel, and then, under FM Settings, choose the audio router device that you installed in Step 1. In the screenshot, the audio device I have selected is Soundflower. The full name of the device is “ma++ ingalls for Cycling '74: Soundflower (2ch)

Step 3: Decoding APRS packets

  1. Start
  2. Open the Connections window. Click on the plug icon on the tool bar, or use Window → Connections
  3. Click the + button to add a new connection, choose ‘Audio Modem’, name it whatever you would like, and click Create.
  4. Click the gear icon next to your new Audio Modem connection to bring up the configuration panel.
  5. For Audio Output, you may choose any device you want, since you will not be transmitting anything. I chose my built-in speakers
  6. For Audio Input, choose the audio router device you installed in Step 1.
  7. Click Save to save the settings and close the panel.
  8. Toggle the switch to start the Audio Modem connection.

And done! Using the audio router, CubicSDR will convert the incoming signal to an audio stream and will decode APRS packets from the incoming audio stream.

Bonus Trick: Getting Data From Someone Else’s SDR

Ok, so you might be in my situation – I have an RTL-SDR, but I live in an area where there is very little actual APRS activity on the local airwaves. What if I wanted to listen to the airwaves somewhere else?

You can try out This website features a number of SDR receivers that have been connected to the Internet. You can tune to the APRS frequency and listen to the audio.

The only catch here  is that many web browsers do not give you an option to select an alternate audio output device; they simply send all audio to the system default device. If this is the case, and you want to route the audio to, you would need to go into System Preferences → Sound and choose the audio router device as your system output device. Just know that while this is set, all other audio, such as alerts or music, will go there as well. This won’t bother any, but your computer will be a bit quiet while you have it set up this way.

Adventures in Fox Hunting

Last night’s topic for Home School Ham Radio was antennas, so I figured what better way to demonstrate a directional (Yagi) antenna than to have a mini fox hunt in Fremont Park. Sounds fun, right? Except that, when I decided to do the fox hunt, I had neither a directional antenna nor a fox transmitter. So, 2 weeks prior, I decided to remedy that problem.

First off, I should probably step back and explain what a “fox hunt” is, for any one who might have no clue. Basically it’s a game that amateur radio people sometimes like to play; a high tech version of hide and seek. Someone builds (or buys) a small, portable transmitter and then hides it somewhere. Its sole job is to send out a beacon periodically on a given frequency. Then the hider gives the frequency and any other clues or details to the seekers. The seekers are armed with a radio and a directional antenna. Because the antenna is directional, the beacon should get stronger when pointed in the direction of the fox and weaker when pointed away. Using this setup, the seekers can travel in the direction of the signal, triangulating along the way, and hopefully find the fox wherever it might be hidden.

If you start miles away from the fox, the signal is generally weak, so the signal should disappear when the antenna is pointed away from the fox. However, once you start to get close, the signal gets so strong that it will seem like the signal is coming from all directions. In fact, if you’re close enough, you can even detach the antenna from your radio and it will still pick up the signal. This becomes a problem when locating the fox in that last mile or so. In my case, I knew that I would be hiding the fox somewhere within the park, so we would be starting out really close.

Step 1: Attenuator

So, the first thing that I built was an “attenuator”. The dictionary definition of “attenuate” is:

to weaken or reduce in force, intensity, effect, quantity, or value:

And that’s exactly what an attenuator does; it’s designed to decrease the amount of signal received by the radio. Normally, in amateur radio, you don’t want to do that; you want the strongest signal you can get. But, in the case of a fox hunt, it is designed to decrease the signal back down to a point where the difference between pointing the antenna at the fox and away from the fox can be heard again.

I decided to go with a kit attenuator from 3rd Planet Solar / KC9ON.

Fox Hunt Offset Attenuator
KC9ON Fox Hunt Offset Attenuator

This kind of attenuator will mix the incoming signal with a small signal generator in order to generate a signal 4 MHz above or below the fox’s signal. Then you can turn the knob to increase or decrease this new signal. So, for example, in our Fremont class, I chose a frequency of 147.54 MHz for the fox to transmit on and then added 4 MHz to it, for a final frequency of 151.54 MHz. This is the frequency that I tuned the radio to. The neat thing about this arrangement is that, because the radio is 4 MHz off of the target signal, if the attenuator is turned off, the radio won’t receive any signal.

You can buy the attenuator already assembled and soldered, but I chose the kit that just had all the parts and you have to solder it yourself. I wanted to put it in a specific enclosure and needed to extend the distance between certain parts like the light, the switch, and the knob.

Here’s what it looks like all assembled:

Step 2: “Tape measure” Yagi Antenna

Once that was done, the next step was to build a “tape measure” Yagi antenna.

Emma helped me build the antenna and we recorded the build; look for it in a future episode of Ham Radio with Emma! We used the plans created by NT1K.Here’s what it looks like all assembled:

Tape measure Yagi

Overall, the parts are pretty cheap to buy at a hardware store. The only special parts that are ham-radio-specific are the PL-259 connector at the end and the RG-58 coaxial cable. You will need to be able to solder wires, but you can get pretty cheap soldering irons. Harbor Freight has the cheapest irons I’ve found. No bells and whistles, but they will get the job done.

Step 3: Fox Transmitter

I knew a fellow ham that already had a fox transmitter, so I had hopes that we could simply borrow that for our meeting. Unfortunately, schedules did not align and it didn’t work out, so I had to get creative.

I initially thought I needed to buy a special transmitter, like the Byonics MicroFox, but they are all over $100 and even if I wanted to spend the money, there wasn’t enough time to get one shipped out in time for the class.

But then it dawned on me that it’s just a radio and I already have a couple of those.

I found this video on YouTube about simply hooking an MP3 player to a Baofeng radio with an audio cable.

I even had the right cable! So, I dug out a really old iPod we don’t use anymore, created an audio file with my callsign and message, and imported it into the iPod. The theory was that I could switch the Baofeng into “VOX” (voice activated) mode and then when the audio file played, it would transmit the audio. On the iPod, I could switch it into “repeat single” mode and it would just play the same audio file on repeat forever. I used Audacity to add 15 seconds of silence to the end of the audio file. The theory was that the VOX mode on the radio would detect silence and stop transmitting.

Except that theory didn’t work. The audio triggered the radio to transmit, but when it got to the silence part, it wouldn’t shut off. We can’t have that happening, so back to the drawing board.

I had the radio part figured out, I could just use a Baofeng. But the two things left to figure out was generating some sort of signal and triggering the Push-to-Talk (PTT) to get it to transmit. That second part is tricky.

The Baofeng has a connector that looks like this:

In order to trigger the PTT, you have to connect the sleeves of both pins. A lot of devices that can be programmed to do things, like computers or phones, don’t have any way of making this electrical connection; typically they just have USB ports as their way of connecting to other devices.

But… Arduinos and Raspberry Pis do! They have “general purpose I/O” (GPIO) pins that can basically turn a voltage on or off. I have devices of both families laying around, so I started searching the Net for designs. I decided to look for Arduino designs first because they are much simpler devices and don’t need a full-on operating system, like a Raspberry Pi does.

As luck would have it, I stumbled upon this design from NF7Z Nelson Farrier:

Auto-Keyer for Radio “Fox Hunting”

Fortunately, between my parts box and Emma’s parts box, I managed to find all of the necessary electronics parts, like capacitors, resistors, and the relay. The tricky part was finding the right cable to connect to the Baofeng. Like I mentioned before, I do have a BTECH APRS-K1 TRRS / APRS Cable, but I discovered that it only connects the mic and speakers, there is no way to trigger the PTT. The expectation, when using this cable is that you will just enable VOX on the Baofeng. After my earlier attempt, I wanted to avoid VOX.

I could have soldered up a new cable for this, but, since this was really intended to be a temporary solution, I didn’t want to use up some connectors. But I happened to have a cable that has a Baofeng-compatible end on it from Mobilinkd. I knew that the Mobilinkd TNC was able to trigger the PTT using this cable, so I just had to get the connections right.

I modified the Arduino code to put my callsign in. The code makes the Arduino generate a morse code audio sequence that beeps out “W8WJB FOX” and then follows with a short tone to help with getting a heading when swinging the Yagi around.

Just turn on the Baofeng radio, tune it to the desired frequency, and plug in the Arduino. It repeats the sequence over and over with a short pause in between until you power it off.

This was the result:
homemade fox transmitter

I secretly turned it on and hid it a half hour before the ham radio class. I’m happy to report that the kids managed to find it where it lay hidden in some brush!

I tried to hide it again, but we discovered that, in the excitement of the first find, it got jostled around pretty good. I think a wire probably came loose and it was no longer transmitting. There wasn’t time during the class for me to troubleshoot which wire, so we simply moved on with the lesson.

But, all in all, I would say that that, despite the last minute, rushed build, it worked for what we needed it to and everyone had fun!

Practice Test Recommendations

At our class in Fremont last night, I promised to provide some links to websites or apps that can help with doing practice tests.

Here is the iOS app that everyone in my family used:

HAM Test Prep: Technician

It costs $5. If you want to see what it’s like before you buy it, you can try the Lite version. Just be aware that the Lite version only contains 2 of the 10 subelements of the question pool.

HAM Test Prep Lite: Technician

You can also take practice tests on several websites. Here are the ones I’ve used and liked:

I really recommend creating an account on these sites when practicing the test because the site can keep track of your past test results and you can see the progress you’re making.


Week 2 Handout

As promised, here is the handout from yesterday’s class in Fremont. It looks much better in full color. Here’s what each page has:

Page 1: The “Schematic Scavenger Hunt”. We did the first three rows, from resistors to capacitors. We’ll learn about the rest next week.

Page 2: Technician test diagrams. These are the three figures that appear on the test. The questions are generally worded like “What is component 6 in figure T2?”. (Bonus points if you comment back and tell me the answer)

Page 3: Resistor color code reference + handy way to identify transistors. We didn’t talk about transistors yet; we’ll cover that next week.

Page 4: A nice collection of electronics symbols courtesy of Sparkfun.

Week 2 Electronics Handout

Electricity Reference Sheet

We had more people that I expected for yesterday evening’s session! That’s awesome! But it also meant I hadn’t printed out enough handouts ahead of time. Here’s the reference sheet as a PDF for anyone who wasn’t able to take one home.

There are a few things that we didn’t get a chance to cover, such a the PIE formula and decibels, but we’ll cover some of the things we missed next week.

Electricity Reference Sheet