AIS Boat Tracking using an RTL-SDR

Yagi antenna picking up AIS off of New Jersey. Laptop running OpenCPN for plotting the craft.

I was able to track boats off of the central Jersey coast by receiving the Automated Identification System (AIS) transponder signal. The signal is sent periodically and picked up by my VHF yagi antenna from as far as New York City about 60 miles away over open ocean.

The signal goes to an RTL-SDR running AiSDeco2 which demodulates the signal. AiSDeco2 also hosts a TCP server for OpenCPN navigational chart software to get the current locations and plot them on a map.

OpenCPN can be loaded with charts from NOAA to give you a more detailed map about the area you are working in. The craft locations are overlaid on the charts.

Crafts send the signal on two frequencies: 161.975 MHz and 162.025 MHz. AiSDeco2 with an RTL-SDR can handle both at the same time. If you watch the signal on a spectrogram waterfall chart, you will see an pretty easily noticed signature to help you aim the antenna.

In addition to crafts, you will also find that some navigational aids like buoys also transmit AIS.

Amateur weather station with Twitter bot

Weather station

We invested in a personal/amateur weather station. This is a result of my kid’s increasing interest in weather and wanting to push data to sites like Weather Underground. We decided to purchase the Ambient Weather WS-2902B WiFi Smart Weather Station which has several sensors including wind direction, wind speed, rainfall, solar radiation, and humidity. It communicates over 900MHz to the base station which can connect to WiFi and push data to other sites.

Configuration was quick and easy. We are now pushing data to:

For some additional fun, I decided to create a Twitter bot that runs on Amazon Web Services Lambda. It periodically queries the Ambient Weather API to fetch my weather station’s data. It then tweets the data on @WanamassaW.

Some useful Python libraries for creating the Twitter bot:

  • Tweepy – lets you interact directly with the Twitter API
  • Ambient API – lets you query the current weather data through Ambient Weather

Here’s a quick prototype of using the libraries:

import tweepy
import datetime
from ambient_api.ambientapi import AmbientAPI
import time

consumer_key = '***'
consumer_secret = '***'

access_token = '***
access_token_secret = '***'

api = 0
ambient_api = 0
data = 0

def degToCompass(num):
    arr=["N","NNE","NE","ENE","E","ESE", "SE", "SSE","S","SSW","SW","WSW","W","WNW","NW","NNW"]
    return(arr[(val % 16)])

def get_current():
    current = "Current weather:\n"
    current += 'Temperature: ' + str(data['tempf']) + 'F\n'
    current += 'Feels like : ' + str(data['feelsLike']) + 'F\n'
    current += 'Humdity: ' + str(data['humidity']) + '\n'
    current += 'Wind direction: ' + degToCompass(data['winddir']) + '\n'
    current += 'Wind speed: ' + str(data['windspeedmph']) + ' MPH\n'

    return current

def publictweet():
    if == 0:
        tweettopublish = 'Hi everyone, today is Monday.   #Monday '
    if == 1:
        tweettopublish = 'Enjoy your Tuesday.  #Tuesday'
    if == 2:
        tweettopublish = 'Third week of the Week. #Wednesday'
    if == 3:
        tweettopublish = 'Thursday. I cannot wait for the Weekend'
    if == 4:
        tweettopublish = 'Friday...Finally'
    if == 5:
        tweettopublish = 'Great it is Saturday #weekend #Saturday'
    if == 6:
        tweettopublish = 'Sunday...#Weekend #enjoy '
    tweettopublish += '\n' + get_current()

def lambda_handler(event, context):
    auth = tweepy.OAuthHandler(consumer_key, consumer_secret)
    auth.set_access_token(access_token, access_token_secret)
    global api
    api = tweepy.API(auth)
    global ambient_api
    ambient_api = AmbientAPI()
    devices = ambient_api.get_devices()
    device = devices[0]
    global data
    data = device.get_data()[0]
    return {

Capturing NOAA Automatic Picture Transmissions

I was able to successfully download and decode the NOAA weather imagery from the NOAA-18 satellite. The Automatic Picture Transmissions (APT) has a downlink frequency of 137.9125 MHz.

Yagi antenna

What do you need?

VHF Yagi antenna – I used a hand held VHF/UHF yagi from Arrow Antennas that can cover most satellite frequencies and can also be used for talking over amateur radio satellites. I’ve read about people also using rabbit ear antennas as long as they are measured to the right length and angle. You may also be able to just use a discone antenna in the attic or on the roof.

SDR– The cheap and portable RTL-SDR that you can pick up for $20 bucks on amazon. It has an SMA female adapter that can use the male SMA coming off of the yagi.

Heavens Above

Satellite tracking software – There is the popular Gpredict that you and mobile Heaven’s Above app that will let you know when the satellite will be over head. You probably want it to be high off the horizon when it passes to avoid interference form buildings and trees.

Recording software – I recorded the signal with GQRX on Linux, but you can also use SDR#. The guide on the NOAA-APT software site has a good description of the specific configuration required. Most importantly, the signal is narrow so you may want to zoom in on the FFTs to get a better look. Also try to reduce the receive bandwidth to the size of the signal. GQRX and SDR# let you record a wav file of the transmission that you will use for decoding.

GQRX with configuration

Decoding software – I used NOAA-APT to decode the wav recording. It doesn’t have as many features as wxtoimg (like color images), but it is open source and user friendly. NOAA-APT will take GQRX recording and convert it into an image. You may see some artifacts like noise or missing sections depending on the quality of the recording.

NOAA-18 visible (left) and thermal (right) imagery