Raspberry Pi NOAA Weather Satellite Receiver


Introduction: Raspberry Pi NOAA Weather Satellite Receiver

About: I'm a ham, a tinker, a maker. I like interesting things. I'm a technophile, a wood turner, and a pen maker.

A new pile of parts means a new project is in the works.

I’m building a Raspberry Pi based NOAA weather satellite receiver. I’ve got some experience with receiving signals from NOAA satellites, but will be a little different, as all of the work is going to be done automatically on a Raspberry Pi. This will allow me to place the receiver right at the antenna, which is mounted in my attic. With a very short piece of coax, reducing feed-line loss.

I’ll be using the following list of parts:

  • Raspberry Pi 3 Model B
  • MicroUSB Power Supply
  • Generic Raspberry Pi 3 Case
  • 32 GB Micro SD Card
  • NooElec SDR Dongle
  • QFH Antenna

This project will require some basic Linux skills. If you are not comfortable navigating around the Linux command line, you may need to get some help if you want to follow along.

This instructable is going to focus on getting the Raspberry Pi working to receive images. Details around building a proper antenna can be found from other sources. I even made a video about it: https://youtu.be/KU75FSA6o2M

Step 1: Prepare the Raspberry Pi

The first step is getting the Raspberry Pi up and running. I’m using Raspbian (Jessie 2016-11-25).

There are plenty of tutorials on getting Raspbian set up and booting on the Raspberry Pi. You should have no difficulty in finding one: https://www.raspberrypi.org/documentation/installation/installing-images/README.md

Once you have the Raspbian image copied to your micro SD card, boot the Raspberry Pi. You'll need to get it on the network and enable SSH. You can certainly use either a wired Ethernet connection, or wireless. I'm using wireless, as I don't have a wired connection in my attic.

Enable SSH using the Raspberry Pi Configuration utility in the Preferences menu. You may want to set it to boot to CLI while you are in there. Since this is going to be a headless setup, there is no need to waste resources on a GUI.

Next we want to make sure the Raspberry Pi is fully up-to-date. Issue the following commands:

sudo apt-get update
sudo apt-get upgrade
sudo reboot

Step 2: Install the Necessary Software

The first thing we need is the USB drivers for the RTL dongle:

sudo apt-get install libusb-1.0

Since we need to build the latest version of rtl-sdr to actually make use of the RTL dongle, we'll need to install cmake:

sudo apt-get install cmake

We need to make sure the Raspberry Pi doesn't load any SDR kernel modules that will interfere with the rtl-sdr sofware.

Using your favorite text editor, create a new file named /etc/modprobe.d/no-rtl.conf and put the following text in the file. You need to run that text editor as sudo (i.e. 'sudo vi' or 'sudo nano' etc) to write to the modprobe.d directory:

blacklist dvb_usb_rtl28xxu
blacklist rtl2832
blacklist rtl2830

Install the most recent build of rtl-sdr:

cd ~
git clone https://github.com/keenerd/rtl-sdr.git
cd rtl-sdr/
mkdir build
cd build
sudo make install
sudo ldconfig
cd ~
sudo cp ./rtl-sdr/rtl-sdr.rules /etc/udev/rules.d/
sudo reboot

We'll need the sox audio toolkit in order to manipulate the received audio stream:

sudo apt-get install sox

We need a way to schedule the captures to happen as the satellites pass overhead. Install the at scheduler:

sudo apt-get install at

We need a way to know when the satellites will pass overhead. We'll use an application called predict:

sudo apt-get install predict

Finally, we'll need wxtoimg to convert the captured audio stream to an actual image:

cd ~
wget http://www.wxtoimg.com/beta/wxtoimg-armhf-2.11.2-beta.deb
sudo dpkg -i wxtoimg-armhf-2.11.2-beta.deb

Step 3: Testing Things Out

Once all the software is installed, make sure your USB dongle is connected and run the following command:

sudo rtl_test

You should see the following output:

Found 1 device(s):
  0:  Realtek, RTL2838UHIDIR, SN: 00000001

Using device 0: Generic RTL2832U OEM
Found Rafael Micro R820T tuner
Supported gain values (29): 0.0 0.9 1.4 2.7 3.7 7.7 8.7 12.5 14.4 15.7 16.6 19.7 20.7 22.9 25.4 28.0 29.7 32.8 33.8 36.4 37.2 38.6 40.2 42.1 43.4 43.9 44.5 48.0 49.6 
Sampling at 2048000 S/s.

Info: This tool will continuously read from the device, and report if
samples get lost. If you observe no further output, everything is fine.

Reading samples in async mode...

If you receive any error messages, you'll need to troubleshoot them before continuing. If your RTL Dongle isn't working at this point, it won't do any good to continue.

