0x55aa
← Back to Blog

NOAA Weather Satellites: I'm Downloading Photos Directly from SPACE! šŸ›°ļøšŸ“”

•19 min read

NOAA Weather Satellites: I'm Downloading Photos Directly from SPACE! šŸ›°ļøšŸ“”

Real talk: My friend asked me what the weather looked like. I said "hang on" and pointed a homemade wire antenna at the sky for 12 minutes.

Then I showed him an actual photo of the cloud cover over our continent. Downloaded. Live. From a satellite orbiting Earth at 530 miles altitude. Using a USB dongle I bought for $20.

He asked if I needed professional help.

I told him I needed a BETTER ANTENNA.

Welcome to NOAA APT satellite reception — the most ridiculously satisfying SDR project that nobody tells beginners about. A literal photograph. From space. For free. Today. šŸŒ

What Even ARE NOAA Satellites? šŸ¤”

NOAA = National Oceanic and Atmospheric Administration

They operate a fleet of polar-orbiting weather satellites circling Earth at ~830 km altitude. Every pass takes about 15 minutes. They cross every point on Earth multiple times per day.

The beautiful part? These satellites have been broadcasting weather images in a format called APT (Automatic Picture Transmission) since the 1960s. It's an ANALOG signal. At VHF. At 137 MHz. Designed to be received by simple ground stations.

Think of it like this:

  • The old way: Tune into a TV station
  • APT reception: Same concept — tune into a satellite "TV station" broadcasting weather images from orbit!

The active satellites right now:

NOAA-15: 137.620 MHz
NOAA-18: 137.9125 MHz
NOAA-19: 137.100 MHz

All broadcasting continuously.
All crossing YOUR sky multiple times daily.
All transmitting actual cloud cover images.

What fascinated me as a developer: APT isn't compressed data. It's literally an audio-frequency image signal — like a fax machine from space. The image is encoded in the audio. You can almost HEAR it sound like a picture when you play it back! šŸŽµ

How I Fell Into This Rabbit Hole 🐰

The Accidental Discovery

Me: Scanning 137 MHz with RTL-SDR just exploring the VHF band

Waterfall display: Suddenly shows a MASSIVE wide signal sweeping across the screen. Strong, structured, beautiful.

Me: "What the HECK is THAT?! It's enormous!"

Google: "137 MHz wide signal — NOAA weather satellite APT downlink"

Me: "Wait... satellites are just... broadcasting? And I can RECEIVE them? With THIS?!" 😱

The First Attempt (Spectacular Failure)

In my RF experiments, the first try was humbling:

Used: Stock RTL-SDR whip antenna (upright, indoors)
Result: Faint signal, barely above noise
Image quality: Like a potato dragged through mud
Lesson learned: ANTENNA MATTERS A LOT

The V-Dipole Revelation

Two hours later, I built a V-dipole antenna from two pieces of wire. Cost: $0 (I used an old coat hanger).

V-Dipole for 137 MHz:
Each arm: 53.4 cm (quarter wavelength)
Angle between arms: 120 degrees
Mount horizontally, point at sky

That's it. Seriously. That's the whole antenna.

Me: Goes outside, holds antenna at sky, records satellite pass

The result: A crisp, beautiful, actual satellite image of cloud formations over my continent.

My reaction: I sat in my backyard at 6 AM staring at my laptop screen showing real-time weather patterns forming over the ocean and I literally said "I'm receiving signals from SPACE" to nobody in particular. My neighbor's dog looked at me funny.

I have never recovered. šŸ›°ļø

