I've decided to build an Arduino CW decoder (by Hjalmar Skovholm Hansen OZ1JHM) as I had spare parts lying around. The input circuitry was soldered on a piece of breadboard and tested "on wires". During tests I've noticed that my LCD had one fault - in the third row all symbols had 1 pixel offset upwards. That annoyed me a lot, so I've decided to redesign output from the Arduino board. Looking at the code I found out that the number of samples, averaging filter speed and lowest magnitude limit were hard-coded and I wanted ability to change them at runtime. So I've added three additional buttons - FN, DOWN (-) and UP (+). Final circuit looks like this:
I've packaged everything in a small plastic food container:
Operation is simple: number of samples is selected during boot, so if you don't hold any button n would be 64. If you hold DOWN button pressed while turning on decoder - number of samples would be 48, and if the button pressed is UP - decoder would capture 96 samples. This is denoted by letter b in LCD and shows input bandwidth in Hz. When all is set up decoder shows message Ready and waits until the button is depressed.
If you press UP or DOWN buttons while holding FN button - decoder will change speed of moving average filter which sets magnitude limit automatically. This should handle QSB situations a bit better. Filter speed is denoted by letter f in LCD and ranges from 1 to 15 (where 1 is the fastest).
At last - if you just press UP or DOWN buttons during runtime, you'll be setting up the lowest magnitude level, which is temporary displayed on the third row, while you are pressing the button. It will help your decoder to handle very weak or very loud signals better.
I've decided to use the faulty row as a visual level meter with visual threshold marks. This is how the finished project looks:
I also opted out a speaker as I don't need it, but you can uncomment lines in the code to bring it back. You can download my version of Arduino code here.