Decoding AIS Signals for Marine Monitoring

Automatic Identification System is a system for boats to broadcast their location. This is very helpful in congested waters, such as in the San Francisco Bay, where many ferries, huge container ships, and small pleasure craft are trying to avoid each other. Onboard digital chart plotters can show nearby ships, their heading, speed, and expected position a few minutes from now. Early AIS transmitters were very expensive, but the new generation of Class B transmitters are actually pretty inexpensive.

AIS operates on two frequencies, Marine VHF channels 87B and 88B. These are the high-side duplex frequencies of channel 87 and 88, and they are 161.975 and 162.025 MHz. The data link layer is 9600 baud GMSK, packet length of 256 bytes, which works out to 26.6 millisecond packet time including some guard time. Each AIS "frame" is 1 minute long, so within each frame there can be 2250 time slots (per frequency). With two channels available, a lot of positions can be transmitted every minute.

The boats use a self-organizing time division multiple access (SOTDMA) scheme, which allows boats to transmit their position, speed, next transmission time, and some other identifying data every six to 60 seconds, depending on boat speed. Interestingly enough, the protocol doesn't include a full timestamp, only the timeslot within a frame, so playing back AIS packets in delayed time is not possible, unless you externally record the received packet time.

Radio Connection

I have an older Kenwood TM-G707A amateur radio that I use for APRS balloon chasing. 9600 baud signals are wider than the audio passband of standard FM radios (such as Marine VHF or scanners), so you need to tap the descriminator of the radio to get a clean signal. The data connector on the back of the radio is as follows:

Pinout of 6-pin Mini-DIN connector

Pin 4 looks exactly like what I'm looking for. It must be discriminator tapped, as they specify 9600 baud audio. Perfect, just solder this up to my laptop?

But we have a problem. This "audio" signal is going into my computer for decoding, but the diagram specifies 500 mVP-P at 10 kOhms. I'm using a cheap USB soundcard microphone input, and the standard microphone input levels is around 5 mVP-P at 2.2 kOhms. Ignoring the impedance difference for a moment, the radio output is way too loud for the USB soundcard, so the waveform will be mangled beyond belief, even if I don't fry the circuitry on the first packet.

To drop the 500 mVp-p down to 5 mVp-p, I need a simple 100:1 voltage divider. Matching the 10 kOhm radio output impedance for max power transfer (and no reflections), math says that the other resistor should be 100 ohms.

Voltage divider schematic

Because I don't seem to have any 10k or 100 ohm resistors around (what kind of electrical engineer am I?), I had to get creative and parallel up some 24 kOhm and 220 ohm resistors, for a total of 12 kOhm and 110 Ohm. Close enough! I used some 0.100" headers to help while soldering and to keep the leads from shorting each other.

Voltage divider schematic


So now that I have audio getting in to my computer, how do I decode the packets? Because this was a quick and dirty test, I decided to use the free AISMon software decoder from It takes a soundcard input, decodes the packets, and sends the data back to their servers where it gets posted on the web. They make their money by reselling AIS data to ship operators, ports, and maritime services companies.

Their software requires Windows to run. I haven't had an actual windows computer in many many years, but I do have some old Windows 7 virtual machines. Installation was painless, and in short order I was decoding AIS packets. As it turns out, if you are located near the ocean, there are a lot of AIS packets being transmitted!

AISMon decoding screenshot

Their software decodes packets and uploads the data to their servers, but it doesn't show you a pretty map of nearby boats. I guess this makes sense, wants you to visit their webpage and/or give them money to get boat positions. The webpage for your station does helpfully show a bunch of statistics about your station, including coverage area.

Range of my AIS decoding station.

The website also shows a time graph of packet receptions per minute of your station. Keep in mind that this is a log chart, with packets per minute, so my station is decoding anywhere from about 40 to 100 packets per minute, or about 1 AIS packet per second.

Packets decoded per minute, and polar charts of where the packets are coming from.

AISMon can output data to a COM port, so initially I was looking at a plotting program that could stream data from that. But due to the ancient way that COM/serial ports operate, I would have needed a software null-modem cable that took the output from AISMon and piped it into one of these plotting programs, and that seemed like a lot of work to set up.

Since I was running AISMon in a virtual machine, could I somehow use a virtual COM port? Poking around VirtualBox, there was an option for this, and after a few minutes of searching the internet, got it working.

VirtualBox configuration settings for a COM port to socket

So VirtualBox connects to the AISMon COM port, and spits the data out in a TCP stream on the host. My host is running Ubuntu, and there are several open-source plotting programs that accept a TCP stream of AIS packets. I settled on OpenCPN, and after installing it from the Ubuntu repositories, configured it to accept a TCP stream from localhost.

OpenCPN configuration for streaming data from a VirtualBox COM port TCP stream.

OpenCPN has a great built-in map downloading tool, and in very short order I had downloaded all the local maps for my area, and the ships were being plotted on the map. It was pretty cool to see all the ships anchored nearby, and the ferries crisscrossing the bay.

Screenshot of OpenCPN

Future Work

This setup for me is not too sustainable. I have my (only) external dual-band antenna dedicated to this, and receiving these signals take an entire hardware radio. And because it's using a Windows VM on my personal laptop, my laptop needs to live by the radio and antenna feed, which is not by my desk.

Some ideas for future exploring:

  • Use a RTL SDR dongle for the RF side.
  • GNU Radio has a gr-ais module for AIS reception.
  • dAISy HAT is a full 2-channel "Hardware Attached on Top" module for the RaspberryPi. Outputs standard serial.
  • Another soundcard program to demodulate the packets.