Some years ago I setup a basic antenna connected to a Raspberry Pi in order to directly receive and decode NOAA weather satellite images, which are transmitted in the APT analog encoding - I used this initial guide at the beginning, with some updates from this one, but not including the added Meteor-M decoder functionality, which, perhaps due to a not-too-great antenna quality and exposure didn’t turn out to work.

This was, in fact, the initial reason for setting up this website, with the received images being published here, with a very rudimental list of the day’s scheduled passes is available here.

Additionally, more recently I reworked the three provided scripts in order to remove unneeded uses of the “sudo” command and explicit references to the then-standard default “pi” name used for the user and thus the home directory path.

In 2020 I switched from a V-dipole antenna to a Quadrifilar Helix (QFH) antenna: QFH antenna

In 2022 I switched from a NooElec NESDR Mini 2+ to a genuine RTL-SDR Blog V3, thinking that an issue might have cropped up with the former’s smaller coax connector, but this didn’t turn out to be the case.

The “predict” package seems to have been deprecated from Debian’s repositories some time ago, so it’s no longer possible to install it directly using the apt package manager as suggested in the first guide referred to here. Instead, it must be downloaded manually fomr either the GitHub repository or the project’s main website, which seems to show newer versions compared to the one available on GitHub (2.2.5 at the time of writing).

In the meantime the updated scrips are listed here - I might package them a bit better in a GitHub repo at a later date…perhaps.


# Update Satellite Information

wget -qr -O ~/weather/predict/weather.txt
grep "NOAA 15" ~/weather/predict/weather.txt -A 2 > ~/weather/predict/weather.tle
grep "NOAA 18" ~/weather/predict/weather.txt -A 2 >> ~/weather/predict/weather.tle
grep "NOAA 19" ~/weather/predict/weather.txt -A 2 >> ~/weather/predict/weather.tle

#Remove all AT jobs

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

# Create a new empty temporary passes.txt file

touch passes.txt
echo -e "Satellite\tDate-Time\t\tMax Elevation" >> passes.txt
echo "----------------------------------------------------------" >> passes.txt

# Schedule Satellite Passes:

~/weather/predict/ "NOAA 19" 137.1000
~/weather/predict/ "NOAA 18" 137.9125
~/weather/predict/ "NOAA 15" 137.6200

# Move passes.txt file
mv passes.txt ~/weather/received_temp

# To enable verbose output uncomment the following line:
# set -x

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

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

MAXELEV=`/usr/bin/predict -t ~/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
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 40 ]
    echo -e ${1//" "}'\t\t'${OUTDATE}'\t\t'$MAXELEV >> passes.txt

    echo "~/weather/predict/ \"${1}\" $2 ~/weather/${1//" "}${OUTDATE} ~/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 ~/weather/predict/weather.tle -p "${1}" $nextpredict | head -1`
PREDICTION_END=`/usr/bin/predict -t ~/weather/predict/weather.tle -p "${1}"  $nextpredict | tail -1`

MAXELEV=`/usr/bin/predict -t ~/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`

  • - this file also includes a reference to an optional script that manages the syncing of the images to this very website (

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

# Originally from with
# revised rtl_fm command from

# New version with also sudo removed:
timeout $6 rtl_fm -f ${2}M -s 48k -g 44.5 -p 0 -E dc -A fast -F 9 - | sox -t raw -r 48000 -es -b16 -c1 -V1 - $3.wav rate 11025 >> rtl_log.txt

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 -e MSA $3.wav ${3}.MSA.png
    #/usr/local/bin/noaa-apt $3.wav -o $3_noaa-apt.png

    # Delete overlay file
    rm ~/weather/*-map.png

    # Copy resulting images to webserver folder
    cp ~/weather/*.png ~/weather/received_temp/
    cp ~/weather/*.wav ~/weather/received_temp/

    # Delete files older than 7 days
    find ~/weather/received_temp/* -mtime +7 -exec rm {} \;

    # Cleanup folder
    rm ~/weather/*.png
    rm ~/weather/*.wav

    # Sync to remote server