The last previous revision of my
Morse code trainer (first project described on this page)
relied on a Teensy 3.5 microcontroller. Unfortunately
the Teensy 3.5 is no longer manufactured and is out-of-stock at all the
usual places. You can get one on
eBay, but
might balk at the price! After sending my last Teensy 3.5
to a ham radio friend, I decided to port the
‘Mother of all Keyers’ (MOAK version 3) to the Teensy 4.1
platform.
This more advanced Teensy module
remains readily available as of May 2023. The software (firmware) port
was more challenging than anticipated,
but there were no insurmountable problems. When this effort was
finished I began
to reflect on Teensy 4.1 features. In particular, the Teensy 4.1
platform includes a
built-in real time clock (RTC) and an
on-board
micro SD card slot. Surely I should do something with these appealing
features. That is when inspiration struck.
Mother Lode ... is the name I
thought of to label an option that would exploit
Teensy 4.1’s
integral micro SD-slot.
The original MOAK had a pseudo-text option. Pseudo-text consists of
made up words, similar to English, but gibberish. MOAK
version 3 added the 1000
most common English words as a new code practice option. English words
were presented
randomly, roughly in proportion to their frequency
of occurrence in the language. Obviously, with a micro SD it would be
possible to store a massive amount of natural language text for Morse
practice. Whole
books could be stored, possibly whole libraries.
The micro SD cards I had previously
purchased or had seen on
store shelves were multi-gigabyte capacity. I
wondered if low capacity micro SD’s might be obtainable at
proportionately lower cost. Books in text format
require very little storage. The King James Bible consumes just over 4
MB as plain text, and most books take half or less this amount. As it
turns out small capacity micro SD cards are readily
available in multi-packs, where the cost works out to less than $2 per
unit. I purchased this 10-pack from Amazon.
Books: Thousands of
copyright-free books are available for download from Internet sources,
perhaps the
most prominent being Project Gutenberg. Many are classics—well known
titles. The first book I downloaded for micro SD card experimentation
was Moby
Dick.
Right away it was clear that some sort of repackaging would be needed
to facilitate using the book as a Morse practice source. The downloaded
file starts with about 20 lines of metadata, while another 350 lines of
copyright information and related material are appended to the end. The
Morse application code would need to find the start of the actual
book, and where the book proper ended.
Fortunately these locations are easily identified with the aid of
Notepad++ (and probably other text editors in common use). Simply place
the editor’s cursor on the
first and last characters of the book and read
their numeric character positions from the
status bar. These two numbers may be recorded on a separate line and
inserted before the beginning of the downloaded text
(first character
position, space, last character position). Upon
reading-in these values the program can compute exactly where the book
begins and ends, taking into account the length of the
inserted line.
There were a couple of other kinks. Morse does
not distinguish upper and lower case. The common part of Morse—the part
that ham operators routinely use—includes only a small subset of
punctuation. Furthermore,
UTF-8 characters are not translatable to Morse, as a general
rule. By good luck my first test download Moby
Dick was ASCII encoded. However, a couple of subsequent
downloads did not work at first because they were not plain
text. It is important to save downloaded books as unadorned
ASCII text encoding.
I went a step further, replacing selected none 7-bit ASCII characters.
For
example, I substituted double hyphens ‘--’ for dashes ‘–’. Maybe a
single Morse dash would be better. Of course, any edits that change the
character
count should be made before
pinpointing the start and end of the
book.
Clearly it is not desirable to start natural
language
listening practice in the middle of a word, or even in the middle of a
sentence. That is what happens when the excerpt is selected from a
random character position between the start and end of a book. Better
is
to find the beginning of a sentence and start from there. Once all this
was implemented and proven to work with the first example book, I
downloaded a few other test books. As
mentioned above, each had to be saved (in some instances re-encoded) as
plain text in order to
be useable in the desired way. Finally the microcontroller code
was generalized to choose a random book first, then a random spot
in the book, and finally to begin its practice transmission from the
beginning
of
the next sentence.1
Real-time clock:
Parts of this story will be told slightly out of order—I will fill in
the blanks later. As previously noted, Teensy 4.1 has an
integral real-time clock. A 3-volt button battery
(coin cell) suffices to maintain time when the Teensy is powered-off.
So the MOAK
could easily
be made to announce time in Morse. But how would the user request
the time? There
was no room for another button on the MOAK’s main options screen.
Furthermore, a Morse time announcement would be a short-duration phrase
at best, not worthy of a dedicated button. This dilemma, together
with a different unrelated concern, led to the keyed control sequence
idea. The Morse
stroke symbol ‘/’ (dash-dot-dot-dash-dot) is
used in ham radio to modify a callsign, usually
indicating that a
station
is operating in a different jurisdiction. However, I thought it would
be safe to overload the symbol’s meaning by insisting that a
two-character control sequence, consisting of stroke and another
character, be bounded by the space character on both ends. Keying ‘ /t
’
would request the MOAK to announce the time in
Morse.
Control sequences out the
yazoo: Once the control sequence concept was coded, then of
course other uses sprang to mind. One of these became the most
shameless of the MOAK-4’s soon-to-be-implemented features. But first I
made a much more useful enhancement—a change that had been requested by
a couple of Email correspondents who had built or used the MOAK.
Previously the sending practice options only worked with an
electronic key (paddle). These options could not be used with a
straight key.
Electronic key speed was set using a control in
the ‘More...’ options group. With a straight key it would be necessary
to detect the user’s actual keying speed and somehow match it. I had
previously experimented with this idea in another
project and sort-of knew what to do. After selecting the
‘Straight Key’ option, the user would key-in three letter V’s
(dot-dot-dot-dash). That
would enable the MOAK to detect the keying speed and decode
other characters keyed at a similar speed. This method worked better
than I
recalled it having worked in the JavaScript version from a few years
ago. I must have done something different now than then. In any case,
it occurred to me that if enabling straight-key character decoding in
the sending practice options, why not also enable it in the ‘Straight
Key’ option screen itself. That context could be used for free-form
sending
practice. The upshot was that in the options for selecting electronic
(paddle) or straight key, the user can key-in anything and have the
keyed-input echoed in those sub-screens. On exiting from either
electronic or straight key option, the type-of-key selection persists
so
that either straight key or paddle can be used for ‘Sending Practice’
or ‘Listen and
send’.
And that’s not all...
Eliza: This is where
the MOAK-4 project jumps the rails. Once keyed-characters were being
echoed in the type selection options, the effect was like sounding-out
or exhibiting one side of a conversation, perhaps not an
inappropriate complement to listening practice. On the other hand it
would be more interesting if the MOAK could reply to whatever was
being keyed. I had a momentary thought of interfacing the MOAK with an
AI chat bot, but best I can tell that would entail a subscription
service,
not an expensive one at Morse speed, but perhaps awkward to manage.
Then I
remembered Eliza. In the mid 1960’s
an MIT computer science professor named Joseph Weizenbaum2
came up with
Eliza. His creation was a parody (I think) of non-directive psychotherapy,
and a minor
sensation in its day. It is fair to say that
Eliza was the world’s
first chat bot, long before the term ‘chat bot’ had been invented. And
Weizenbaum is acclaimed as one of the founders of Artificial
Intelligence.
Conversation with Eliza is stilted—It would be so in
any language, but perhaps is even stranger in Morse. The demo video
linked at the bottom of this page includes a short sample. Eliza relies
on spotting keywords in its input text. This
part doesn’t work if the Morse is keyed imperfectly. Let’s say you mean
to key ‘dream’, but slip and key two dots instead of one for the letter
‘e’. Unlike Google, Eliza won’t
understand that ‘driam’ was meant to be ‘dream’.
Well, no harm or not much harm, because even with perfect keying, a
conversation with Eliza is not likely to sustain
interest for more than a few sentences. Although it should be said that
sometimes the combination of keyed text and Eliza’s response is quite
funny. In truth, though, implementing Eliza on the MOAK
was one of those things that could be done, and so it happened.
Another such ‘can be done therefore will
be’ came
about because even a ‘small’ 256 MB micro SD card has a lot of unused
space if only a handful of books are stored on it. The MOAK display
screen’s resolution is 320
× 240 pixels. Thus a full screen maximum
resolution bitmap image would consume less than 2 MB storage. I was
curious as to how to display images on the 3.2-inch TFT LCD screen (this one) and found a perfect tutorial with
example code here.
With this tutorial as a guide I was able to
display images from the SD card. Of course, this exercise has nothing
to do with Morse training, unless keying a Morse sequence to pop up a
random stored image could be considered instructive, but that would be
too long a stretch. I did consider making a photo-frame like
screensaver, but opted to adapt the Arduino TFT ‘bubbles’ demo
sketch
for this purpose instead.
Tech talk: The schematic above
shows connections between the Teensy 4.1 (large middle rectangle) and
the touch-screen (TFT SPI right), and also the LM386 sub-board. Below
is an outline of the corresponding Autodesk
Eagle circuit board. It is easier to visualize the Teensy-to-TFT
connections on the board illustration than in the schematic diagram.
One caution, as of this writing I have not had boards manufactured and
therefore have not tested this Eagle CAD rendering.
It is possible these illustrations might have errors. For
reference, it may be helpful to compare to the MOAK-3 (Teensy 3.5)
diagram and/or earlier Atmel MPU versions of the project. Also compare
pin numbers to those referenced in the Arduino IDE sketch. Note that
the tone output pin changed from DIO 8 in previous versions of the MOAK
to DIO 7 in this revision. Physical layout of
components is not critical. For the prototype I glued the coin-cell
battery clip to the left side (inside) of the 3D-printed enclosure.
Update:
(A few weeks later) I decided to go ahead and have boards made so that
I could verify (or not) the schematic. I don’t think it would be
possible to beat the price that JLCPCB
charges to manufacture small two-sided prototype boards: 5 boards for
$2. Shipping from China to eastern US via DHL (3 days) runs about $20.
When the boards were received I soldered female pin
headers for the Teensy and TFT onto one of them, and also soldered the
4.7K resistor that connects to the TFT’s
LED pin (#8). After confirming that the MOAK-4 splash screen and main
options menu displayed as expected and that touch also worked, I
soldered the audio filter components and a small header for the LM386
sub-assembly board, and another header for the LM386 Vcc jumper (lower
right edge in Autodesk Eagle board illustration). Finally, I connected
a Morse key paddle and tested all MOAK-4 options. Options worked as
designed and the sound quality was satisfactory.
In summary everything on
the board was tested except the 3 volts
RTC backup battery clip connection and the 5 volt regulator—main power was
supplied via USB. At
the time of designing the board I selected a 3v battery from a (Eagle)
SparkFun parts list, thinking I had one of that type on hand—should
have looked. That particular part is discontinued and I have not been
able to find a coin-cell clip with the same footprint. I will likely
solder a pair of wires (or pin headers) to the + and – holes on the
board, and test both the battery clip and
alternate 5-volt power supply (LM7805) later. (Later) Alas, an error—In the
upper left corner of the schematic above, there is no connection from
the alternate power supply ground to the main circuit ground (Teensy
and LM386 sub-board). The missing connection has been added and
highlighted in the clip from the schematic on the right. The omission
was easily remedied by routing a wire underneath the PCB from the
middle pin of the LM7805 to a nearby main circuit ground point.
The paragraph
following this one will include a link to the MOAK-4 control program
(sketch and data) as well as other construction details. One of the
differences between
the MOAK-3 (Teensy 3.5) and MOAK-4 (Teensy 4.1) implementations is that
the former relied on the simple-to-use UTouch.h library while the
latter substitutes the XPT2046_Touchscreen.h library. Display and touch
are separate
physical devices with separate serial interfaces. (In this project the
two SPI interfaces share the same clock.) Touch point coordinate values
returned by the XPT2046 replacement library occupy a different range
than those
returned by Utouch.h. The latter covered the same numeric range as the
display
screen’s pixel coordinates.
At first I thought it would be necessary to re-do the constants
that define touch component boundaries, but then realized it would be
simpler to translate the new range to the old one. To this end I
recorded many touch data points and performed linear regressions.
(Data points were transmitted automatically over USB
virtual serial to the desktop computer for this analysis.) Thus, touch
points are
converted at the lowest level to quasi-pixel coordinates. The numeric
constants that specify component dimensions and touch-region boundaries
remain unchanged.
To summarize, application firmware consists of a
Teensy 4.1 compatible c++
(Arduino IDE) sketch and four data files, three of these the same as in
MOAK-3, and the fourth supporting Eliza. MOAK-4.1.7.zip
contents should be
extracted to the same structure as the zip archive has: sketch plus
sub-folder named ‘Data’, containing the .c extension #include files
referenced in the sketch. [Note: The following paragraph has links to an updated version of the application.] Physical circuit construction is simpler than
for
previous
versions of the MOAK. The external keying circuit is omitted (level
converter and relay). In place of assembling the audio amplifier
from discrete components I have substituted an LM386 sub-board. This inexpensive module
plugs
into a female pin-header (4-pins) on the MOAK circuit board. Another
simplification was to remove support for the two or four-row
character cell LCD. Touch screens are inexpensive—less than the
combined cost of the character-only display and physical buttons that
they replace. And the larger
screen geometry is advantageous when sentence- or
paragraph-length
natural language text is chosen for Morse listening practice. Finally
it might be noted
that Teensy 4.1 analog and digital pins are not 5 volt tolerant. This
should not pose a problem as the SPI interface operates on 3 volts and
no
external 5 volt signal connects to the Teensy in this application.
Iambic Keying:
I am indebted to Tom NL7WK for letting me know that the MOAK as
described in the preceding paragraphs did not respect iambic keying. I
did not know what iambic keying was, although as it happens I have an
iambic key (in addition to the old Vibroplex that I am more comforable
with). The MOAK code has now been modified to support iambic
keying as well as single-lever paddle keying, and straight keying.
Since some time has elapsed since MOAK version 4.1 was posted, one or
two other ‘enhancements’ have found their way into the code, and are
summaraized in the next paragraph. The current revision may be
downloaded either as a zip of source code and data MOAK_4.2.3.zip or in compiled form MOAK_4.2.3.ino.hex. The compiled version may be uploaded directly to Teensy 4.1 using the Teensy Loader Program for Windows from PJRC. The latter method does not require the Arduino IDE. It is a simple step-by-step procedure.
In addition to support for iambic keying, version
4.2.2 includes scoring for the practice sending options. This feature
may be toggled on or off using the control sequence ‘/G’ (for graphs).
Key the control sequence in either the Electronic Key or Straight Key
option, then proceed to the sending practice option (shortcut ‘/8’ or
‘/9’). —A more whimsical new option is the coin toss. Key-in ‘/B’ (for
binary) for a pseudo-random heads or tails in Morse, along with an
image of the coin. This admittedly strange feature was inspired by my Geiger Counter project
of a few years ago. The video demo below shows key features of MOAK
version 4, but does not illustrate iambic keying or other more recent
features.
Demo video: MOAK-4 What’s new?
1. Strictly speaking if the recorded starting
position value corresponds to the first
character of the book, the ‘go-to start of next sentence’ logic will
bypass the first sentence, should it ever be hit upon randomly. We
will never hear, “Call me Ishmael” in Morse. But let’s
not be picky.
2. Joseph Weizenbaum photo courtesy of
Wikimedia.
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.