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). On this page I document the process of setting up a satellite dish to record the output of one of these satellites and process the images.
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. It is also possible to receive and decode the output from these satellites. I've gotten acceptable images using a $30 SDR and a 2m dipole antenna. Since these 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. But for real-time forecasting, the GOES satellites have a strong advantage. They maintain their position over the earth so they can consistently monitor a portion of the globe. Because they don't move, 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:
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:
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.
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 https://github.com/pietern/goestools.git
git submodule init
git submodule update --recursive
cmake -DCMAKE_INSTALL_PREFIX:PATH=/usr ..
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:
#if PROJ_VERSION_MAJOR != 4
#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 pietern!) that more updated 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.
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 groundcontrol.com 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 when the dish is aligned. 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.
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://127.0.0.1:5004
If you want to run this from another machine on your network you could replace 127.0.0.1 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:
Here are a few notes and tips which didn't fit into the main post but I think may be useful:
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.
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: https://wx-star.com/post/169608535305/designing-false-colors-for-goes-r-hrit
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.
- 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