You need to run predict one time to set your ground station location. To do that you'll need your latitude and longitude. You can get your latitude and longitude from google maps by searching for your address, the right clicking on the pointer and selecting "What's Here". One thing to note is that Google displays North as positive and East as positive numbers. Predict uses North as positive but WEST as positive. Make sure to adjust accordingly, or your predictions will be no good.

Run predict from the command line, and select option 'G'. Enter your ground station information and exit the program.:

                           --== PREDICT  v2.2.3 ==--         
                     Released by John A. Magliacane, KD2BD   
                                    May 2006                 

                            --==[ Main Menu ]==--

 [P]: Predict Satellite Passes          [I]: Program Information
 [V]: Predict Visible Passes            [G]: Edit Ground Station Information
 [S]: Solar Illumination Predictions    [D]: Display Satellite Orbital Data
 [L]: Lunar Predictions                 [U]: Update Sat Elements From File
 [O]: Solar Predictions                 [E]: Manually Edit Orbital Elements
 [T]: Single Satellite Tracking Mode    [B]: Edit Transponder Database
 [M]: Multi-Satellite Tracking Mode     [Q]: Exit PREDICT

                 *  Ground Station Location Editing Utility  *

                        Station Callsign  : W1AW
                        Station Latitude  : 41.7169 [DegN]
                        Station Longitude : 72.7271 [DegW]
                        Station Altitude  : 25 [m]

            Enter the callsign or identifier of your ground station

You need to run wxtoimg once to accept the terms and conditions.


You need to tell wxtoimg where your base station is at, so it can properly generate an overlay map. You do so by creating a file in your home directory named ~/.wxtoimgrc. In this file, North is positive, as with predict, however EAST is positive, which is the opposite of what predict uses. Make sure to adjust your values appropriately.

Using your favorite text editor, create a new file named ~/.wxtoimgrc and put the following text in the file, substituting your values:

Latitude: 41.7169
Longitude: -72.7271
Altitude: 25

Step 4: The Scripts

Now that you've got a working RTL dongle on your Raspberry Pi, it's time to actually make it receive some weather maps. Make sure your antenna is connected and located as best as possible. I've got mine mounted in my attic and it works fairly well from there. If you can mount it outside, that would be even better. Get it as high as possible.

We are going to need to create a few scripts to automate everything. This is where that Linux familiarity is going to come in.

First we'll create a couple directories to hold our files:

cd ~
mkdir weather
cd weather
mkdir predict
cd predict

Next we'll make the two scripts that kick off the scheduling. The first is 'schedule_all.sh'. This script will be called nightly at midnight. It downloads satellite pass information from celestrak and creates a TLE file for predict to use. Then it removes all AT jobs from the system, so no passes get double scheduled. Finally, it calls the second script 'schedule_satellite.sh' for each satellite we are interested in.

Using your favorite text editor, create a new file in ~/weather/predict named schedule_all.sh and put the following code in the file:


# Update Satellite Information

wget -qr https://www.celestrak.com/NORAD/elements/weather.txt -O /home/pi/weather/predict/weather.txt
grep "NOAA 15" /home/pi/weather/predict/weather.txt -A 2 > /home/pi/weather/predict/weather.tle
grep "NOAA 18" /home/pi/weather/predict/weather.txt -A 2 >> /home/pi/weather/predict/weather.tle
grep "NOAA 19" /home/pi/weather/predict/weather.txt -A 2 >> /home/pi/weather/predict/weather.tle
grep "METEOR-M 2" /home/pi/weather/predict/weather.txt -A 2 >> /home/pi/weather/predict/weather.tle

#Remove all AT jobs

for i in `atq | awk '{print $1}'`;do atrm $i;done

#Schedule Satellite Passes:

/home/pi/weather/predict/schedule_satellite.sh "NOAA 19" 137.1000
/home/pi/weather/predict/schedule_satellite.sh "NOAA 18" 137.9125
/home/pi/weather/predict/schedule_satellite.sh "NOAA 15" 137.6200

The second script, 'schedule_satellite.sh', recurses through each pass of the given satellite for the current day. It determines if the maximum elevation is 20 degrees or greater. If it is, then it calculates the length of the pass, and schedules the recording and processing of the pass. If the maximum elevation is less than 20 degrees, the pass is ignored, as it generally won't produce a decent image.

Using your favorite text editor, create a new file in ~/weather/predict named schedule_satellite.sh and put the following code in the file:

PREDICTION_START=`/usr/bin/predict -t /home/pi/weather/predict/weather.tle -p "${1}" | head -1`
PREDICTION_END=`/usr/bin/predict -t /home/pi/weather/predict/weather.tle -p "${1}" | tail -1`

var2=`echo $PREDICTION_END | cut -d " " -f 1`

