Background and Introduction

Since 1975, NOAA has maintained multiple geostationary satellites to aid in weather forecasting and research. These are called GOES satellites (Geostationary Operational Environmental Satellite). The first GOES satellite in 1975 was initially called GOES-A during launch and then renamed to GOES-1 upon reaching in final location in the sky. The most recent satellite is GOES-17, which was launched in March 2018 as GOES-S and recently reached its final operating point above the Pacific Ocean. There are two other GOES satellites in orbit GOES-15 (replaced by GOES-17) and GOES-16 (Atlantic coverage).

There is a great overview of GOES-16 and 17 here. Here is a map of the coverage:

NOAA also has a number of weather satellites in a polar orbit. These include NOAA 15, 18, and 19. These are at a lower elevation and are much easier to receive – I've gotten acceptable images using a $30 SDR and a 2m dipole antenna. Since those satellites are in a polar orbit they are only "visible" when they are passing overhead. It is typical to get a few passes a day of 5-15 usable minutes. Its really fun to record these and I hope to post a separate article about it soon.

Polar satellites are able to make some measurements more accurately due to their lower elevation (ocean surface temperature, for example). They also cover the entire earth since the planet is rotating beneath them. For real-time forecasting, the GOES satellites have a strong advantage. Since they orbit at the same speed as the earth is spinning, Geostationary satellites maintain their position relative to earth. This means a parabolic dish can be pointed at the satellite and receive continuous downloads 24/7/365. According to the GOES-17 schedule a full disk image of the earth is typically available every 10 minutes and some isolated regions are updated more frequently. Here is an example of one of the full disk images I received:

The continental US is in the upper-right corner of the globe from this angle. The images are 5424 × 5424 pixels. In digital camera terms that would be equivalent to a 29MP camera.

Here is a cropped photo from the area around Baja:

And, here is an animation of 48 consecutive full disk images (there is a full resolution video of this at the end of the article):

Hardware for Receiving GOES Satellites

The is the hardware I am using for receiving:

From my location, this gets me an verterbi error rate of 400-500 (explained more later). This is acceptable, but a lower rate would produce cleaner images.

The setup consists of:

  • Airspy Mini (link)
  • Parabolic Dish Antenna (I am using this one, with 19dBi gain)
  • Bandpass Filter + LNA (I am using this one)
  • N-female to SMA female adapter.
  • (2) SMA male to SMA male cables
  • Tripod with Mount OR sturdy pole with a diameter <= 50mm to mount the antenna.

The antenna is shipped with a bracket which allows it to be mounted to a pole and adjusted in azimuth and elevation. This worked fine, but it was a little difficult to adjust, and I want my setup to be portable. I 3D printed a mounting bracket so that I can attach the antenna to the tripod:

Mounting bracket attached to tripod without antenna. 
Antenna mounted on Tripod with with coax connected

If you happen to have a Manfrotto tripod with a hexagonal camera plate and want to print your own mount I uploaded the design to Thingiverse. The M6 bolts included with the Antenna mounting kit work for mounting to the plastic adapter.

Software Setup:

I am starting with a new installation of Ubuntu version 19.04 on my laptop. Since I am working from a fresh OS install, I hope most of the steps I'm listing are applicable for anyone trying to follow along.

I am using goestools available here on Github for the receiving and decoding of images. Some of the commands I'm listing come from this excellent guide about setting up goestools on a Raspberry Pi with an rtl-sdr v3 dongle , but some of the dependancies and install steps are different because I am using Ubuntu and and Airspy.

First, install some dependencies:

sudo apt-get install git build-essential cmake libusb-1.0 libopencv-dev libproj-dev proj-bin airspy

After running that, you should be able to plug your airspy or airspy mini into the PC and type airspy-info to inquire about your Airspy device:

Next, clone and install goestools:

git clone
cd goestools
git submodule init
git submodule update --recursive
mkdir build
cd build
sudo make -j2 install

On the last step, you may see an error complaining about the wrong version of "proj" being installed. Ubuntu 19 is currently shipping with proj5 and the goesproc checks for proj4. I tried installing proj4 from source and the issue remained. I was eventually able to compile and install by editing 'proj.h' in /goestools/src/goesproc/proj.h. Replace the '4's in the following section with '5' and you should be able to finish installing:

