Mother of All Keyers

    Update May 2023 - The MOAK has been ported to Teensy 4.1 with new and enhanced options. MOAK V4 introduces full support for straight key sending practice and an option called ‘The Mother Load’. See this page for details, including the revised sketch (program with data) and schematic.

    MOAK: My first Arduino exercise was a Morse code sender. Later I reconstructed a sine wave oscillator circuit on an Arduino prototyping shield, and integrated this with the original exercise (details here and in this follow-up paragraph). By all rights that should have been the end of it. However, two trains of thought led to the present extension. First I wanted the ‘sender’ to generate practice text that was more like ordinary language than random five-character groups. Second, I thought the device should include a keyer function. These ideas led to others, and when I told N4EFS about the project she came up with the name, “Mother of All Keyers” (MOAK for short).

    The name is a joke, of course. Physical components of the MOAK are the same as those commonly found in other keyers, for example, the audio oscillator (
QST, February 2017, pages 46-47). [Other sidetone generating circuits would have worked as well, but this one was ready to use.] There is not much else, after the Arduino and oscillator, just the LCD and input/output support. The only unusual aspect of this keyer is its control program (MOAK Arduino sketch), which implements a unique mix of options.

Default startup optionSpeed Adjustment    On startup, the device displays a splash screen for five seconds, followed by ‘Electronic Key’ (the first option), and finally the current speed setting. The screen then goes dark. It is dark for the ‘Electronic Key’ and ‘Straight Key’ options and illuminated for other options. The left button on top of the enclosure is the ‘Option’ button and right is ‘Select’ in the prototype. Pressing the ‘Option’ button steps through the option list and pressing ‘Select’ enters (or enables) the currently displayed option. Pressing the ‘Option’ button while running an option returns to the ‘Current option’ display, from which point the same or another option may be selected.

    A straight key or paddle may be plugged into the front panel jack (lower right in the prototype). Connections are standard for a right-hand paddle (iambic key). The ‘Straight key’ function uses the dash side of the key. The speed potentiometer knob on the front changes speed within a pre-determined range of approximately 5 to 35 words per minute. (Full disclosure: The upper end of this range has not been exercised.)

Block Diagram with Pin Numbers

Debounce circuits    The block diagram illustrates main components and their interconnections. Pushbutton debounce circuits, each consisting of a pullup resistor plus an RC and Schmitt trigger, came from this useful article. These were constructed on a small generic circuit board (photo right). The front panel speed control, a 10K potentiometer, divides the Arduino’s 5 volt DC supply. Its wiper connects to an analog pin (A1 in the sketch). The assignment of connecting pins is largely arbitrary and different pins could be used, except that analog pins A4 and A5 are defaults in the LCD serial communications support library. The choice of D13 for transmit-out produced an amusing side effect. Since D13 is the on-board LED indicator pin, the letters ‘H’ and ‘E’ sound on power up (4 blinks, then 1). When loading a sketch from the IDE, ‘H’ signals the beginning of the load and ‘E’ signals completion.
    Nine currently coded options are listed and explained more fully in MOAK_User_Guide.pdf. Two of these options, 5-letter groups and 5-alphanumeric groups were inherited from the original project. The rest are new.

Pseudo-text Option    Random pseudo-text is gibberish that is similar to English—many of the ‘words’ are pronounceable. Pseudo-text options were especially fun to construct, as they required a bit of background study. Some time ago I had played with the British National Corpus (BNC), a very large sample (or collection of samples) of written and spoken English. At that time I excerpted the XML edition of the BNC to a database, and indexed the data this way and that, with a view to doing something interesting with it—don’t know what exactly. For the present project I computed a few simple statistics from this subset of the BNC, and combined these with intuitive guesses to create pseudo-text generating rules. These rules, embodied as arrays and values near the top of the sketch, influence the form of the text generated. As such, they may be modified experimentally to produce different flavors of generated text.

    Arduino’s pseudo random number generator behaved in an unexpected way. Documentation for the randomSeed() method suggests using an analogRead() of an unconnected pin. I tried this, but kept seeing the same ‘random’ sequences on repeating the same option after a restart. Analog port readings produce integer values ranging from 0 to 210 − 1. However, the port’s unconnected input voltage doesn’t exactly roam over the 10-bit range. Perhaps with a noise source attached it would. Eventually I substituted a button press as the seed. The millis() function returns an unsigned long, which matches the seed parameter. After making this change, repeating sequences were no longer observed.

