CW Messenger: A New Project

I came across a book, Microcontroller Projects for Amateur Radio, that has a number of interesting projects that may interest some of you.

Microcontroller Projects for Amateur Radio by Jack Purdum

Chapter 10 covers a CW memory keyer (one down from the top on the left). I decided to put testing of the S-Pixie transmitter on hold to start this project. It should help me with that testing.

The “CW Messenger“, as it’s called in the book, looks like a quick build. At this point though, I can’t wholeheartedly recommend it or the book, especially for those who like their projects completely documented. For example, the project doesn’t have a BOM, the schematic has several components without a value specified, and the support website, on, isn’t the best for finding more information on the projects.

Frustratingly, it took me about half a day to find the software for this project! You’d think the link would be provided in the book or in a FAQ on the website. Nope. You need to search through user messages for someone who asked the question about where the software was located. Then you had to search through files for a file uploaded on a specific date and hope that it hadn’t been updated since the question was asked. Then you had to wonder some more when you come across a message where the book’s author appears confused about the number of the latest version of the software.

On the positive side, the book’s author seems active on the site, though his responses to questions come across as snarky at times. Also, several of the projects, including this one, have lengthy threads where users have discussed their build. I’m hoping that reading through these will help me overcome some of the limitations in the book’s documentation.

If the project pans out, I’ll provide information here that hopefully will aid future builders.

CW Messenger: BOM

Here is a preliminary BOM for my version of the CW Messenger. The biggest differences from the project in the book are that I’m using a 2.8″ display rather than a 2.4″ one and (2) my case is off-the-shelf rather than 3D printed and is a different size. The total price for the project, sourced from Mouser is about $81. You can save some money with alternate sourcing. I’ve indicated volume discounts for a few components which may be attractive if you plan to build more projects.

