Ilma  · NAVTEX receiver
NAVTEX 518 kHz · RTTY 4.5 / 7.6 / 10.1 MHz · WEFAX 3.8 / 7.9 / 13.9 MHz

Songs propagating through the air,
decoded at sea

Ilma decodes maritime weather services – unattended on a Raspberry Pi in the boat, and on a Mac for development.

The interface

FIG. 1  ·  navtex-pi.local:8080
Ilma web interface: barometric-pressure trend in the topbar, NAVAREA and subject-code filters down the side, and a received DWD weather bulletin in the message archive.
518 kHz · MF

NAVTEX

International English service · single dial, monitored 24/7

SITOR-B FSK at 518 kHz. NAVAREA I stations take turns in fixed 10-minute slots, so the channel is live around the clock. When the same bulletin is re-broadcast a few hours later, Ilma merges the receptions — useful when fading varies between them.

ProtocolSITOR-B · F1B
Baud100
Shift±85 Hz
AreasNAVAREA I
4.5 / 7.6 / 10.1 MHz · HF

RTTY

DDK2 · DDH7 · DDK9 — scheduled UTC windows

Baudot at 50 baud. Maritime weather forecasts. Safety bulletins.

DDH7 · 7646 kHz · fragment F1B · 50 baud
ADRIA-N (44.1N  14.0E) SST: 18 C
MO 18. 00Z: S      0-2         0  M //
MO 18. 12Z: SE-S   2-3         0  M //
TU 19. 00Z: SW-W   0-2         0  M //
TU 19. 12Z: NW       3        0.5 M //
WE 20. 00Z: 
ProtocolBaudot · F1B
Baud50
Shift±225 Hz
StationsDDK2 · DDH7 · DDK9
3.8 / 7.9 / 13.9 MHz · HF

Weather fax

DDK3 · DDH3 · DDK6 — Pinneberg, simultaneous

FM-modulated facsimile at 120 lines per minute. Ilma syncs to the phasing band, accumulates the image, and writes one PNG per chart. The chart below is from the Royal Navy's GYA at Northwood, which Ilma also tracks.

Decoded 10 m wind forecast chart, North Atlantic, received from Northwood UK on 22 May 2026 12:00 UTC. Wind barbs and isotachs over Greenland, Iceland and the British Isles.
GYA Northwood 10 m wind · 22 May 2026 12:00 UTC
ModulationFM · 120 LPM
IOC576
OutputPNG · trimmed
Clockdisciplined
01

Offline re-decode

A separate process re-decodes each window from saved IQ and replaces the live transcript if it scores better.

02

Archive

Bulletins kept on disk and in SQLite. Search by body text, filter by area, station, subject, or date.

03

Schedule

Daily UTC windows, editable from the phone UI. Conflicts checked against the NAVAREA I slot table.

04

Phone notifications

Optional ntfy for new bulletins. SAR messages (subject D) bypass filters, per IMO MSC.1/Circ.1403.

Two ways to run it ·
I The bench

Mac or PC with an SDR dongle

Where I write and verify the decoder.

A 1:9 balun and a long wire is enough for bench reception. SDR++ sends audio into BlackHole 2ch and main.py --source audio reads from there. I check it against a known window — Den Helder at 14:30 UTC, or Pinneberg at 15:00 UTC.

SHELL · MACOS~/code
# clone, venv, install, run
$ git clone https://codeberg.org/sailingthroughcode/Ilma.git
$ cd Ilma
$ python3 -m venv .venv && source .venv/bin/activate
$ pip install -r requirements.txt
$ python3 main.py        # default --source audio
SDR appSDR++ · BlackHole 2ch
Dial517.000 kHz USB · IQ correction on
Antenna1:9 balun + long wire
Web UIlocalhost:8080
II The boat

Raspberry Pi, headless, on board

A Pi Zero 2 W in a dry locker, fed by a marine NAVTEX antenna.

The Pi reads IQ directly from the dongle. Everything runs as systemd services from boot. setup_pi.sh is idempotent; it installs deps, the RTL-SDR DVB blacklist, the NetworkManager AP profile, and the systemd units.

SHELL · RASPBERRY PI~/navtex
# one-shot install on a fresh Pi OS
$ git clone https://codeberg.org/sailingthroughcode/Ilma.git ~/navtex
$ cd ~/navtex
$ bash scripts/setup_pi.sh
$ sudo $EDITOR /etc/default/navtex     # AP_PASSWORD, KNOWN_SSIDS
$ sudo systemctl enable --now navtex.service
SBCPi Zero 2 W · headless
IQ rate256 kS/s direct from pyrtlsdr
AntennaActive marine NAVTEX
Web UInavtex-pi.local:8080 · or 10.42.0.1 (AP)