Picture of Arduino Morse Code Shield
Morse code was the breakthrough that made possible long-distance
communication in the era of the telegraph. The code represents
alphanumeric characters by short and long intervals of signal -- those
familiar dots and dashes. For many years passing a Morse code test was a
prerequisite of getting a Ham license, but nowadays most radio amateurs
use it only infrequently. No longer are ship-to-ship distress signals
sent in Morse, as was the famous CQD (dah-dit-dah-dit dah-dah-dit-dah
dah-dit-dit) transmitted by the sinking Titanic's radio operator in 1912.
Still, Morse remains important for signalling distress,  if only by a lost
hiker blinking a flashlight into the lonely, dark night.

Hacking the Arduino as a Morse code trainer is fairly straightforward.
All you need is a blinking light, such as a high-intensity LED, and a sound
source, say a mini piezo speaker, to provide the beeps. Rounding out
the project is an LCD display to show the character being beeped/blinked.

The goal is to beep and simultaneously display the letters, numbers,
and a few important punctuation marks in ordered sequence. Following
this, do 50 random letters. Then, have the entire routine repeat.
The combination of beeps, flashes, and LCD display serves as an
effective tool for memorizing the Morse code.

I built this project as an Arduino shield, using an Adafruit protoshield
blank board. It will likewise work with most of the commercially pre-built
16x2 LCD shields or even just breadboarded. The hardware consists of
an 8x2 or 16x2 LCD wired to the Arduino in conventional fashion, an LED,
and a piezo speaker. Most of the actual work is done by software.

I used point-to-point wiring, otherwise known as "haywiring," a
venerable technique lost in the mists of antiquity. Before the mid 1950s,
virtually all electronic devices were built this way, and by humans,
not robots or automatic devices.

This is how the completed project works:

crich12 years ago
Very nice! I built one of these with a 16 X 2 LCD and not only does it work beautifully but now I have a really good working LCD shield for other projects too. Most of the other shields you buy mount the LCD accross the shield and it hangs off both sides. Your's is a much cleaner build. Thanks.
ajaen14 months ago

honestly i cant reat ... it is too slow to get the rithm is there an adjust ment to make it faster to 5 words a minute?

davidbarcomb9 months ago

Excellent project with great instructable. Thank you

thegrendel (author)  davidbarcomb9 months ago
Thank you for the praise.
thegrendel (author)  JeanDavis1 year ago
We lowly tinkerers all too often must brave scorn and cold
indifference, and so a few welcome words of praise are as
balm to our wounds. Thank you!
DGerman3 years ago
I have several (hopefully constructive) comments regarding your code, including algorithm, use of memory, constants and code simplification. Interested?
thegrendel (author)  DGerman3 years ago
Sure, why not? I don't know if I'll adopt your suggestions, since an Arduino
sketch is by no stretch of the imagination elegant code that might be submitted
to a professional journal. It's more like a quick-and-dirty back-of-the-envelope
hack just to get things working.

I think you'd find, if you compare my sketch to others, that's it's reasonably
well-structured and maintainable. Note also that since I've placed it in the
Public Domain, that you or anyone else is permitted to alter and distribute
your own version without restriction.
Hopefully my comments are informative and "instructive" they are not meant as a criticism nor an "I can write it better:"

1) The algorithm, that is the basic idea, which breaks up the symbols into categories ( numeric and alphabetic) sounds like a good idea. However, since the space between the categories is small, rearranging the table (numbers, then alphabetics) and combining them, makes a big difference in the complexity of the code. The fact that there are a different number of "tones" (i.e. the letters take a maximum of 5, numbers always 5) is overshadowed by the need to create additional tables ( strings) defining the categories. This also avoids specifying a category to play_letter. You should try to keep nomenclature consistent (morse, Alpha, ALPHABETIC) (I suspect the differences has to do with the way you developed the code)

2) Some of the code is replicated for each category. For example within the play_letter function: each category contain a statement that increments the variable i ( I cannot seem to get the plus plus into this reply!).
Although this may seems like nit picking, when later modification are made it is easy to forget to include code that is common to all cases.

3) Not sure why you made the numbers [20][6] rather than [10][6] ? (Maybe also from code "evolution ")

4) int s are 2 byte variables, better idea for the table to use CHAR. You could even test for a '.' or a '-'.

5a) "Define constants" are, well, constant and so should be declared using const . Even better use PROGMEM. This is applicable for any strings or tables.

5b)Then there is the DEFINE issue. (This concept is under active discussion within the arduino community at this time. )
The compiler directive
#define ccc vvv
does not allocate ANY space in target memory. When the compiler encounters the string ccc in the source it substitutes vvv.
This is significant since the code that can be generated for a small valued DEFINEd constant can use the immediate instruction that does not reference memory(other than the instruction) and are twice as fast. These include Load, Add, Subtract, Compare, AND and OR Immediate as well as instructions for setting or clearing bits. Similarly, I/O to pins can be handled better if the pin is DEFINEd. This allows the compiler to construct instruction. With ints the value needs not be retrieved from a memory location and the instruction "built" at execution time as in the case of pinSpeaker, pinled. This is not applicable for tables.

6) Size considerations mentioned are especially important if the code is extracted and added to another program as a means of error reporting using LED_BUILTIN (that is my intention)

7) Calculating "constatnts". If dashlen is twice a dot than have the CODE say so, i.e. dashLen =dotLen*2

8) Are you familiar with the tone() function ? http://arduino.cc/en/Reference/Tone Why did you use mikegrb's code instead?

Please reply or Private message me with comments or questions.

Where did you find values for punctuation? Are there values for other symbols?

Where did you find enum?

I am still finishing up a version which takes these thoughts into consideration and will post it when I have it completed.
thegrendel (author)  DGerman3 years ago
>> Where did you find values for punctuation? <<

Standard Internation Morse Code, per Wikipedia.

>>Where did you find enum?<<

Standard ANSI C.

>> Why did you use mikegrb's code instead? <<

Because it works.

>> I am still finishing up a version which takes these thoughts into consideration and will post it when I have it completed. <<

You have my best wishes.
DGerman3 years ago
I think you ment 2012
Reldate: 04 March 2102

Question: Why is the dashlen = 2 * dotlen
"Not the standard dash = 3 x dot length!" ?
thegrendel (author)  DGerman3 years ago
Yes, probably 2012. Will maybe release 99th update in 2102
if still around.

>> Question: Why is the dashlen = 2 * dotlen <<

I tried 3 * dotlen to start with, but it just didn't sound right.
2 * sounds more natural. If you like 3 * or something else,
you can easily enough edit the sketch to match your preference.

Thanks for your comment.
derte843 years ago
Nice idea! I think is the sister of mine http://www.instructables.com/id/The-useless-but-mazing-QR-clock/
thegrendel (author)  derte843 years ago
Not the sister, but maybe second cousin.

Like your project, too.