Item DescriptionPart #PriceComments
U2TFT LCD DisplayDFR0665$24.902.8″ LCD; book uses 2.4″
U3Voltage RegulatorL7805CV$0.69
U4Optocoupler4N25$0.6010 @ $3.68
U5Rotary EncoderPEC11R-4230K-S0024$2.16
Q1NPN Transistor2N3904$0.4210 @ $1.40
D1Reverse Polarity DiodeBAT48$0.47SCHR msg #21252. I used a Schottky diode
R1PotentiometerPDB181-B225K-503B$1.52select as needed by buzzer; 50k here, text suggests 75k for loud buzzer; SCHR msg #21252 indicates `10k?`
C1, C2100 uFRGA101M1EBK-0611G$0.12value from SCHR msg #21252
C310 uF667-EEA-GA1E100H$0.28value from SCHR msg #21252; 10 @ $1.27
S1, S2, S3Pushbutton SwitchPS1024AT-BLK$1.42
S4Toggle Switch2M1-SP1-T1-B1-M1Q$2.33
J1, J2JackSJ5-43502PM$2.504 position, wire per schematic
Knobs1227-L$1.69need 2
DC Power JackPJ-005A$2.54
Socket[1-2199298-1$0.2610 @ $1.69
CW Messenger BOM


  • Parts # reflect manufacturer’s number as listed by Mouser.
  • Pricing as of 7/4/2023.
  • Other size cases may work as well. I may make mine a handheld using with CM5-200 or CM5-125.
  • Other items needed: wire, display and protoboard mounting hardware.

7/29/2023 Update: The buzzer above requires an external source to buzz, something the CW Messenger doesn’t provide. As is it only clicks, and poorly at that. You’ll either want to replace this with an actual buzzer or wait to see what I do. Hint: I’m hoping to utilize the buzzer specified above by incorporating some software from the author’s Morse Code Tutor project.

Delivery from Mouser! – Time to get prototyping

CW Messenger parts awaiting testing/assembly

Not much to the CW Messenger. I’m going to build up a prototype this weekend and dive into the software. That’s where most people seem to have problems. Crossing my fingers that all the wrinkles have been ironed out.

Parts Testing

The Display

I haven’t worked with the Arduino IDE for a couple of years and since previous builders have reported issues with getting the CW Messenger software working on their builds, I wanted to verify that my display and ESP32 board were working properly before moving on to testing the CW Messenger software. I followed the Getting Started tutorial for the DFRobot display on an old SparkFun Inventor’s Kit I had laying around. No luck. I just got a white screen. Not knowing if the problem was with the old Arduino clone, the DFRobot software or my header soldering, I tried again on an Adafruit display that ordered as a backup. This time I used a more recent Arduino Mega clone.

After adding a few Adafruit libraries to my Arduino IDE, the Adafruit display went through it’s paces without problem. Good. If all else failed I could at least use the Adafruit display in the CW Messenger.

I then tried the DFRobot display with the Adafruit Getting Started tutorial. Now these displays are rather generic but given that they are “branded” I didn’t know if their respective companies had customized them in some way that would make them incompatible with other display libraries. Translating the Adafruit display pinout to the DFRobot display, I attached it to the Arduino Mega and fired it up.


DFRobot display test

Given that I was about a half day in at this point (with header soldering, software updates and what not) I decided not to pause to find out where the problem was with the previous setup, though I’m guessing it was software related. I move on to testing the current official version of the C Messenger software. There are a number of somewhat poorly documented, fiddly steps that need to be taken here, such as installing 3rd party libraries in various states of development since the writing of the book and making changes to them, any of which could possibly lead to failure. At least here you have some feedback from the IDE when the program doesn’t compile. Resolving many issue, which I’ll document elsewhere, I finally was able to compile and upload the CW Messenger program to the ESP32 development board. I was hopeful, but given other builder’s experience, I wasn’t much surprised, but still disappointed none the less, when on firing up the development board I just got a blank white screen.

Now I hadn’t separately tested the ESP32 development board. Stepping back, I loaded up one of the development board’s example programs and attempted to get an LED attached to pin 21 to blink. No luck, the LED was dark. It was a very simple sketch, so what could be the problem. Maybe I didn’t have the correct board selected in the Arduino IDE. This is always a cause of frustration for me.

After a bit of googling, I noticed that one tutorial showed the LED connected directly between pin 21 on the development board and ground. Interesting. I had put a 330 ohm resistor in line with the LED, as I’ve done with other blinky LED experiments in the past. Removing the resistor solved the problem. I guess the development board output pins at 3.3 volts were insufficient to drive the LED with the resistor I was using.

Having verified that the ESP32 development board was working and that I could successfully interface it to the Arduino IDE (actually several different board selections all worked), I moved back to the problem at hand, getting the CW Messenger software up and running.

There are at least two other versions of the CW Messenger software posted in various messages (not the Files section) of the book’s website. I tried each of these in turn without success, though the most recent posting (still from almost two years ago), did blink the display once or twice before showing the blank white screen. Like some others, I was starting to get frustrated.

I decided to pull out an old laptop, wipe Arduino off of it and install an old version that was around when the last unofficial version of the software was posted. I also installed the version of the libraries that poster had used (or was active at that time since in one case the version number appeared incorrect). This proved successful.

CW Messenger software test

Apparently IDE and library changes over time break the CW Messenger program. I don’t have enough experience with the Arduino environment to know if this is common. If it is, you’d think the book’s author would mention it and more carefully document what versions are needed to run his software.

So it took me about a day to get the CW Messenger software running. I had hoped to have a completed prototype in that time, but still I’m happy to have gotten this far. I’m guessing others gave up. Its interesting that the version of the software I got working was modified, with some difficulty it seems, to work with the IDE and library version of the time. I’d have though the more simple path of changing the IDE and library versions to the last know working versions, like I did, was a better starting point, especially given all of the other uncertainties in getting 3rd party software to work. One can then update the IDE/libraries one at a time to systematically track down any problems introduced by the change. But maybe that’s more work when jumping into the middle of a project and just wanting to get to the end of it.

I haven’t tracked down the problem with newer versions yet. I plan to go back to the beginning with the latest official version of the software, with an IDE and libraries available at that time. I hope to trace through the various changes needed as the IDE and libraries were updated. Probably a waste of time, but it should help me become more familiar with the CW Messenger software and the Arduino IDE. Not a total waste if I do more of these types of projects.

The Rotary Encoder

You’d think that wiring up a mechanical rotary encoder would be easy. At least I did. Come on, the one I’m using for my CW Messenger project only has 5 pins, and two of those are for the switch!

I knew the basic functionality of a rotary encoder and have taken apart an optical one so I wasn’t a total noob, but I was puzzled on how to hook up my mechanical encoder. The datasheet obviously assumed more familiarity with encoders that I possessed. As such, I decided to do some testing on the rotary encoder before I moved on to the breadboard prototype of the CW Messenger.

I connected my encoder to the ESP32 development board, following, as best as I could, the project schematic and encoder datasheet. Neither were particularly helpful. The schematic referred to an unspecified encoder (searching, it appears to be similar to this one) and I couldn’t glean much more from the datasheet for the encoder I was using. Needless to say, it didn’t work. The CW Messenger program continually reset, though honestly I’m not sure that was solely due to attaching the encoder because when I removed it the program continued on resetting, even after cycling the power.

After getting a little education from google, I did a little test of my own to verify the encoder was working properly. The key, at least for my encoder, the switch is just a simple two terminal, momentary contact, switch, as shown in the datasheet.

Rotary encoder testing

With more than a little bit of fiddling, I was in business.

One thing that puzzled me was how the switch fit in. I also misread the datasheet, thinking the encoder terminals were A, B, C in that order on the encoder. They’re actually, A, C, B. Since the C terminal is common, this makes a big difference.

Once I had the basics down, getting good traces was a simple matter of turning the encoder!

Rotary Encoder – clockwise rotation
Rotary Encoder – counter-clockwise rotation

Well, actually a bit more fiddling than that. But let’s leave some mystery!


Comparing the working version of the CW Messenger software to the author’s latest official version I noted that the author’s version had ESP32 development board pin assignments different than those noted in the schematic. No wonder I couldn’t get the official version of the software running. The working version of the software had edited these to be consistent with the schematic.

Given these types of errors, I don’t think it’s worth tracking down the history of IDE and library version changes over time. I’ve got a working version of the software and I’ll move on from here. I’ve uploaded the working version of the software to my GitHub.