Arduino Morse Code

121K32751

Intro: Arduino Morse Code

When I was younger I started practicing for my Ham Radio license but did not stick with this long enough to master the morse code. With this project you can convert any text to morse code. This project will show you how to create a basic circuit which converts the text to morse code and blinks LED lights while playing audio of the translated dots and dashes.

This is my first Instructables project so I hope you like it! In this project I will assume you have some very basic knowledge of electronics and uploading code to the Arduino. Check out many other great Instructables for help on this if necessary. This is a really easy project so I'm sure you will not have any issues.

STEP 1: Gather the Parts

For this project use an Arduino Uno micro controller connected to a solderless breadboard.

  • 1 - Andruino
  • 1 - Solderless Breadboard
  • 3 - Resistors (220 Ohm)
  • 1 - 8-ohm Mini Speaker
  • 2 - 5mm LED Lights
  • 3 - Short Jumper Wires (1 cm)
  • 4 - Longer Jumper Wires (6 - 10 cm)
  • 1 - USB Cable

STEP 2: Setup the Circuit Board

First setup the breadboard to connect the two LEDs and one speaker as seen in the wiring diagram. Connect the small jumper from the ground to one row. On a second row connect a longer jumper cable and a resistor. The LED light or speaker will bridge these two rows. When connecting the LEDs, the positive leg (longer of the two wires coming out of the LED) should be connected to the line with the resistor and the negative leg will be on the grounded row.

STEP 3: Connecting the Arduino

Now that you have the breadboard wired you will connect this to the Arduino. In the code we will be using output pins six and twelve for the LED lights and pin eight for the audio. Connect the two longer jumper wires with the LEDs inline to pin six and twelve on the Arduino. Connect the longer jumber wire with the speaker to pin eight. Finally, connect the GND pin to the ground bus at the top of the breadboard.

STEP 4: Uploading the Code

Next connect your computer to the Arduino via the USB cable. Using the Arduino compiler upload the following code. To modify the morse code string just change the 'stringToMorseCode'. The code will read this string and convert the string to morse code, both visual and audio.

The code reads the string to an array and then using the GetChar function this converts each character into dots and dashes. Currently this is just converting alphabetic characters but you can easily add additional characters (numbers, punctuation) in this select statement switch at the bottom of the code.

/*
Morse Code Project This code will loop through a string of characters and convert these to morse code. It will blink two LED lights and play audio on a speaker. */ //**************************************************// // Type the String to Convert to Morse Code Here // //**************************************************// char stringToMorseCode[] = "Arduino Morse Code Project";

// Create variable to define the output pins int led12 = 12; // blink an led on output 12 int led6 = 6; // blink an led on output 6 int audio8 = 8; // output audio on pin 8 int note = 1200; // music note/pitch

/* Set the speed of your morse code Adjust the 'dotlen' length to speed up or slow down your morse code (all of the other lengths are based on the dotlen)

Here are the ratios code elements: Dash length = Dot length x 3 Pause between elements = Dot length (pause between dots and dashes within the character) Pause between characters = Dot length x 3 Pause between words = Dot length x 7 http://www.nu-ware.com/NuCode%20Help/index.html?m... */ int dotLen = 100; // length of the morse code 'dot' int dashLen = dotLen * 3; // length of the morse code 'dash' int elemPause = dotLen; // length of the pause between elements of a character int Spaces = dotLen * 3; // length of the spaces between characters int wordPause = dotLen * 7; // length of the pause between words

// the setup routine runs once when you press reset: void setup() { // initialize the digital pin as an output for LED lights. pinMode(led12, OUTPUT); pinMode(led6, OUTPUT); }

// Create a loop of the letters/words you want to output in morse code (defined in string at top of code) void loop() { // Loop through the string and get each character one at a time until the end is reached for (int i = 0; i < sizeof(stringToMorseCode) - 1; i++) { // Get the character in the current position char tmpChar = stringToMorseCode[i]; // Set the case to lower case tmpChar = toLowerCase(tmpChar); // Call the subroutine to get the morse code equivalent for this character GetChar(tmpChar); } // At the end of the string long pause before looping and starting again LightsOff(8000); }

