Today we will describe a single channel Morse decoder architecture. These are the systems and structures I will need to write a decoding program.
My first step will be to obtain audio from the radio receiver. While there are many ways I can do this, my approach will be to use PortAudio to read in audio sampled at 8000 samples per second. My receiver will do the heavy lifting to filter CW, typically in a 100 Hz bandwidth.
Simple enough. Now the first challenge is (1) Tone Detection. The simplest approach is to use a Goertzel filter to convert a bunch of samples into an “on” or “off” signal. This is the same algorithm used by telephone systems to read tones at a specific frequency, e.g. DTMF dialing tones. My receiver CW pitch and Goertzel filter will both the set to pass 800 Hz tones.
I want to create a DC pulse train (on-off keying) for analysis. Two methods are available to create the pulses. One is thresholding, where a signal above a certain level will signify a digital “on”. Another and better approach is edge detection, where I use the rising and falling edges of the Morse tone.
Critical to the architecture is (2) Sampling and Unit Timing. I will use the audio sampling rate, 8000 S/s, as my master clock. Edge detection will let me measure the time period of Morse elements accurately, as well as calculate the magic ratios for dits, dahs and periods of silence.
I will detect the keying state every 2.5 milliseconds, or every 20 samples. As you will see later, this is plenty fast enough to read Morse up to 50 WPM and beyond.
Morse Decoder Architecture Timing
As long as I can accurately detect pulses and measure their periods, I can create a queue to represent individual letters and spaces. From then on, I can use a lookup table to (3) Decode Elements, Characters and Words into plain text. The lookup table can do an exact translation, or find the nearest appropriate character.
So, that’s the basic Morse decoder architecture that can work for single channels, or indeed multiple channels concurrently.