Andy Fletcher Homebrew

CW Decoder

I came across a CW Decoder based on an Arduino Uno implementing the Goertzel algorithm, and have lashed together a prototype which works quite well.

The CW Decoder circuit and code come from Hjalmar, OZ1JHM and are described in his web page A VERY simpel CW decoder EASY BUILD. Thanks Hjalmar!

The Goertzel algorithm does much the same as an FFT but in a more efficient way. It gets its efficiency by only working for various fixed tones rather than a continuous frequency spectrum as in the FFT.

I’ve not modified the circuit in any way as I can fiddle with the controls on my TS590-S transceiver to get the decoder to work. As I write, we’re in horrible HF conditions at the moment with poor propagation. Even so, the decoder has decoded plenty of signals even when drowned in HF mush. The noise reduction on the TS590-S is needed to allow this, and with NR2=20, fast AGC and reasonably keyed morse it does pretty well. I use the 744Hz tone in the algorithm and a bandwidth of 140Hz. This allows me to use a sidetone of 750Hz and a 150Hz filter on the transceiver. The decoding quality starts falling off as the CW speed rises above 30 WPM but it’s still usable. I’m using an LCD of 4 lines of 20 characters which works well.

Screenshot of CW Decoder Prototype
Screenshot of CW Decoder Prototype

I instrumented the code to see where it was using up CPU as Hjalmar hints that you can’t reduce the tone bandwidth too far. As reducing the bandwidth is done by iterating more in the algorithm I suspected this was the bottleneck. But it was actually the display to LCD which took much of the time. So I changed the code to use the LiquidCrystalFast library rather than the bog-standard LiquidCrystal library. This almosts halves the time taken to write to the screen. I also changed the ADC registers to speed up reading from the analogue pin, but this had little effect. I also let the code work with an Arduino Due which has a faster CPU than the Arduino Uno. This allows more lee-way in the Goertzel algorithm.

I also added a LCD tuning aid – you can see this in the photo. The number of > chars increases with the accuracy of the tuning. I find this more useful than watching the LED blink.

Screenshot of completed project
Screenshot of completed project

For the completed decoder I changed to an LCD shield. It happens to have buttons on it so I added some configuration using these buttons. At start-up the ‘N’ in the Goertzel algorithm and the expected amplitude of the signal can be changed. This can help if conditions change and signals become very weak or very strong. I set the default ‘N’ to 48 and the default magnitude to 20. The magnitude default suits the ACC2 output of my TS–590. The completed project just has a 3.5mm jack socket hot-glued to the Arduino and connected to the ground and A1 pins.

The code is here and has details of the buttons to press during configuration.