// DOT void MorseDot() { digitalWrite(led12, HIGH); // turn the LED on digitalWrite(led6, HIGH); tone(audio8, note, dotLen); // start playing a tone delay(dotLen); // hold in this position }

// DASH void MorseDash() { digitalWrite(led12, HIGH); // turn the LED on digitalWrite(led6, HIGH); tone(audio8, note, dashLen); // start playing a tone delay(dashLen); // hold in this position }

// Turn Off void LightsOff(int delayTime) { digitalWrite(led12, LOW); // turn the LED off digitalWrite(led6, LOW); noTone(audio8); // stop playing a tone delay(delayTime); // hold in this position }

// *** Characters to Morse Code Conversion *** // void GetChar(char tmpChar) { // Take the passed character and use a switch case to find the morse code for that character switch (tmpChar) { case 'a': MorseDot(); LightsOff(elemPause); MorseDash(); LightsOff(elemPause); break; case 'b': MorseDash(); LightsOff(elemPause); MorseDot(); LightsOff(elemPause); MorseDot(); LightsOff(elemPause); MorseDot(); LightsOff(elemPause); break; case 'c': MorseDash(); LightsOff(elemPause); MorseDot(); LightsOff(elemPause); MorseDash(); LightsOff(elemPause); MorseDot(); LightsOff(elemPause); break; case 'd': MorseDash(); LightsOff(elemPause); MorseDash(); LightsOff(elemPause); MorseDot(); LightsOff(elemPause); break; case 'e': MorseDot(); LightsOff(elemPause); break; case 'f': MorseDot(); LightsOff(elemPause); MorseDot(); LightsOff(elemPause); MorseDash(); LightsOff(elemPause); MorseDot(); LightsOff(elemPause); break; case 'g': MorseDash(); LightsOff(elemPause); MorseDash(); LightsOff(elemPause); MorseDot(); LightsOff(elemPause); break; case 'h': MorseDot(); LightsOff(elemPause); MorseDot(); LightsOff(elemPause); MorseDot(); LightsOff(elemPause); MorseDot(); LightsOff(elemPause); break; case 'i': MorseDot(); LightsOff(elemPause); MorseDot(); LightsOff(elemPause); break; case 'j': MorseDot(); LightsOff(elemPause); MorseDash(); LightsOff(elemPause); MorseDash(); LightsOff(elemPause); MorseDash(); LightsOff(elemPause); break; case 'k': MorseDash(); LightsOff(elemPause); MorseDot(); LightsOff(elemPause); MorseDash(); LightsOff(elemPause); break; case 'l': MorseDot(); LightsOff(elemPause); MorseDash(); LightsOff(elemPause); MorseDot(); LightsOff(elemPause); MorseDot(); LightsOff(elemPause); break; case 'm': MorseDash(); LightsOff(elemPause); MorseDash(); LightsOff(elemPause); break; case 'n': MorseDash(); LightsOff(elemPause); MorseDot(); LightsOff(elemPause); break; case 'o': MorseDash(); LightsOff(elemPause); MorseDash(); LightsOff(elemPause); MorseDash(); LightsOff(elemPause); break; case 'p': MorseDot(); LightsOff(elemPause); MorseDash(); LightsOff(elemPause); MorseDash(); LightsOff(elemPause); MorseDot(); LightsOff(elemPause); break; case 'q': MorseDash(); LightsOff(elemPause); MorseDash(); LightsOff(elemPause); MorseDot(); LightsOff(elemPause); MorseDash(); LightsOff(elemPause); break; case 'r': MorseDot(); LightsOff(elemPause); MorseDash(); LightsOff(elemPause); MorseDot(); LightsOff(elemPause); break; case 's': MorseDot(); LightsOff(elemPause); MorseDot(); LightsOff(elemPause); MorseDot(); LightsOff(elemPause); break; case 't': MorseDash(); LightsOff(elemPause); break; case 'u': MorseDot(); LightsOff(elemPause); MorseDot(); LightsOff(elemPause); MorseDash(); LightsOff(elemPause); break; case 'v': MorseDot(); LightsOff(elemPause); MorseDot(); LightsOff(elemPause); MorseDot(); LightsOff(elemPause); MorseDash(); LightsOff(elemPause); break; case 'w': MorseDot(); LightsOff(elemPause); MorseDash(); LightsOff(elemPause); MorseDash(); LightsOff(elemPause); break; case 'x': MorseDash(); LightsOff(elemPause); MorseDot(); LightsOff(elemPause); MorseDot(); LightsOff(elemPause); MorseDash(); LightsOff(elemPause); break; case 'y': MorseDash(); LightsOff(elemPause); MorseDot(); LightsOff(elemPause); MorseDash(); LightsOff(elemPause); MorseDash(); LightsOff(elemPause); break; case 'z': MorseDash(); LightsOff(elemPause); MorseDash(); LightsOff(elemPause); MorseDot(); LightsOff(elemPause); MorseDot(); LightsOff(elemPause); break; default: // If a matching character was not found it will default to a blank space LightsOff(Spaces); } }

