Morse Buddy

For the curious

How it works

The interesting part is not that a phone can blink. It is that the other phone can reliably tell the difference between a blink and the rest of the world.

None of this is needed to use the app. It is here because people ask, and because several of these were found the hard way.

Detection uses the brightest few pixels, not the average

The obvious approach — average the brightness of a region and watch it rise — fails at any useful distance. At 30 feet the flash is a point of light perhaps three pixels across. Averaging it across the region divides its brightness by the region's area, lifting the mean by roughly 0.12 grey levels. That is below the sensor's own noise floor, and lost.

Morse Buddy instead takes the mean of the brightest handful of pixels in the frame. For that three-pixel case it measured 1728 times more sensitive than the average, and it still works when the spot is down to a single pixel.

At distance, the resize throws the signal away

At 100 feet the torch is plainly visible to the naked eye, and the app could not decode it. That turned out not to be a sensitivity problem but a resizing one. Frames are captured at 640×480, downscaled from a much larger sensor. At that distance the flash covers a fraction of a single sensor pixel, so the downscale averages it together with the dark around it — the signal is discarded before any of the decoding code sees a frame. The eye wins because the eye is not downscaling.

Cropping the sensor before the resize keeps that light. It adds no photons; it stops the ones already arriving from being thrown away. At the same 100 feet, on the same night, signal margin went from 99–123 without zoom to 223.6 with 5× zoom, against a detection gate of roughly 6–30. The furthest successful decode is 125 feet, outdoors, at night.

The receiver works out the sender's speed for itself

Nobody has to agree on a words-per-minute setting beforehand. The receiver collects the lengths of the on and off runs it observes and clusters them, deriving the dot length from the distribution rather than judging each symbol in isolation. That is what lets it survive timing jitter of ±25% and still decode.

The silent carrier is shaped, not switched

Gating a sine wave on and off with hard edges is the naive way to key a tone, and it splatters energy either side of the carrier as an audible click. Every dot would announce itself. Morse Buddy ramps each element with a raised-cosine envelope, which measured the out-of-band splatter at 65.5 dB down. That is the difference between a silent mode and a mode that clicks.

One decoder, two senses

The camera path and the microphone path both reduce what they see or hear to the same thing: a list of on and off durations. From there a single decoder handles both. The Morse engine itself is covered by 22 tests, and the tone decoder by a further 21 checks run against the transmitter's own output.

Why each carrier has the ceiling it does

Light runs 3 to 20 WPM, all proven decoding. The 18.5 kHz carrier is good well past 70 WPM — it is never the limit. The 700 Hz tone tops out near 18 WPM, because measuring a low frequency needs a 21 ms block, and above that speed the block is longer than the dits it is trying to measure. Not a defect; a consequence of the frequency.

The receiver zooms for you

It starts on a wide view and zooms in while it is not seeing anything, then holds the moment the flash appears. You do not need to know how far away the other phone is.

Try it with one device

The receive screen can replay a real recorded signal through the live decoder, so you can watch the app work before you have found a second device.

What you need

Requires iPhone 8 or newer, or an iPad, running iOS 16.4 or later. Signalling by light needs a camera flash — every iPhone has one, and so do iPad Pro and recent iPad mini models. Learning needs one device. Signalling needs two — one sending, one watching — though the built-in demo shows how the decoder works on a single device.