Decoding Weather Fax Transmissions with Ilma

sailingcode1 pts1 comments

Decoding Weather Fax Transmissions with Ilma | Sailing through Code 11/06/2026 Decoding Weather Fax Transmissions with Ilma

Ilma1 is a Navtex decoder for the Raspberry Pi that just got weather fax (WEFAX) capabilities. For an offshore sailor, reliable weather forecasts are essential. Ilma continuously receives and decodes Navtex, as recently described. The addition of weather fax extends Ilma’s features to charts showing barometric pressure, sea temperature, wave direction, or ice.

⇨ Ilma’s website

Adding weather fax capabilities to Ilma was a quest for straight lines in the decoded charts. Ilma’s first decode came back warped with a strange S-shape (Figure 1).2 An S-shape was not what I expected – the usual problem is skewing. I would get plenty of that later.

Figure 1. The first weather fax decoded by Ilma. The transmission, received via Twente WebSDR, shows a Pinneberg DDK3 transmission on 7880 kHz: a weather prediction chart by DWD.

This first decoded fax still shows the post-alignment tail sliced into ~20 image rows of black with a left-edge pulse – the visible noise band. This was subsequently corrected to display only the trailing fractional-line residue (<br>In the North Sea area, weather fax charts are transmitted by Deutscher Wetterdienst (DWD) from Pinneberg on 3855, 7880, and 13882.5 kHz. 36-hour-prediction charts are broadcast at 0512 and 1256 UTC, for example.3 Met Office charts are sent by the Royal Navy from Northwood, UK.4 During development of Ilma, I used Twente WebSDR5 routed through BlackHole to receive these signals on the Mac and tweak the decoder to auto-detect the start tone.

There are weather fax stations worldwide,6 e.g. in Australia, Canada, Chile, China, Germany, Greece, Japan, Korea, Russia, Thailand, the UK, and the USA. Because these fax charts are broadcast via shortwave radio, they propagate over thousands of miles. These signals reflect off the ionosphere (skywave propagation). The lower frequencies propagate best at night, the higher ones during the day, depending on which ionospheric layer is doing the work.

A visit to Leonhard Euler

Programming the basic fax decoder revealed my struggle to recall what I should have learned in math classes. Leonhard Euler was Swiss, too, but that didn’t help me grasp his formula at a glance. It’s worth understanding his almost-300-year-old formula, and the reason becomes apparent the moment you open an SDR datasheet. The incoming signal is delivered as a complex number with a real and an imaginary part.

For a mathematical agnostic like me, numbers are all somewhat imaginary. But the term goes back to René Descartes’ 1637 work La Géométrie, where he described square roots of negative numbers as “imaginaires”. The work appeared in the Dutch Golden Age. Descartes had been drawn there by the country’s intellectual and religious freedom. It’s only fitting that the test transmissions for my decoder were received via the Twente WebSDR5 located in the Netherlands.

A century later, Leonhard Euler published e(iθ) = cos(θ) + i·sin(θ) in Introductio in analysin infinitorum (1748), joining exponential growth (analysis) and circular motion (trigonometry) and thereby laying the foundation for digital signal processing.7

To implement a frequency-modulation (FM) discriminator, we need to compute instantaneous frequency from the analytic signal. Instantaneous frequency is the time derivative of phase. For a discrete complex signal z[n]:

f[n] = (sample_rate / (2π)) · angle(z[n] · conj(z[n−1]))

The crucial point is that SDRs deliver each sample as an I/Q pair8 – called I/Q for In-Phase / Quadrature. The I component is in phase with the carrier; it’s the complex number’s real part, i.e. Euler’s cos(θ). The Q (Quadrature denotes its 90° shift from the I component) maps to Euler’s i·sin(θ), the imaginary part of the complex number. These two numbers, taken together, encode both amplitude and phase. The principle, which also applies to the demodulation of WLAN, LTE, and 5G signals, lets us use simple algebra instead of trigonometry for signal processing.

The I/Q signal delivered by the SDR dongle, a complex 1024 kS/s stream, is decimated to 48 kHz and passes through the discriminator, which outputs instantaneous frequency in Hz. This real value is the instantaneous frequency scaled to 1500–2300 Hz; values outside the band are clipped. It’s the grey level we can map to pixels (Figure 2).

Figure 2. Top: A slice of audio with a visible frequency shift around 18 ms. Oscillation goes from sparse (1500 Hz, black) to denser (2300 Hz, white).<br>Middle panel: The discriminator shows a clean step from 1500 to 2300 Hz at the pulse leading edge, then a 24 ms plateau at 2300 Hz, and a step back down at the trailing edge.<br>Bottom: The luminance strip displays the corresponding black / white / black band of pixels.

A 17th-century mathematical curiosity, perceived as imaginary, became radio infrastructure centuries later and now decodes weather charts from...

weather ilma charts from signal frequency

Related Articles