/* Unlicensed Software: This is free and unencumbered software released into the public domain.

Anyone is free to copy, modify, publish, use, compile, sell, or distribute this software, either in source code form or as a compiled binary, for any purpose, commercial or non-commercial, and by any means.

In jurisdictions that recognize copyright laws, the author or authors of this software dedicate any and all copyright interest in the software to the public domain. We make this dedication for the benefit of the public at large and to the detriment of our heirs and successors. We intend this dedication to be an overt act of relinquishment in perpetuity of all present and future rights to this software under copyright law.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

For more information, please refer to */

STEP 5: Testing the Project

Now the fun part, test it out! The code will play through the morse code string and then pause for several seconds before looping again. Play around with code and circuit layout. Try adding a few extra lights in parallel with each other. Also play around with the code by changing the "dotLen" variable to adjust the length of the dots and dashes (speeds up/slows down the morse code). Change the "note" variable to adjust the audio pitch.

Let me know how this works for you and if you have any improvements!

Chris Weatherford

41 Comments

Nice!
Your code is 300+ lines (not counting license).
Challenge: how to write it in less than 150 while improving code readability?

Just for the fun of it, under 60 lines... A little late but maybe someone has use for it.

#define ledPin A2 // assign name to pin

char *letters[] = { // letters a-z in morse code
".-", "-...", "-.-.", "-..", ".", "..-.", "--.",
"....", "..", ".---", "-.-", ".-..", "--", "-.",
"---", ".--.", "--.-", ".-.", "...", "-", "..-",
"...-", ".--", "-..-", "-.--", "--.." };

char *numbers[] = { // numbers 0-9 in morse code
"-----", ".----", "..---", "...--", "....-",
".....", "-....", "--...", "---..", "----." };

char textToMorseCode[] = "Hello World";

unsigned int dotMillis = 100; // time duration for a morse dot


void setup() {
pinMode( ledPin, OUTPUT);
}


void loop() {
for( int i = 0; i < sizeof( textToMorseCode) - 1; i++){
char readChar = textToMorseCode[i];
readChar = toLowerCase( readChar);
if( readChar >= 'a' && readChar <= 'z'){
flashMorseCode( letters[ readChar - 'a']);
} else if ( readChar >= '0' && readChar <= '9'){ // check for numbers
flashMorseCode( numbers[ readChar - '0']);
} else if ( readChar == ' ') { // check for space
delay( dotMillis * 7); // pause between words
}
}
}


void flashMorseCode( char *morseCode) { // read the morse elements for the character
unsigned int i = 0;
while( morseCode[i] != NULL){
flashMorseElement( morseCode[i]);
i++;
}
delay( dotMillis * 3); // pause between two letters
}

void flashMorseElement( char morseElement){
digitalWrite( ledPin, HIGH); // turn LED on

if ( morseElement == '.') delay( dotMillis);
else delay( dotMillis * 3);

digitalWrite( ledPin, LOW); // turn LED off
delay( dotMillis); // pause between morse elements
}