MAXELEV=`/usr/bin/predict -t /home/pi/weather/predict/weather.tle -p "${1}" | awk -v max=0 '{if($5>max){max=$5}}END{print max}'`

while [ `date --date="TZ=\"UTC\" @${var2}" +%D` == `date +%D` ]; do

START_TIME=`echo $PREDICTION_START | cut -d " " -f 3-4`
var1=`echo $PREDICTION_START | cut -d " " -f 1`

var3=`echo $START_TIME | cut -d " " -f 2 | cut -d ":" -f 3`

TIMER=`expr $var2 - $var1 + $var3`

OUTDATE=`date --date="TZ=\"UTC\" $START_TIME" +%Y%m%d-%H%M%S`

if [ $MAXELEV -gt 19 ]
    echo ${1//" "}${OUTDATE} $MAXELEV

    echo "/home/pi/weather/predict/receive_and_process_satellite.sh \"${1}\" $2 /home/pi/weather/${1//" "}${OUTDATE} /home/pi/weather/predict/weather.tle $var1 $TIMER" | at `date --date="TZ=\"UTC\" $START_TIME" +"%H:%M %D"`


nextpredict=`expr $var2 + 60`

PREDICTION_START=`/usr/bin/predict -t /home/pi/weather/predict/weather.tle -p "${1}" $nextpredict | head -1`
PREDICTION_END=`/usr/bin/predict -t /home/pi/weather/predict/weather.tle -p "${1}"  $nextpredict | tail -1`

MAXELEV=`/usr/bin/predict -t /home/pi/weather/predict/weather.tle -p "${1}" $nextpredict | awk -v max=0 '{if($5>max){max=$5}}END{print max}'`

var2=`echo $PREDICTION_END | cut -d " " -f 1`


When the time comes for a give pass to be recorded and processed, at kicks off the final script 'receive_and_process_satellite.sh'. When this script is called, it uses rtl_fm to receive the audio from the satellite pass, and sends that audio to sox for processing. Sox saves the audio to a file. Once the pass is complete, wxmap is called to generate an overlay map for the image. Finally, wxtoimg is called to generate the actual image and place the overlay map on it.

Using your favorite text editor, create a new file in ~/weather/predict named receive_and_process_satellite.sh and put the following code in the file:


# $1 = Satellite Name
# $2 = Frequency
# $3 = FileName base
# $4 = TLE File
# $5 = EPOC start time
# $6 = Time to capture

sudo timeout $6 rtl_fm -f ${2}M -s 60k -g 45 -p 55 -E wav -E deemp -F 9 - | sox -t wav - $3.wav rate 11025

PassStart=`expr $5 + 90`

if [ -e $3.wav ]
    /usr/local/bin/wxmap -T "${1}" -H $4 -p 0 -l 0 -o $PassStart ${3}-map.png

    /usr/local/bin/wxtoimg -m ${3}-map.png -e ZA $3.wav $3.png

Once all three scripts have been created, we need to make the executable, by issuing the following commands:

chmod +x schedule_all.sh
chmod +x schedule_satellite.sh
chmod +x receive_and_process_satellite.sh

Now, the last step in automating the reception is to schedule the first script to run just after midnight. Run the following command:

crontab -e

It will open a text editor of your choice to edit the cron file. Simply add the following line to the bottom of this file and save:

1 0 * * * /home/pi/weather/predict/schedule_all.sh

Now, at 00:01 the schedule will start. (if you don't want to wait, simply run the following command once to kick the process off:)


Step 5: Check Things Out

To see upcoming satellite passes that are scheduled to be processed, run the following command:


Check the ~/weather directory for your results. Each pass will generate three files:

NOAA1820170105-181147-map.png  <-- Map overlay file
NOAA1820170105-181147.png      <-- The final image file
NOAA1820170105-181147.wav      <-- The raw audio file

The format of the file name is the satellite name, followed by the date (YYYYMMDD) and time (HHMMSS) of the start of the pass. There are several filters that wxtoimg can use when generating the image file. I've had different luck with different satellites and passes on each filter. Feel free to play around with wxtoimg on the original map and audio files and see what you come up with.

One thing to note, the receiver can only receive one satellite at a time. If two satellites are passing overhead at the same time, the first one to start recording will "win" and be recorded. The second recording will error out and stop.

Step 6: Some of My Results

24 People Made This Project!


  • Make it Move Contest

    Make it Move Contest
  • Oil Contest

    Oil Contest
  • Woodworking Contest

    Woodworking Contest

We have a be nice policy.
Please be positive and constructive.


18 Questions

This is my 2nd time here. I now have everything debugged, and I find two of the three expected files in the weather directory (the ones that end in ".wav" and ".png") but there is no file that ends in "-map.png". What can I do to include that file in my weather directory?

Also, I get the files for NOAA15 and NOAA18, but nothing for NOAA19.

Also when I view the ".png" files, they are just sort of gray rectangles with no resolution. I have adjusted my antenna and hope that maybe that will improve the resolution problem.

I am having some difficulty getting this working, as well. I just discovered one thing that caused me to get no -map file. I had a space in the filename because of how it is shown in the listing above. This causes the arguments to misalign! There should be 6 arguments to the receive and process script. You must examine the scripts very carefully. Notice that there is no space in the line below in between the variable for the satellite name and the date -

echo "/home/pi/weather/predict/receive_and_process_satellite.sh \"${1}\" $2 /home/pi/weather/${1//" "}${OUTDATE} /home/pi/weather/predict/weather.tle $var1 $TIMER" | at `date --date="TZ=\"UTC\" $START_TIME" +"%H:%M %D"`

The scripts send an email, too. it is located at /var/mail/pi and you can read it from the command line using cat /var/mail/pi | less

Using headless Linux is very...onerous, but I am working the problem, same as you. Good luck.

5 more answers

First, Thanks so much for getting in touch!

I have no experience with bash, and it is not clear to me what I should do. You point out that there is no space between the variable name and the date. But it is not clear to me whether there SHOULD be a space, or if I should REMOVE a space. My problem is that I don't know where the variable for the satellite name ends and the date begins. I had decided that the project was too difficult for me, but your note has me back at it.

No problem, I am struggling to get my station up, too. Bash is new to me -- but, it is a lot like DOS batch files, so -- I looked at my symptoms, studied the programs and Linux a little and got it working. I started by examining the receive_and_process_satellite.sh script. At the top -- there are 6 lines of comments (Comments start with #) that tell you the six incoming variables needed to perform the receive and processing task. That task is created in schedule_satellite.sh and the six variables are created in this line:

echo "/home/pi/weather/predict/receive_and_process_satellite.sh \"${1}\" $2 /home/pi/weather/${1//" "}${OUTDATE} /home/pi/weather/predict/weather.tle $var1 $TIMER" | at `date --date="TZ=\"UTC\" $START_TIME" +"%H:%M %D"`

Unfortunately, if you did not cut and paste that line -- you might have embedded spaces in it accidentally -- that is what I did.

The entire process starts with schedule_all.sh -- that downloads current satellite data and uses grep to extract the data it needs and then creates the weather.tle file.

The last three lines of schedule_all.sh call schedule_satellite.sh for the three that are active and it passes two variables into that script -- the satellite name and its downlink frequency. schedule_satellite.sh determines if the pass will meet the minimum elevation requirements and if it does, it sets up a scheduled task to run receive_and_process_satellite.sh -- passing six variables into that script by way of the task.

Let me break it down as I understand it, hopefully that will help. Note that there is a space between each of the six variables, but -- no spaces in the variables themselves.

First -- the six variables in that line are:

1. "\${1}\" = The satellite name from the schedule_all.sh script ("NOAA15", "NOAA18" or "NOAA19") The quotes are removed in this line and all other instances of $1 -- That is the first "argument" passed into this script.

2. $2 = The satellite's frequency -- also from the schedule_all.sh script. (The second argument passed in.)

3. /home/pi/weather/${1//" "}${OUTDATE} -- This is where my mistake was. This is the filename base used to name the wav file, and the two image files. The first part is the PATH -- /home/pi/weather/. The next part extracts the satellite name from the first argument -- ${1//" "}. The last part adds the date and time -- ${OUTDATE}

When it is working, your filenames will look something like this :


-- If they are just the satellite name -- NOAA19.wav, for example -- you probably have a space between }$ -- like this } $ -- that won't work and was difficult to detect for me. This also ruins the rest of the task because the arguments are misaligned, now.

4. /home/pi/weather/predict/weather.tle -- the TLE file to use.

5. $var1 -- Calculated satellite pass start time -- called PREDICTION_START -- calculated by predict above.

6. $TIMER -- Calculated above as the length of the pass.

The stuff after the pipe symbol | is creating the scheduled task. Notice that your Raspberry Pi should be set to UTC, or GMT -- not localtime.

Another helpful thing -- the .wav files should be around 19 or 20MB and the -map file comes from your Internet connection and not the satellite pass. Even if you receive no good data -- you should get a very pretty map file, just no weather and no land or water. The PNG files are about 1MB each.

I am still trying to get an antenna and outdoor setup -- I am in a bit of a RF "hole" and my SDR can only do broadcast FM and some voice from inside.

Hello, Michael!

Thanks very much for your generous willingness to help me. But it appears that my code for that line already had all the spaces in the right places. However, I had my Raspi set to local time. I set it to UTC and eagerly awaited the next pass to see if I got a picture or a sound file. I was disappointed to find neither; the .png file was still a gray blur, and the .wav file just static. And I still do not receive a -map file at all.

Questions: Might I be opening the .png file too early? That is, might the .png file appear in the weather directory before the entire file is received? Is there a typical length of pass? Can you suggest a reason why I don't find the -map file for any of the passes?

The forms of the names of the .png and .wav files are just as you say they should be.


That's progress, at least. Now, your symptom resembles my other problem. You cannot create the .png file early, but -- you might not have the timer variable right. That was the other symptom caused another typo -- the TIMER variable was way too big and the .wav file would be huge. That's why I said -- it should be 19 or 20MB. The .png image is never created until the .wav file is done. I was "killing" the task when I was trying to troubleshoot it. That will cause you not to get a -map file, too. A typical pass lasts about 20-30 minutes at the most. I am in Iowa and just today, I got a pass that was almost directly overhead. Still not great data, but -- it was clearly a nearly overhead pass because the reception was the best right over where I live.

I would still scrutinize schedule_satellite.sh -- especially if your .wav file is not about 20MB. Right now, the quality is not important, the flow is your main issue at the moment. Next, I would verify receive_and_process_satellite.sh -- there are three lines to run the three programs -- rtl_fm, wxmap and wxtoimg. $6 is the variable that determines how long rtl_fm runs -- it is what determines when the .png image gets created. wxmap is what gets the overlay and wxtoimg is what decodes the image and overlays the map.

wxmap has 5 parameters and the first (-T "${1}") and last ({$3-map.png}) ones are okay, according to your latest update. I further assume that your TLE file is correct, which is the second parameter (-H $4) the next two should not matter (-p 0) -- the minimum population of cities to show -- 0 turns it off entirely, (-l 0) -- station location OFF, and that leaves the one that might be another source of trouble for you -- (-o $PassStart) Just to be absolutely sure -- the parameter is a lowercase letter o, but -- if you are having trouble, it is more likely that PassStart is wrong, or -- most likely, your wav file is too big, like mine was. What does that have to do with time, you ask? Not much, except that this operation is synchronized by determining the start time for a pass and calculating the stop time -- in schedule_satellite.sh -- if that is wrong, the receive_and_process_satellite.sh task will not operate properly at all. You will get some results, but -- not all three files. The variable PassStart is calculated by adding 90 to the EPOC start time. I assume the base is seconds. At any rate, if that is not reasonably close to the actual start time, you will not get a map file.

One last thing that I want to say is that you will receive an email every time a job gets ran, but -- it is one long text file and the only way I know to read it is by typing the following on a terminal screen (like SSH):

cat /var/mail/pi | less

and using the down and up arrow keys.\ to scroll forward and backward.


Hello again,

Still no pictures from the .png files; only static from the .wav files, and I still don't receive the -map files. I have gone over all the instructions, and everything in my code seems to be as presented (except I added a ">" to the grep line for NOAA15 in schedule_all.sh). My .wav files are about 20MB and my .png files are about 4MB. My PassStart is exactly as written in the instructions: PassStart=`expr $5 + 90`

When I type cat/var/mail/pi | less in my terminal (the same one I'm using for the code) all I see is a bunch of "~"s lined up vertically along the left side of the screen. Do I have to access the email somehow first?

I found a different "sudo timeout..." instruction in receive_and_process_satellite.sh online:

sudo timeout $6 rtl_fm -M wfm -f ${2}M -s 60k -A fast -p 10 -E wav -E deemp -F 9 - | sox -t wav - $3.wav rate 11025

but I haven't tried it as yet. I'll try it and get back to you. Unfortunately I am going on a month's vacation starting Sunday, so will be away from my setup until around the 4th of July.

Thanks again for your patience and willingness to help. It's difficult for you, not knowing what I know and don't know about this project.



HI, its me again, Im now getting problems with the "cmake ../ -DINSTALL_UDEV_RULES=ON"
It come up with " -bash : cmake : command not found" now is that down to the script or could it be down to something else?


If you followed this instruction and just copied and paste the commands it should work. I had a problem before trying to install it under Stretch.
If you start from a Jessie raspbian install it should work.

Can the code be changed to receive NOAA marine forecasts? Also, If your location is changing like on a boat is there an way to stream line the location input?

NOAA marine forecasts work very differently -- for one thing, they are transmitted on a schedule and use HF, not VHF. They are also considerably more difficult to get. There is a Wikipedia page that has links to the NOAA PDF that lists the stations and their schedules.


Using your favorite text editor, create a new file named /etc/modprobe.d/no-rtl.conf and put the following text in the file. You need to run that text editor as sudo (i.e. 'sudo vi' or 'sudo nano' etc) to write to the modprobe.d directory:

blacklist dvb_usb_rtl28xxu
blacklist rtl2832

blacklist rtl2830

Hi guys a very newbie doing coding on the PI, Im getting confused on how to exiting the "Text editor". I've spent hours on YouTube trying to figure it out but it seems that there's more ways of doing this.

I've tried most but nothing seems to happen.

HELP plase


Use Nano instead of VI ! Ctrl-X to save and quit ;-)

VI is a #@%$...

1 more answer

Welcome to the world of VIM the VI editor. Being new, I suggest to use only the NANO editor. It lists the commands at the bottom of the screen.

$ sudo nano /etc/modprobe.d/no-rtl.conf

Then to exit, type Control-X It will ask to save Y/N


Just a quick question. Can someone just please put all of this on an SD card so those of us who havent a clue what we'er doing can just "plug and play" lol :)


I have the same, have wav files of about 10Mb but only have an one of about 21k of 88 lines.
Even last night when NOAA18 crossed about overhead. Have a v-dipole in the attic with the open end of the V pointing south.
Have read other people having antennas in the attic, is not ideal but should have had something more so far.

The message "Tuned to 137580000 Hz. <--------" is correct. RTL-SDR's have to offset themselves from center frequency due to a DC spike that they filter out. But then they actually "listen" on the frequency that you originally entered.

This just moves the filter away from your tuned freq.

I also use the V antenna, but mine is outside. See the comments below for my userid "rgrokett" to see the rtm_fm and wxtoimg cmds I use and notes about the antenna.

1 more answer


Meanwhile improved the situation, built a qfh and now I have images.
What is weird one pass gives a perfect image and some passes give empty images. Most of those passes are high elevation passes.
Also in the mail in the header there is a strange frequency listed that is about 480kHz higher than the sats frequency.
I lowered the -p 55 tuner error correction to -p 20

Found 1 device(s):

0: Realtek, RTL2838UHIDIR, SN: 00000001

Using device 0: Generic RTL2832U OEM

Found Fitipower FC0012 tuner

Tuner gain set to 19.20 dB.

Tuner error set to 20 ppm.

Tuned to 137580000 Hz. <--------

Oversampling input by: 32x.

Oversampling output by: 1x.

Buffer size: 4.27ms

Sampling at 1920000 S/s.

Output at 60000 Hz.

Signal caught, exiting!

User cancel, exiting...

sox WARN wav: Premature EOF on .wav input file

wxmap: warning: could not find matching pass to build overlay map.

wxtoimg: error: could not open overlay map file '/home/pi/weather/NOAA1920180428-120216-map.png'

Satellite: NOAA

Status: signal processing.........wxtoimg: warning: number of lines in image exceeded 4096

wxtoimg: warning: couldn't find telemetry data

Gain: 24.3

Channel A: 3/3B (mid infrared)

Channel B: 4 (thermal infrared)

wxtoimg: error: could not open overlay map file '/home/pi/weather/NOAA1920180428-120216-map.png'

Satellite: NOAA

Status: signal processing.........wxtoimg: warning: number of lines in image exceeded 4096

wxtoimg: warning: couldn't find telemetry data

Gain: 21.8

wxtoimg: error: could not open overlay map file '/home/pi/weather/NOAA1920180428-120216-map.png'

Satellite: NOAA

Status: signal processing.........wxtoimg: warning: number of lines in image exceeded 4096

wxtoimg: warning: couldn't find telemetry data

Gain: 24.3

Channel A: 3/3B (mid infrared)

Channel B: 4 (thermal infrared)


Hi, i made this project on my raspberry pi 3B, and it seems to be receiving and processing all of the files normally. how do i view/export the .wav and .png files from my raspberry pi since the GUI is disabled? thank you!


This project's instructions worked flawlessly on my two Pi 3's. The first Pi was connected to a discone antenna and the second Pi to my QFH. Both antennas were placed next to each other at ground level, not very optimum, but good enough to run
comparison tests. The results of the QFH are phenomenal. Bulid one if
you have the chance, it's worth the time and effort.

I installed Apache2 and configured it to use port 8080 and added the NOAA directory
to /var/www/html (ex. /var/www/html/NOAA). Then I modified
receive_and_process_satellite.sh script to perform some extra tasks such

1. Removing old satellite images from /var/www/html/NOAA

2. Rename and copy the current satellite images from /home/pi/weather to /var/www/html/NOAA

3. Remove all satellite .png and .wav files from /home/pi/weather

Modified receive_and_process_satellite.sh :



# $1 = Satellite Name
# $2 = Frequency
# $3 = FileName base
# $4 = TLE File
# $5 = EPOC start time
# $6 = Time to capture

sudo timeout $6 rtl_fm -f ${2}M -s 60k -g 45 -p 55 -E wav -E deemp -F 9 - | sox -t wav - $3.wav rate 11025

PassStart=`expr $5 + 90`

if [ -e $3.wav ]
/usr/local/bin/wxmap -T "${1}" -H $4 -p 0 -l 0 -o $PassStart ${3}-map.png

/usr/local/bin/wxtoimg -m ${3}-map.png -e ZA $3.wav $3.png
/usr/local/bin/wxtoimg -m ${3}-map.png -e NO $3.wav ${3}.NO.png
/usr/local/bin/wxtoimg -m ${3}-map.png -e MCIR $3.wav ${3}.MCIR.png
/usr/local/bin/wxtoimg -m ${3}-map.png -e MSA $3.wav ${3}.MSA.png

# Delete old satellite image files from www directory
sudo rm /var/www/html/NOAA/*.*

# Copy, rename current files to www directory
sudo cp /home/pi/weather/NOAA*.png /var/www/html/NOAA/current.png
sudo cp /home/pi/weather/NOAA*.NO.png /var/www/html/NOAA/current.NO.png
sudo cp /home/pi/weather/NOAA*.MCIR.png /var/www/html/NOAA/current.MCIR.png
sudo cp /home/pi/weather/NOAA*.MSA.png /var/www/html/NOAA/current.MSA.png

# Delete old .png and .wav files from weather directory
sudo rm /home/pi/weather/*.png
sudo rm /home/pi/weather/*.wav



Browsing locally to 192.168.x.x:8080/NOAA will serve up the images and I can
also view them from anywhere that I have internet access by configuring
my router to port forward requests to the RPi.

I can't wait to move this project to our amateur radio club facility with a 360 deg., horizon to horizon view of the sky.

Here is my little modification to schedule_satellite.sh to begin to record when sat is at 10º:

PREDICTION_START=`/usr/bin/predict -t /home/pi/weather/predict/weather.tle -p "${1}" | awk '{ if($5>=10) print $0}' | head -1`
PREDICTION_END=`/usr/bin/predict -t /home/pi/weather/predict/weather.tle -p "${1}" | awk '{ if($5>=10) print $0}' | tail -1`

var2=`echo $PREDICTION_END | cut -d " " -f 1`

var4=`/usr/bin/predict -t /home/pi/weather/predict/weather.tle -p "${1}" | tail -1 | cut -d " " -f 1`

MAXELEV=`/usr/bin/predict -t /home/pi/weather/predict/weather.tle -p "${1}" | awk -v max=0 '{if($5>max){max=$5}}END{print max}'`

while [ `date --date="TZ=\"UTC\" @${var4}" +%D` == `date +%D` ]; do

START_TIME=`echo $PREDICTION_START | cut -d " " -f 3-4`
var1=`echo $PREDICTION_START | cut -d " " -f 1`

var3=`echo $START_TIME | cut -d " " -f 2 | cut -d ":" -f 3`

TIMER=`expr $var2 - $var1 + $var3`

OUTDATE=`date --date="TZ=\"UTC\" $START_TIME" +%Y%m%d-%H%M%S`

if [ $MAXELEV -gt 19 ]
echo ${1//" "} `date --date="TZ=\"UTC\" $START_TIME" +%d/%m/%Y" "%H:%M:%S` Max Elev: $MAXELEV >> /home/pi/weather/predict/pases.txt
echo "/home/pi/weather/predict/receive_and_process_satellite.sh \"${1}\" $2 /home/pi/weather/${1//" "}${OUTDATE} /home/pi/weather/predict/weather.tle $var1 $TIMER" | at `date --date="TZ=\"UTC\" $START_TIME" +"%H:%M %D"`


nextpredict=`expr $var4 + 60`

PREDICTION_START=`/usr/bin/predict -t /home/pi/weather/predict/weather.tle -p "${1}" $nextpredict | awk '{ if($5>=10) print $0}' | head -1`
PREDICTION_END=`/usr/bin/predict -t /home/pi/weather/predict/weather.tle -p "${1}" $nextpredict | awk '{ if($5>=10) print $0}' | tail -1`

MAXELEV=`/usr/bin/predict -t /home/pi/weather/predict/weather.tle -p "${1}" $nextpredict | awk -v max=0 '{if($5>max){max=$5}}END{print max}'`

var2=`echo $PREDICTION_END | cut -d " " -f 1`

var4=`/usr/bin/predict -t /home/pi/weather/predict/weather.tle -p "${1}" $nextpredict | tail -1 | cut -d " " -f 1`


6 replies

Hello, I have tried your modification of the file -schedule_satellite.sh-, copy the code and replace the original, but when I run the file schedule_all.sh so that all the tasks are executed it jumps an error that says - syntax error

I think problem is with copy and paste.

Send me an email and i will attach it.

runahue at gmail dot com

Somehow the line

TIMER=`expr $var2 - $var1 + $var3`

was causing the problem I replaced the apastrophes and script ran without problem.

Can you please post a copy of your script?

I seen to be having the same issue as well.

wasn't it simpler to change the 'gt 19' (greater than 19) to 'gt 9'?

Great Instructable! Using a Pi 3 -> RTL-SDR v3 -> QFH Antenna, with unneeded CATVX cable from Comcast. The antenna and Pi are mounted in the attic. I added on to the receive_and_process_satellite.sh with commands I found at http://www.wxtoimg.com/support/wxtoimg.pdf, to have the script create 5 different version of the image. Descriptions taken from linked .pdf. There are several others options. I also added –c to crop the telemetry lines off the sides.

Using WinSCP to move files from the Pi to my Windows desktop.

ZA: General purpose meteorological IR enhancement options. This is what is in the Instructable

MSA: Multispectral produces a vivid false colored image

HVCT: Another false color image with blue water and colors more indicative of land temperatures

Therm: Produces a false color image based on temperature. Provide a good way of visualizing cloud temps.

JF: Hybrid enhancement use to highlight both sea surface temps and cold clouds tops associated with thunderstorms and other weather systems.

I added the below to the process script.

if [ -e $3.wav ]


/usr/local/bin/wxmap -T "${1}" -H $4 -p 0 -l 0 -o $PassStart ${3}-map.png

/usr/local/bin/wxtoimg -m ${3}-map.png -c -e ZA $3.wav $3.png

/usr/local/bin/wxtoimg -m ${3}-map.png -c -e MSA $3.wav $3.color.png

/usr/local/bin/wxtoimg -m ${3}-map.png -c -e HVCT $3.wav $3.HVCT.png

/usr/local/bin/wxtoimg -m ${3}-map.png -c -e therm $3.wav $3.Thermal.png

/usr/local/bin/wxtoimg -m ${3}-map.png -c -e JF $3.wav $3.JF.png


I'm runing this stuff on NanoPi Neo and the main problem in my opinion are hard coded into script usernames. I had to manually fix /home/pi to my own home dir.

Second problem is the way cron invoke schedule_sattelite.sh script. It does it in somehow different way so output from date command is empty and we receive a lot of error messages (posted here with unary operator). In my situation helped editing cron manually:

sudo nano /etc/crontab

and adding line

1 0 * * * username /home/username/weather/predict/schedule_all.sh

where username is my user name and you should replace it with pi or any different name you use. This will make your cron job run as user you have chosen and errors should be gone.

The software side works now but I have to make an antenna to get proper images.

4 replies


I totally agree for the user name.

"/home/pi/" should be in all scripts replaced by "~/" which is the user's directory ! because under Ubuntu for example, the user may not be "pi".

Moreover, the commande rtl_fm must be /usr/local/bin/rtl_fm for a dark reason of path different between cron and user's terminal.


In my case:

user@nanopineo:~$ whereis rtl_fm
rtl_fm: /usr/local/bin/rtl_fm

Yes, local. I have corrected. Thanks.

In case someone want to view files via webbrowser

sudo apt-get install apache2

rm /var/www/html

sudo ln -s /home/username/weather /var/www/html

this should allow you to view files via webbrowser via your SBC IP address.


I have modified the schedulte_sat script for it to allow only full daytime passes (i.e between 7AM and 8PM). If you are interrested...

Moreover, all is working for a Rpi under Ubuntu 16.


rgrokett Thanks it worked a treat but things are still not working with other parts of the script, Ill figger that out at the weekend. Thanks for the help

Here is the antenna I am using, up at 15 ft fed by CATV coax:


And my wxtoimg line in "receive_and_process_satellite.sh"

sudo timeout $6 rtl_fm -M wfm -f ${2}M -s 60k -A fast -p 10 -E wav -E deemp -F 9 - | sox -t wav - $3.wav rate 11025

/usr/local/bin/wxtoimg -m ${3}-map.png -e MSA $3.wav $3.color.png



Notes :

- In "sudo timeout $6 rtl_fm", the "sudo" must be removed if you want to use the script as a normal user. But there is a difference in the PATH between an at job launched from cron and manually. So you must enter timeout $6 /usr/var/bin/rtl...


- "-p 55" must be "-p 0" for the temperature-compensated NOOELEC 2+ or RTL-SDR.COM ones.

- The RTL-SDR.COM metallic SDR keys are nice but very noisy : they generate a lot of wideband noise which can alter the S/N ratio. The plastic blue NOOELEC 2+ are a must.



Unfortunately, I get the following error message in mail:

sox FAIL formats: can't open input '-': WAVE: RIFF header not found

The leading quote looks a bit slanted compared to the following quote mark. Any ideas what that means?

Doug S.

1 reply

Hi Doug

got this error because I run the scripts under a different user.

I had to add this user to the sudoers without password.

Check /etc/sudoers.