#pragma once

#error "proj version 4 required"

This issue was raised on Github since I compiled and seems to have been addressed, so you may not encounter this at all.

I used some configuration scripts in goestoools/etc/ as a starting point for my configuration files. After posting this article, I heard from the auther of the goestools (thanks !) that more udpated and runable scripts are generated during 'make install' and that you can find them in '<PREFIX>/goestools/share'. Those scripts enable some additional features, also, so I recommend starting from those.

Antenna Alignment

The parabolic dish is high gain with a narrow beam so alignment is important! A few degrees of misalignment will cause a signficant decrease in signal level. I found I was able to set the direction of the antenna approximately using the compass and tilt sensor on my iPhone, then fine-tune the output by looking at the error rate output of goesrecv.

I used to help find the satellite location in the sky. At the time of this writing, GOES-17 is still listed as GOES-S. I expect that will change soon. The output looks like this:

The elevation and azimuth values above are valid for my location – they will be different for yours. If you are using a compass (either real or on your phone) set the Azimuth direction using the "Magn." Azimuth value.

Once you have the antenna generally aligned, type the following into the terminal:

goesrecv --config-file=./goesrecv_airspy.conf -v -i1

After hitting enter, you will see a scrolling display which updates every second:

Among other things, this shows the viterbi error rate (labeled: vit(avg)) each second. This is an indirect measure of the quality of the signal being received by the antenna and it is very useful to help with antenna alignment.  If the antenna is completely misaligned it will read above 2000. For me, it hovers around 400. Others regularly hit 150 or lower.

400 isn't great, but its good enough that I am having no dropped packets or issues with decoding.  I started to see real issues with the dropped packets above 600 or so. I experimented quite a bit with positioning and 400 seems to be the floor I could achieve with this setup from my location. I will try more soon.

While you are aligning the antenna, you may also want to open a program like gqrx which can display a realtime spectrum. It is useful to get fast feedback about the signal level while you are aligning the dish and also interesting to see the character of the signal over time (it is hundreds of kHz wide!):

Processing the Images

Once you are receiving the signal from the satellite with a steady error rate that is less than 500, you can try to process some of the images. Leave goesrecv running – it will continue to run in the background.

Setup your config file for the appropriate satellite (GOES-17 is what I am using) and SDR device. You can find example scripts at '<PREFIX>/goestools/share' and they are commented and easy to adjust.

Then start goesproc with the command:

goesproc -c goesproc_airspy.conf -m packet --subscribe tcp://

If you want to run this from another machine on your network you could replace with the IP address of the machine running goesrecv.

After running this command, you should start to see packets being decoded and images appearing in local directories. This is what the output of goesproc looks like:

Images and Video

Here are a few of the images and videos I've collected from GOES-17:

Midnight from Space 

Extra Notes:

Here are a few notes and tips which didn't fit into the main post but I think may be useful:

Temperature control

On the first day I setup the antenna the temperature outside was about 65F. It felt cool outside, but the Airspy Mini was in direct sunlight. About two hours after I started recording I noticed the error rate rise up to approx 2200. Stopping and starting goesrecv would result in temporary rates around 400, but the errors would suddenly return to 2200 after a few tens of seconds. This ended up being a temperature issue – the airspy mini was hot to the touch.  I was able to resolve it by attaching a small heatsink and a small fan to blow across it. I had no further issues after this.

As a next step, I plan to set this up on a Raspberry Pi as a permanent installation. I will likely remove the Airspy from the housing its in and attach a better heatsink in order to make it through the summer months.

The fan is powered directly from USB – it doesn't take much airflow. 

Color Images

Color images are generated by comparing different parts of the visual/infrared spectrum against a lookup table. There is a great writeup about it here:

The .pgm LUT file is available from on Github from the author of the article above. The two other LUT's are in goestools/share.

Next Steps:

  • Try to reduce the error rate without increasing the size of the antenna (better alignment, fine-tuning gain, etc)
  • Setup on a Raspberry Pi
  • Let run for an extended period to create an extended video