I've written a similar program myself. I put the (equivalent of) LightsOff(elemPause) INTO the MorseDot() and MorseDash(), which I called dit() and dah(), so my case 'c':
can be just dah(); dit(); dah(); dit(); break;

Then having ALREADY HAD one dotlen or elemPause of silence, take one off of each of...
Spaces = dotLen * 2; wordPause = dotLen * 6;

Good thinking.

This will definitely shorten the number of lines but... it is not going to improve code readability. You still are going to have the same issue with understanding that 'dah(); dit(); dah(); dit()' is just '-.-.'

Can you store each letter as sequence of dashes and dots and then just 'play' them?

Hint: start with writing a function play() which takes string like '-.-.'

True, you can, BUT strings on Arduino take up valuable RAM, unless you muck with PROGMEM and prog_char and stuff, which is going to be really ugly again. Admittedly if your only strings are a morse copy of the alphabet, you'll be fine. :-/

I was interested in a similar project. In the code I am missing the "wordPause". There is no pause between "words" other than a space? or am I missing the point.

Change:

GetChar(tmpChar);
}

To:

if(GetChar != ' '){
GetChar(tmpChar);L
LightsOff(Spaces);
} else {
LightsOff(wordPause);
}
}

This is a nice project. As an Extra Class Ham Radio operator, I noticed right off the bat that your Morse encoding for "d" -.. was actually a Morse "g" --. It needs to be dash dot dot not dash dash dot. I was listening to the spelling of "Arduino" and when it came out "Arguino" I did a double take. First time in a long time I've debugged a program by ear ;-), Also, the characters all run together as there is no space between them in words. I fixed that by changing:

// Call the subroutine to get the morse code equivalent for this character
GetChar(tmpChar);
}

TO:

// Call the subroutine to get the morse code equivalent for this character
GetChar(tmpChar);
LightsOff(Spaces);
}

Now it sends perfect Morse.

Didn't look at all of the notes below to see if this had already been pointed out but since it is still incorrect here, I figured it wasn't.

FYI, I'm using this to "flash" the red tail light on my E-bike with a varying flash pattern that in Morse says "please do not hit me, I am fragile" and other texts. Variably flashing red lights tend to stand out more than steady state lights during the day.

I added the Morse for comma and period punctuation. Your project gave me just what I needed. Thanks!

de N5DP

Have no previous experience with Arduino so sorry if I am asking silly questions:

- What power adapter does arduino need?

-Does the Arduino start the morse sequence immediately after it is powered. Or does it have some kind of switch to turn it on. I would like to build the morse code lamp that is turned of with e.g. light switch

Arduino circuit works fine 5v dc input for small project. But with project that need more power to works i usually use 7-12V DC usually i use 9v adapter.
It will works after you uploaded the code. If it not it means that something wrong with your connection or your code.

i can not write the code fully correct
please send me clear code without any extra words or punctuations

Here is the original code I wrote. I think there may be a few errors in the morse code characters so please double check these. If you download this you can open this in a text editor (or the Arduino application). I hope this helps.

https://goo.gl/6mCSBr

Works great now, had to tweak the program a little though.

Changed int Spaces = dotLen * 3 to int charPause = dotLen * 3;

Then changed the last line of each character from LightsOff(elemPause);

to LightsOff(charPause);

Added numbers, punctuation and pro-signs. Used two different color LEDs, blue and red, changed program so blue blinks on dashes and red blinks on dots

hi ,
"D" is wrong, it should be "dash dot dot".

int Spaces = dotLen * 3 - dotLen;

//also need add extra code in loop.
if(i > 0 && i < sizeof(stringToMorseCode) - 1) {//elementPause

noTone(audio8);

delay(dotLen);

}

I noticed there are problems with this code not pausing between letters as well. Like S and H there is 0 pause between them. Where did you put your if statement I keep getting errors no matter where I stick it.

Thanks Chris. I used your code in what will soon be an Instructable. You did all the heavy lifting for me and I had your code running right away.
So I can actually see what your doing
Take better pictures
More Comments