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.
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.