# How to decode morse code with digital logic

I have been curious as to how one might implement a morse code decoder with basic digital logic (no microcontroller), mostly as an exercise. I could decode individual letters with a state machine, if I had asynchronous inputs such as dot, dash, and pause. My problem is essentially in generating those outputs from a raw source like a telegraph key.

Is there a good circuit that can detect when a signal goes high for a certain amount of time? I would need it to send one signal when it is up for a short time and then goes low, and another signal when it stays up longer (three time periods for a dash vs one for a dot). I also need a signal when it stays low for three periods for a letter break, or around seven units for a word break. It needs to be fairly liberal with its timings, as it is intended to decode manual entry, not computer modulation.

It would be super nice if it used minimal components and if I could use a potentiometer to adjust the time period.

• I'm afraid that the simplest way to do this from discrete parts is to build a CPU. Mar 16, 2012 at 17:18

There were some hobbyist experiments (in the early '80s, I believe) with decoding variable speed digital data with the intent of being able to distribute code to accompany magazine articles by printing it as bar-codes. The reader (person, not machine) could then scan it into their machine with a hand-held scanner. It was assumed impractical (until shown otherwise) due one's inability to hand-scan at a uniform speed.

The solution ended up being for the decoder program to initially collect enough white-black to black-white transition times to discover the mean wide-bar and narrow-bar times, assign '1's and '0's, respectively, to the collected data, and continue decoding the incoming stream while simultaneously updating the wide-bar and narrow-bar mean times to account for changes in the wand speed over the bars.

The same technique was applied to decoding hand-sent Morse off the air, with a simple circuit going high and low with the receiver's audio output, fed to a similar algorithm.

As an aside, an interesting issue came up when the words 'T5' or '6E' appeared frequently in the decoded text. Operators naturally developed keying habits on common words, and would key (and understand) f/ex, the word 'the',

Dah - dit dit dit dit - dit

as

Dahdididididit,

which the decoding algorithm, doing its best with slightly uneven element spacing and a result string that didn't match any known Morse character, got one of the above digraphs.

You might find some of the articles in early issues of Byte Magazine at the library.

• Magnetic stripe readers (such as point-of-sale device that reads credit card at checkout) also have to decode at a variable rate, as people don't always swipe their card at the same speed. Might be good for additional reference info although they were already using a microcontroller 20 years ago. Mar 16, 2012 at 17:55

Decoding Morse sent manually using a key without using an MCU will require so much hardware that it isn't really feasible. How will you deal with varying speeds, and inaccurate dot and dash timings? How will you implement the lookup table? What about the output device?

• I agree. It is probably impractical to do in hardware. I know it can be done fairly straightforward in an mcu, but I am curious as to how this sort of thing could be done with more basic elements. I don't think its too infeasible for a simulation or an fpga. Mar 16, 2012 at 16:52
• It could be done on an FPGA, of course, but it will involve a great deal of work. Mar 16, 2012 at 17:12

One major problem with decoding Morse Code in hardware, as compared with e.g. barcode or magstripe data, is that the latter are designed to be machine readable and thus have "preambles" with a known pattern of long and short pulses, allowing hardware to determine what constitutes a "long" or "short" pulse before any actual data arrives. For example, 4-bit mag-stripe data is written using long and short pulses, and has IIRC a minimum of ten short pulses at the start; further, there will never be more than nine long pulses in a row. Thus, if the reader sees a pulse that's less than 75% the length of the previous one, it's short; if it's more than 150% the length of the previous one, it's long. If it's 75%-150% the length of the previous one, it should be categorized the same way as the previous one, unless the previous nine pulses have all been categorized as long, in which case it should be considered short, and any partially-decoded data should be considered erroneous.

Is there a good circuit that can detect when a signal goes high for a certain amount of time?

Perhaps the simplest circuit for distinguishing "long" vs "short" pulses uses a Camenzind 555 timer ICs in something like a "missing pulse detect" circuit. a b c d

In principle, if I had to decode Morse code without a MCU, I might start with one 555 timer circuit that pulsed on long "dah" pulses (but not on short "dit") pulses, another 555 timer circuit that pulses on long between-letter pulses (but not on short pulses between the dits and dots inside a letter), and similar circuits for letter break and word break. Such circuits are pretty easy to tune with a potentiometer, but kind of difficult to automatically adapt to changing speed of transmission.

As others have pointed out, it would take far less hardware to decode Morse code on something like an Arduino. e

It would take even less hardware than that to transmit a Morse code message. (Perhaps with a 555 used as a dot-rate timer and a few CD4017 counters used as a sequencer. Then a diode on each pin for time periods of dot or dash; nothing attached to pins corresponding with space times. These chips can run off a 9V battery without even a voltage regulator).