The Science (Explained Like We're Developers) šŸ”¬

What APT Actually Is

APT encodes the image as audio tones:

Image → Scan line by line (top to bottom)
Each pixel brightness → Audio frequency (from 1040 Hz to 2640 Hz)
Scan rate: 2 lines per second
Frame rate: 120 lines per minute

Think of it as: A VERY SLOW FAX MACHINE IN ORBIT

The audio you hear: That distinctive WEEOOO WEEOOO warbling sound? That's the IMAGE. Your ears are hearing a photograph from space! šŸŽ¶

Two Channels in Every Pass

Each NOAA satellite transmits TWO image channels simultaneously:

Channel A: Visible light (daytime only — actual sunlight reflection)
Channel B: Near-infrared thermal (works day AND night!)

Left half of image = Channel A
Right half of image = Channel B

Together = Stereo weather photo from orbit!

What Channel B shows at night: Heat signatures. Clouds glow because they're cold. Land shows temperature gradients. It's basically thermal vision of the ENTIRE continent!

The Doppler Effect in Action

As the satellite rises over your horizon, flies overhead, then disappears:

Satellite approaching:   Signal SHIFTS UP in frequency (Doppler!)
Satellite at zenith:     Signal at nominal frequency
Satellite receding:      Signal SHIFTS DOWN in frequency

You LITERALLY observe relativistic physics with a $20 dongle!

As a developer exploring radio frequencies, watching the Doppler curve shift in SDR# during a satellite pass is one of the coolest things I've ever seen in real-time. You're watching the satellite MOVE! šŸš€

The Hardware Setup (Embarrassingly Minimal) šŸ› ļø

What You Need

Total cost: $20-40

Essential:
- RTL-SDR Blog v3 dongle: $20
  (any RTL-SDR works, honestly)

Antenna options:
- Option A: V-dipole from coat hanger: $0 (FREE!)
- Option B: Turnstile antenna kit: $15 (better circular polarization)
- Option C: QFH (Quadrifilar Helix): $30 (best performance)

Everything else: Just a laptop!

What I actually use:

  • RTL-SDR Blog v3
  • Homemade V-dipole (coat hanger + some wire)
  • Raspberry Pi 4 for automated passes

My total investment: About $25. I spent more on the coffee I was drinking when I received my first satellite image. ā˜•

Build the V-Dipole (The FREE Antenna)

Materials needed:
- 2 pieces of wire, 53.4 cm each (the magic number for 137 MHz)
- Something to hold them at 120° angle
- Coax cable to connect to your RTL-SDR

The math:
  Speed of light (c) = 299,792,458 m/s
  Frequency (f) = 137.5 MHz (average)
  Quarter wavelength = c / (4 Ɨ f) = 0.545 m = 54.5 cm
  (Trim a bit for end effect: ~53.4 cm)

Mount HORIZONTALLY. Point at SKY. That's it!

What fascinated me: This simple wire outperforms fancy commercial antennas designed for other purposes. RF physics doesn't care about cost — it cares about correct length and orientation! šŸ“

Software Setup (All FREE!) šŸ’»

Option 1: SatDump (Recommended — Does Everything!)

# Install SatDump on Linux/Raspberry Pi
sudo apt-get install cmake build-essential librtlsdr-dev
git clone https://github.com/SatDump/SatDump
cd SatDump
mkdir build && cd build
cmake ..
make -j4
sudo make install

# Run SatDump
satdump-ui

What SatDump does:

  • Receives the satellite signal directly
  • Decodes the APT audio in real-time
  • Generates the image as the pass happens
  • Shows you the image LIVE as it downloads from orbit! šŸŽØ

Option 2: SDR# + WXtoIMG (Classic Workflow)

# Step 1: Record the pass with SDR# (or GQRX on Linux)
# Tune to satellite frequency (137.620 MHz for NOAA-15)
# Record as WAV file during the pass

# Step 2: Decode with WXtoIMG
# Load WAV file
# Click Decode
# Watch image appear!

Option 3: Python (For the Developers!) šŸ

#!/usr/bin/env python3
"""
NOAA APT Decoder in Python
Because we're developers and we want to understand EVERYTHING
"""

import numpy as np
import scipy.signal as signal
from scipy.io import wavfile
import matplotlib.pyplot as plt

def decode_apt(wav_file):
    """Decode a NOAA APT recording to image"""

    # Load WAV file from SDR recording
    sample_rate, audio_data = wavfile.read(wav_file)
    print(f"Sample rate: {sample_rate} Hz")
    print(f"Duration: {len(audio_data)/sample_rate:.1f} seconds")

    # Normalize audio
    audio = audio_data.astype(np.float64)
    audio /= np.max(np.abs(audio))

    # APT signal is AM modulated at 2400 Hz carrier
    # Demodulate: extract the envelope
    hilbert = signal.hilbert(audio)
    envelope = np.abs(hilbert)

    # Resample to exactly 4160 samples per line
    # (2 lines/sec Ɨ 2080 pixels/line = 4160 samples/sec for 11025 Hz audio)
    target_rate = 4160
    num_samples = int(len(envelope) * target_rate / sample_rate)
    resampled = signal.resample(envelope, num_samples)

    # Reshape into image lines (2080 pixels wide)
    pixels_per_line = 2080
    num_lines = len(resampled) // pixels_per_line
    image_data = resampled[:num_lines * pixels_per_line]
    image_matrix = image_data.reshape(num_lines, pixels_per_line)

    # Normalize to 0-255
    image_matrix = (image_matrix - image_matrix.min())
    image_matrix = (image_matrix / image_matrix.max() * 255).astype(np.uint8)

    # Display!
    plt.figure(figsize=(15, 8))
    plt.imshow(image_matrix, cmap='gray', aspect='auto')
    plt.title('NOAA APT Decoded Image — DOWNLOADED FROM SPACE! šŸ›°ļø')
    plt.colorbar(label='Brightness')
    plt.savefig('satellite_image.png', dpi=150, bbox_inches='tight')
    print("Image saved to satellite_image.png!")
    print("You just decoded a satellite image using PURE MATH! šŸŽ‰")

    return image_matrix

# Run the decoder
if __name__ == "__main__":
    image = decode_apt("noaa_pass.wav")
    print(f"Image dimensions: {image.shape[1]}Ɨ{image.shape[0]} pixels")
    print(f"Left half = Channel A (Visible)")
    print(f"Right half = Channel B (Infrared)")

What fascinates me: This is literally just signal processing. Sample rate math, envelope detection, reshaping arrays. The ENTIRE satellite image decoder is about 40 lines of Python. Wild! 🧠

Predicting Satellite Passes (The Fun Part) šŸ”­

You can't just tune to 137 MHz and wait — you need to know WHEN the satellite passes over you!

Free Tools for Pass Prediction

# Install Gpredict (desktop pass predictor)
sudo apt-get install gpredict

# OR use the website:
# https://www.heavens-above.com
# Enter your location → "Radio Amateur Satellites"
# Shows all NOAA pass times, elevations, directions!

# OR command line with predict
sudo apt-get install predict
predict -t tle-data.txt

Reading a Pass Schedule

Upcoming NOAA-19 passes for [Your City]:

Time (UTC)   Max Elev   AOS Dir   LOS Dir   Duration   Quality
──────────────────────────────────────────────────────────────
06:23 AM     78°        NW        SE        14 min     EXCELLENT
08:42 AM     31°        NNW       SE        12 min     GOOD
11:05 AM     12°        NW        S         8 min      POOR

What these numbers mean:

  • Max Elevation 78°: Nearly overhead = strong signal! ā¬†ļø
  • Max Elevation 12°: Low on horizon = lots of atmosphere, weak signal šŸ˜•
  • AOS/LOS: Acquisition/Loss of Signal directions (where to point antenna)

My rule: Only bother with passes above 30° elevation. Below that, the images look terrible and you'll just be disappointed.

Automated Reception on Raspberry Pi

#!/bin/bash
# auto_receive.sh - Fully automated NOAA satellite station!

SATELLITE="NOAA 19"
FREQUENCY="137100000"  # 137.1 MHz in Hz
DURATION="900"          # 15 minutes
OUTPUT_DIR="/home/pi/satellite_images"

# Get next pass time using predict
NEXT_PASS=$(predict -t tle.txt -e "$SATELLITE" | head -1)
echo "Next $SATELLITE pass: $NEXT_PASS"

# Wait until 30 seconds before pass starts
# ... (scheduling logic) ...

# Record the pass
rtl_fm -f $FREQUENCY -s 60000 -g 40 - | \
  sox -t raw -r 60000 -e signed -b 16 -c 1 - \
      -r 11025 "$OUTPUT_DIR/$(date +%Y%m%d_%H%M%S).wav" \
      rate 11025

# Decode with SatDump
satdump noaa_apt \
  --source wav \
  --file "$OUTPUT_DIR/latest.wav" \
  --output "$OUTPUT_DIR/decoded/"

echo "New satellite image saved! šŸ›°ļø"
# Optionally: send to email/Slack/Discord

Result: My Raspberry Pi automatically records EVERY NOAA pass, decodes the image, and saves it. I come home to fresh satellite photos of my continent taken while I was at work. It's my own private weather satellite ground station! šŸ–„ļø

My Best Satellite Images (Emotional Moments!) šŸ“ø

Image #1: First Ever — The Shaky-Hands Moment

Setting: 6 AM. Cold. Standing in backyard. Holding antenna with both hands toward sky.

Pass duration: 12 minutes.

What I saw materializing line by line:

[Line 1-50]:   Black. Just noise. Did I mess up the frequency?
[Line 51-100]:  WAIT. Something is forming...
[Line 101-150]: Oh my god those are CLOUDS.
[Line 151-200]: I CAN SEE THE COASTLINE.
[Line 200+]:    THAT IS AN ACTUAL SATELLITE PHOTO OF MY COUNTRY.

I may have made sounds a grown adult shouldn't make at 6 AM. My neighbors probably noticed. I don't care. I DOWNLOADED A PHOTO FROM SPACE WITH COAT HANGER WIRE. 🤩

Image #2: Tropical Storm Discovery

Three months into running my automated station, I reviewed a 3 AM image from NOAA-19.

In the thermal infrared channel: A perfect spiral.

A tropical storm system I hadn't heard about yet. I could see the spiral arms, the eye, the cold cloud tops.

I found it on my screen before I saw it on the news.

My automated ground station caught a WEATHER EVENT before I read about it.

That's when this stopped being a toy and became something meaningful.

Image #3: The Solar Panel Burn-In

NOAA-15 is getting old. It launched in 1998 and the solar panel charging system is degrading. Some of my NOAA-15 images have characteristic artifacts from the aging satellite.

What fascinates me: I'm receiving signals from hardware that has been orbiting Earth for nearly 30 YEARS. Those photons bouncing off clouds and hitting my coat-hanger antenna were converted to electricity by solar panels launched when I was a kid. The signal quality tells the story of an aging spacecraft. 🌟

Why This Is Perfect for Developers šŸ§‘ā€šŸ’»

As a software developer who got into RF, NOAA APT hits every interesting intersection:

Signal processing: Demodulation, resampling, envelope detection — all real DSP concepts!

Data visualization: You're turning audio data into a 2D image array. NumPy and matplotlib make this beautiful.

Automation: Cron jobs, satellite TLE calculations, pass prediction algorithms — proper software engineering for a physical system!

APIs and data:

# The "API" is: a 137 MHz radio signal
# The "authentication" is: being inside the satellite's coverage footprint
# The "response" is: a 2080ƗN pixel weather image
# The "documentation" is: ITU APT specification from 1968

# It's like calling a REST API except the server is in SPACE
# and the response literally falls from the sky šŸ›°ļø

Version control for your images:

# I store all my satellite captures in a git repository!
git add "images/2026-02-20_NOAA19_0623UTC.png"
git commit -m "feat: NOAA-19 morning pass, nice cloud formations over Bay of Bengal"
git push

# My satellite image history is version-controlled.
# I am not okay. This is fine. šŸ“”

Practical Project Ideas šŸš€

Project 1: Automated Weather Station

Run a Raspberry Pi that captures every pass, decodes the image, and posts to a Discord/Slack channel:

import discord
from pathlib import Path

async def post_satellite_image(channel, image_path, satellite_name, pass_time):
    """Post new satellite image to Discord"""
    embed = discord.Embed(
        title=f"šŸ›°ļø New {satellite_name} Pass!",
        description=f"Captured at {pass_time} UTC",
        color=0x00ff00
    )

    with open(image_path, 'rb') as f:
        file = discord.File(f, filename="satellite.png")
        embed.set_image(url="attachment://satellite.png")

    await channel.send(embed=embed, file=file)
    print(f"Posted {satellite_name} image to Discord! āœ…")

Project 2: Cloud Cover Tracker

Compare images from morning and evening passes to detect weather changes:

import numpy as np
from PIL import Image

def analyze_cloud_cover(image_path):
    """Calculate cloud cover percentage from APT image"""
    img = Image.open(image_path).convert('L')
    data = np.array(img)

    # Channel B (right half) = infrared
    # Bright pixels = cold clouds (high altitude)
    infrared = data[:, 1040:]  # Right half

    # Threshold: pixels brighter than 128 = likely cloud
    cloud_pixels = np.sum(infrared > 128)
    total_pixels = infrared.size
    cloud_percentage = (cloud_pixels / total_pixels) * 100

    print(f"Estimated cloud cover: {cloud_percentage:.1f}%")
    return cloud_percentage

# Track over time!
# 08:00 UTC: 34% cloud cover
# 20:00 UTC: 67% cloud cover
# Tomorrow: Weather system moving in!

Project 3: Color-Enhanced Images

The default grayscale images are cool. The false-color enhanced versions are STUNNING:

def apply_false_color(apt_image):
    """
    Apply false color to APT image
    Channel A (visible) = show as green (land) + blue (sea)
    Channel B (infrared) = cold regions = white clouds
    """
    h, w = apt_image.shape
    color_image = np.zeros((h, w, 3), dtype=np.uint8)

    visible = apt_image[:, :w//2]   # Channel A
    infrared = apt_image[:, w//2:]  # Channel B

    # Classic "MSA" (Multi-Spectral Analysis) palette
    # Cold cloud tops (bright infrared) = white
    # Warm land = green/brown
    # Sea = dark blue

    color_image[:, :w//2, 1] = visible       # Green channel
    color_image[:, w//2:, 2] = 255 - infrared  # Blue (inverted IR)
    color_image[:, w//2:, 0] = infrared >> 1   # Red (half IR)

    return color_image

The result: Proper satellite-looking images with blue oceans, green land, and white cloud tops. Looks like something NASA would publish! šŸŒ

Legal & Safety Stuff āš–ļø

The Beautiful Legal Reality

NOAA APT reception:

  • āœ… 100% legal worldwide (passive receive only)
  • āœ… These are PUBLIC broadcasts from government satellites
  • āœ… No license required to RECEIVE
  • āœ… NOAA literally wants people to receive this data
  • āœ… The APT format is an open standard

What NOAA says: They publish TLE orbital data, frequency information, and documentation specifically so people can receive these signals! They WANT a global network of ground stations. 🌐

One technical note: You're only RECEIVING. Your RTL-SDR cannot transmit on 137 MHz — it's receive-only hardware. No accidental interference risk!

Electrical Basics

Power the antenna correctly:

Good: RTL-SDR → V-dipole antenna (passive, safe)
Bad: Transmitter → RTL-SDR (instant fried dongle)

RTL-SDR is a RECEIVER ONLY. Keep it that way! šŸ›”ļø

Bias tee tip: Some RTL-SDR dongles have a bias tee (5V DC on antenna port) for powering LNAs. Don't accidentally enable this on a passive antenna. Check your settings! āš ļø

Getting Started This Weekend šŸš€

Saturday: First Satellite Pass

Morning prep:

  1. Check pass times at heavens-above.com (enter your location)
  2. Make V-dipole (53.4 cm wire Ɨ 2, any wire works!)
  3. Install SatDump or SDR# + WXtoIMG

The actual process:

# 5 minutes before pass:
# Open SDR#, tune to satellite frequency
# Start recording

# During 12-minute pass:
# Watch the waterfall for the satellite signal
# Strong signal = doppler curve across waterfall
# Keep antenna pointed OVERHEAD (satellite is near zenith!)

# After pass:
# Load recording in WXtoIMG
# Click Decode
# See your first satellite image! šŸ›°ļø

Guaranteed first-pass success tip: Pick a pass with MAXIMUM ELEVATION above 60°. You'll get a strong signal even with a basic antenna!

Sunday: Level Up

  1. Build a turnstile antenna (circular polarization = better reception!)
  2. Set up Gpredict for pass scheduling
  3. Try Python decoder on your WAV recording
  4. Compare Channel A (visible) vs Channel B (infrared) images

Next Week: Automate Everything

  • Raspberry Pi + rtl_fm = automated recordings
  • SatDump batch processing = auto-decoded images
  • Cron jobs = scheduled captures
  • Discord webhook = satellite images in your phone every morning! šŸ“±

Resources for Getting Started šŸ“š

Software (all FREE!):

Pass Prediction:

Learning:

Hardware:

  • RTL-SDR Blog v3 ($20) — the standard recommendation
  • Any coax cable with SMA connector ($5)
  • Wire for V-dipole — literally free

The Bottom Line šŸ’”

NOAA APT reception is the project that makes non-technical people's jaws drop. "You downloaded a satellite image? With THAT?" Yes. Yes I did. With coat hanger wire and free software.

What I learned as a developer exploring radio frequencies:

The electromagnetic spectrum is everywhere, full of signals, and most of them are meant to be received by anyone with the right antenna. NOAA has been broadcasting weather images since the Nixon administration. For FREE. For ANYONE. The technology predates the internet. And with a $20 USB dongle, you can participate in this global observation network that's been quietly operating for half a century.

The real magic: You're not just seeing a weather image. You're watching a satellite transmit data about our atmosphere, decode it in real-time with open-source software, and understand weather patterns firsthand. Meteorologists use the EXACT SAME images (in higher resolution versions) for actual forecasts.

After six months of automated NOAA captures, I've downloaded over 1,200 satellite images, caught 3 tropical weather systems forming, watched a heatwave move across a continent, and once accidentally became the most weather-aware person at a party by pulling up a thermal infrared satellite image from two hours earlier on my phone.

The weather app is for quitters. We receive it from ORBIT. šŸŒšŸ“”

TL;DR

  • NOAA-15/18/19 broadcast weather images from orbit at 137 MHz VHF
  • $20 RTL-SDR + FREE coat hanger antenna + FREE software = satellite photos
  • Each pass = 12-15 minutes, multiple times per day over your location
  • 100% legal passive receive, no license needed
  • You're literally downloading a photograph from a satellite 830 km above Earth
  • The first time you see clouds form on your screen from a live satellite pass, you will question every "expensive hobby" you've ever had

Built a NOAA ground station? Connect with me on LinkedIn and share your best satellite image!

Want to see my satellite automation code? Check out my GitHub — automated pass scheduler, image decoder, and cloud cover analyzer scripts!

Now go build that antenna. The satellites are up there right now, broadcasting. All you have to do is listen. šŸ›°ļøšŸ“”šŸŒ


P.S. The first time you show someone a live satellite image you just captured and their reaction is "wait, you MADE that?" — you will understand why RF is the best hobby nobody talks about. The look on their face when you explain it was coat hanger wire is PRICELESS.

P.P.S. I now check my satellite image archive before checking the weather app. Every morning. My Raspberry Pi quietly captured two NOAA passes while I slept, and I wake up to actual photographs of the weather system heading my way. This is not a healthy obsession. This is SCIENCE.

P.P.P.S. Warning: Once you successfully receive NOAA APT, you will immediately start researching HRPT (higher resolution satellite images), Meteor-M N2-3 reception (Russian satellite, even BETTER images), and eventually you'll be looking at 1.2-meter dish antennas and wondering how to mount one on your apartment roof. Your landlord will say no. You will start looking at houses with "good southern exposure." This is the path. Welcome. šŸ›°ļø