Send practice Option   
The idea of incorporating sending practice came from a ‘CW Trainer’ application designed by Tom Lewis N4TL ( In the ‘Sending Practice’ option, the LCD screen displays a string (generated by one of the listening practice options). To practice, a person keys-in the displayed string. Each correctly keyed character gets echoed (as lowercase), while incorrectly keyed characters are echoed in the way the program interprets them, or as ‘*’ if not a recognized Morse character. The ‘Listen and Send’ option is similar, except that the practice text to be keyed is not only displayed but also sounded out. One may attempt to reproduce the characters as they were heard, in addition to relying on memorized dot-dash sequences. Sending practice options require the use of a paddle—the program cannot decode characters that are keyed-in with a straight key.


Packaging of Components

    Packaging: The prototype enclosure is a plastic box, approximately 8-inches wide by 4-inches high and 2-1/2 inches deep. The Arduino and small PCB are held more-or-less in place using long #2 machine screws and nuts. A short USB-B jumper conveys power from outside the box to the Arduino (and everything else). Point-to-point wiring is the usual rat’s nest, due in part to the fact that most of the wire I have is springy stuff. —I must purchase soft wire for the next project!

    A 16 x 2 LCD may be substituted for the 20 x 4 display shown in accompanying photos. It should only be necessary to edit the ROWS and COLS constants near the top of the sketch. Option names were chosen to fit the smaller display. Similarly, functions that support scrolling were coded to adjust automatically for either display size.

    The inside-the-box sidetone generator can be omitted. The only components that are required to produce the same functionality as the MOAK are the Arduino, LCD display, and option navigation buttons—and of course, the sketch. If features are added in the future, I will post a revised sketch.

    MOAK demo: moak.mp4

Speed adjustment mode    Addendum: The procedure for changing speed was a little awkward. This revised sketch includes a new speed adjustment mode. In this mode the LCD displays current speed in words per minute, as the speed knob is being turned. To enter this mode, press the ‘Select’ button from within any option except sending practice options. In other words, press ‘Select’ instead of the ‘Option’ button. Once a desired speed has been specified, press ‘Select’ again to return to normal operation. The User Guide has been updated to reflect this change. The revised sketch incorporates a few other ‘invisible’ changes, to improve efficiency and anticipate possible future enhancements.

    Addendum: This revised sketch includes a semi-automatic key (bug) emulation option.  See my YouTube demo for additional information.

NetMOAK Java Application

    Yet another addendum: An article in CQ magazine (“Learning CW at 70, by Words - Like a Child” by Nizar Mullani K0NM, September 2018. pp. 38-40) inspired this add-on project. The concept of learning the Morse sound of words (or even phrases) seemed analogous to how one would learn a spoken language. Intuitively this approach could be more effective than memorizing letter sounds.

    The MOAK sketch described in preceding paragraphs consumes approximately 50% of the Arduino Uno’s program storage, and 60% of its scarce dynamic memory. It is possible to interface an SD card with Arduino (, and at one point I considered this option. Then I thought why not implement the word training concept as a stand-alone computer application.

    Initial experiments using the NetBeans platform were disappointing. Keying a program-generated tone on and off at slow speeds worked okay, but as the off-duration was shortened, tone quality worsened (prominent clicks) and timing became erratic. No doubt these problems could have been resolved with patience.

    At this point a lazy and rather obvious solution presented itself, namely to use the computer for storing and managing ‘words’ (training terms or strings), while leveraging MOAK to generate Morse characters and switch the tone oscillator. The challenge with this approach would be to implement communication between the computer and Arduino. I had previously experimented with a serial COM package called RXTX in connection with interfacing an amateur radio transceiver. So this problem was more-or-less in hand.

    I decided to name the application NetMOAK, reflecting the project’s hybrid NetBeans + Arduino MOAK structure. A detailed description, including download links for the revised Arduino sketch and NetBeans (Java) application, as well as installation and usage instructions may be found here. It would add nothing to repeat details in this summary. For an example of usage please see the video demo below.

    NetMOAK demo: netmoak.mp4

    Redesign and Simplification: According to YouTube view count statistics, the ‘Mother of All Keyers’ is among the least interesting of my projects. Yet for me it has been one of the most instructive. Along and along I came to realize that the Arduino Uno and tone oscillator shield could be replaced with a bare ATmega328 microcontroller. In part this realization was inspired by a reference to the Arduino tone(pin, frequency) function that I had noticed while examining an unrelated sketch.

    Arduino tone() outputs a square wave to a DIO pin at a specified audio frequency. (Duration is an optional parameter.) Would it be possible to produce a more listenable sound by smoothing the waveform? To be satisfactory in the present context, a smoothing circuit would need to be simpler than the oscillator, otherwise there would be little point in replacing the latter. This instructive article suggested a plausible answer. As the article advises I experimented with component values suitable for smoothing in the 200 Hz to 1200 Hz range. The resulting filtered tone resembles a sine wave near the middle of the selected range, and is pleasing to the ear.

    Another factor contributing to my interest in a redesign was the wish to have some practice using the open source KiCad electronics design software. I had worked through the beginner’s tutorial here, and wanted to try creating a schematic with more components and connections. So at this stage I began to draw a plan for reproducing the functionality of NetMOAK, but without the Arduino Uno or its attached tone oscillator shield.

MOAK redesign without Arduino or oscillator
    The revised design includes a potentiometer to adjust the ATmega328-generated tone’s pitch (component RV1 in the diagram). The circuit also includes an audio amplifier (op amp U2), capable of driving a speaker. However, since there is no external oscillator to switch, the redesign dispenses with the 4016 analog switch, instead operating the small transmit relay directly from the assigned digital output pin (D13). These additions and changes necessitated only minor revisions of the sketch (version 2).

    Initially I had no thought of actually constructing this circuit, as the original MOAK is still fully functional, and in an enclosure that hides the mess, but curiosity as to whether the revised design would work got the better of me. Briefly I considered a custom PCB, but abandoned that idea as too ambitious. Instead I fetched an old Radio Shack generic board from the miscellaneous bin and began to solder sockets. All small electronic parts needed for the circuit were also on hand.

    Before starting, I thought it would be good to have additional ATmega chips on hand in case one of them bit the dust—as of this writing that has happened only once, and it was a physical misadventure (in another project) where chip pins came in contact with a 12-volt battery. On-line articles about programming the ATmega328 refer to burning a bootloader, and how this can be done with an Arduino, using software serial for linking to the target chip. Anticipating this step, I constructed a simple accessory board with DIP socket and crystal etc. to accommodate the raw microcontroller,  But then, when it came time to order chips, all that I found for quick delivery had the bootloader pre-installed. No doubt it is possible to purchase chips without the bootloader, perhaps in quantity, but for small projects such as mine, that would not be necessary.

MOAK version 2 + USB

    The photo shows the finished board connected to the NetMOAK computer application via USB (lower left). I will return to that feature’s implementation in a moment. The board has headers for each attachment, LCD, option button, select button, key jack, transmit jack, speed pot, tone pot, headphones jack, speaker, power, serial I/O, and reset. I’m probably forgetting something. Smoothed tone output (lower right) and amplifier input (upper middle) also have headers. A short jumper between them enables the amplifier, if it is needed. Layout-wise the microcontroller is on the lower middle left (obviously), with the Schmitt trigger chip above it on the left, and op amp near the top. Power can be supplied via a USB-serial cable if connected, or a separate header (upper left).  There is a pin for supplying more than 5 volts to the op amp, if desired. Smoothing filter capacitors are at the bottom center right.

Arduino Uno U2    The business of programming an ATmega328 for standalone use led to a few instructive observations. Initially I used an Arduino Uno for programming, and after the sketch was loaded, moved the microcontroller chip from the Uno to the project PCB. Later I learned of a way to reprogram the chip without having to remove it from the project board for plugging into the Arduino. All that is needed is a USB-to-serial adapter, a confusing variety of which exist. The Arduino itself is essentially a microcontroller development kit with integral USB-to-serial capability (photo). For repeatedly reprogramming an ATmega328 it would be more efficient to configure a means for updating the chip in-circuit. However, for the present project, there was little to do, as the program needed only minor additions for the tone oscillator replacement. (After completing this code revision, I thought of a possible future project that would entail loading and testing multiple iterations of an unrelated sketch.)

    The particular type of USB-to-serial cable that I purchased (3-pack from Amazon) has an embedded PL2303 chipset. Windows 7 automatically loaded a driver. At first I was concerned that it might be the wrong driver, but on starting the NetMOAK application with the USB-to-serial cable connected to the microcontroller (photo above), the application’s port selection box listed the COM port. Oddly, it was necessary to start the program, then close and restart it after first plugging in the USB cable, in order for the program to detect the port.

    Two of the three cables worked—one was a dud. And rather to my surprise the program successfully communicated with the new MOAK board. The computer end was able to adjust MOAK speed and to process the usual practice data through the device. Initially I exercised the application interface for an hour or so, and afterward tested several startup connect cycles. Over the next couple of days I performed more exhaustive testing.

    Data from the computer application to the board were always received and processed, the same as if the microcontroller were interfaced via the Atmel chip (U2 on Arduino Uno). However, microcontroller acknowledgments were not reliably received by the computer application, when using either of the functional PL2303 cables. Whereas, when connected via the Atmel chip, acknowledgments were always received. I don't yet know why acknowledgments are not reliably received with the store-bought cable. To solve this will require additional study, perhaps using Termite to send/receive data manually. For now, not receiving acknowledgements has little practical effect. Unless logging is enabled the only noticeable consequence is that unlinking does not change the ‘Link’ button color—the NetMOAK application does not detect that it has been unlinked, and must be restarted for the next session.

    I have ordered a USB-to-TTL cable that claims an FTDI chipset, and compatibility with wireless Arduino
—report to follow.

USB-to-serial Package Label    The cable works: The second cable that I purchased (Amazon Prime) cost $7.99, whereas the previous one was $9.99 divided by 3. More importantly, the new cable with its claimed FTDI chipset works reliably. Using this cable, the NetMOAK computer application communicates with the ATmega328 for both Tx and Rx. Thus, the MOAK can be linked and unlinked repeatedly when connected—The ‘Link MOAK’ button color correctly reflects link status. Additionally, when the application log is enabled, acknowledgements from the microcontroller can be viewed in the Logs text area. 

Projects Home

Project descriptions on this page are intended for entertainment only. The author makes no claim as to the accuracy or completeness of the information presented. In no event will the author be liable for any damages, lost effort, inability to carry out a similar project, or to reproduce a claimed result, or anything else relating to a decision to use the information on this page.