ASCII to Morse Translator

While there are several ASCII to Morse code translators out there, I haven’t seen the encoding used herein. It is slightly denser than most and should work nicely in machines with a tight memory constraint.

The basic translation represents each Morse code character as a single byte. The individual Morse code dots and dashes are the low-order bits as 0s and 1s, respectively. But since Morse codes are different lengths, not all bits are used. To mark the used bits, a 1 bit is to the left of the first Morse code bit.

For example, in Morse code, “E” is a single dot. Encoded in binary here, it is 00000010 where the 1 is the marker and the 0 thereafter is that single dot.

The letter “J” is dot-dash-dash-dash and is encoded (in binary) as 00010111 with the left-most 1 the marker and the 0111 sequence that follows is dot-dash-dash-dash.

Since all Morse code letters, numbers and punctuation marks have six or fewer elements, a maximum of seven bits is needed for the marker plus the Morse code bits.

In the source code, alphanumerics are translated by a look-up table while the less-used punctuation marks are handled in a switch statement.

Here is a fragment of the translation table for the first six letters:

static char a2m_alpha[26] = {
    0x05, /* A */
    0x18, /* B */
    0x1a, /* C */
    0x0c, /* D */
    0x02, /* E */
    0x12, /* F */
    ...
};

The decoding is done by shifting to find the leading 1 marker bit, and then shifting out the remaining Morse code bits. Here is a fragment of that routine:

for (cnt = 0; (!(code & 0x80)) && (cnt <= 7); cnt++ )
    code <<= 1;
for ( ; cnt <= 6; cnt++ ) {
    code <<= 1;
    if (code & 0x80)
        send_dash();
    else
        send_dot();
}

I built and tested this on an Arduino Duemilanove using the default LED so it should be compatible with most of the Arduino boards — but since I was developing on Eclipse, if you’re using the standard Arduino development GUI, you’ll need to save the files as *.ino instead of the *.cpp and *.h I used.

You may download the five (5) source files below, or download ascii2morse.zip, or “git” from https://github.com/edskinner/ASCII2MorseCode.

  1. ascii2morse.cpp – Translates ASCII to Morse, calls send_dot() and send_dash()
  2. ascii2morse.h – Prototypes, etc. for above
  3. ascii2morse_test.cpp – Test driver – Sends all Morse code characters
  4. ascii2morse_send.cpp – Miscellaneous support routines (send_dot(), etc.)
  5. ascii2morse_send.h – Prototypes, etc. for above

License is Apache 2.0 — Read the license for details but, in a nutshell:

  1. Keep my copyright and license intact, and
  2. Put a note in the code if you make any changes.

There are no fees or restrictions other than that.

Enjoy!

3 thoughts on “ASCII to Morse Translator

  1. Fun! I have several arduino type boards (and thousands of microcontrollers) and also a few CGMMSTICKs that run BASIC and connect to microSD, keyboard, and VGA. The ‘stick’ could do audio and a conversion from keyboard or even file (SD card) easily. Just another way to have fun.

    • Yep, tons of fun!
      I’m just starting on another Arduino project: The 12v light bulbs in our kitchen burn out way too fast in spite of the “slow on” power switch (on the 110v side of the transformer). So, I started jotting down some notes for something to help me answer WTF.
      There will be a photoresistor per bulb so the Arduino can “see” when a bulb goes out, an AD converter on the 12v secondary, scaled for 50v so I can see if there are some transients, and a microphone glued to the cabinet to pick up door slams and such. The unit will sample all inputs and when a “bulb burnout detect” event occurs, the last “whatever” samples will be written to EEPROM. I’ll have another digital input that gets sampled on startup to select “sample” or “dump EEPROM to serial” mode, the latter so I can get the samples out and see WTF (hopefully).
      This is a spare time project but should be fun. The one unknown is the analog circuit to shift the 12v AC up so it’s all on the plus side of zero, and then scale the input so I’m measuring 0-50 volts (as 0-5 volts) at the Arduino.

      • The one unknown is the analog circuit to shift the 12v AC up so it’s all on the plus side of zero,

        The positive half is OK, the negative half isn’t. So half the time you are OK, the other half you are not. Just convert the negative half of the waveform to positive with a rectifier.

        Or if you must shift it, AC couple it first to an op amp. Reference a 2.5V point in a voltage divider. Output will be above 0V…

Leave a Reply

Your email address will not be published. Required fields are marked *