In this post, I’ll show you how to develop an application which executes on an Arduino and displays a user typed string, such as “Hello World”, as Morse code on an LED.
Named after Samuel F.B. Morse, the inventor of the telegraph, Morse code is a character encoding scheme that represents letters as long and short pulses of sound or light.
Requirements
The system that is developed must satisfy the following requirements:
- It must execute on an Arduino. The Arduino version used was version 1.8.8. Most Arduino versions will work.
- It must display a user typed string, such as “Hello World”, as Morse code on an LED (or several LEDs), or an LCD.
- A dash is three times as long as a dot.
- The time between each dot or dash in the same letter is equal to the duration of one dot.
- The time between two letters is the duration of one dash.
- The time between two words is the same duration as seven dots.
- It must use a Round Robin design where a loop:
- Waits for a string
- Displays the string in Morse code
- Exits the loop only if a sentinel is entered (e.g. !)
Hardware Design
The following components are used for the Morse code LED system. You will need:
Here is the schematic:
Software Design
Here are the steps for the Morse code LED system:
- Step 1. Prompt the user to enter a message on the Serial Monitor. The input for the message contains characters (letters and/or numbers).
- Step 2. Read each character, one at a time.
- Step 3. Convert each character into the equivalent Morse Code.
- Step 4. Convert each Morse code sequence into the corresponding sequence of dots and dashes.
- Step 5. Transmit the dots and dashes to the LED while transmitting the message to the Serial Monitor.
- Step 6. Exit the loop if user enters the sentinel value of “!”
Implementation
Here is the source code that you will need to load to your Arduino:
/**
* In this program, we develop an application which executes on an Arduino
* Uno and displays a user typed string, such as “Hello World”, as Morse
* code on an LED.
*
* @version 1.0 2019-01-31
* @author Addison Sears-Collins
*/
// Assign a name to the digital pin 12
unsigned int led_pin = 12;
// Declare an array named letters that holds addresses of string literals
// (i.e. an array of pointers to strings composed of dots and dashes)
// Done to preserve memory because strings are not equal in size. A 2D array
// would be a waste of space.
char *letters[] = {
// The letters A-Z in Morse code
".-", "-...", "-.-.", "-..", ".", "..-.", "--.", "....", "..",
".---", "-.-", ".-..", "--", "-.", "---", ".--.", "--.-", ".-.",
"...", "-", "..-", "...-", ".--", "-..-", "-.--", "--.."
};
char *numbers[] = {
// The numbers 0-9 in Morse code
"-----", ".----", "..---", "...--", "....-", ".....", "-....",
"--...", "---..", "----."
};
unsigned int dot_duration = 200;
bool done = false;
/**
* Function runs only once, after each powerup or reset of the Arduino
*/
void setup() {
// Set the LED to output
pinMode(led_pin, OUTPUT);
// Open the serial port and set the data transmission rate to 9600 bits
// per second. 9600 is the default baud rate for Arduino.
Serial.begin(9600);
// Show welcome message as human-readable ASCII text
Serial.println("MORSE CODE LED PROGRAM");
Serial.println("This program translates your message into Morse code");
Serial.println("and flashes it on an LED.");
Serial.println("Author: Addison Sears-Collins");
Serial.println("");
Serial.println("Enter your message(s) or ! to exit: ");
}
/**
* Main function that drives the system
*/
void loop() {
char ch;
// This loop waits for a string, displays it in Morse code, and only exits
// the loop if the sentinel is entered.
while (!done) {
// Check to see if there are letters or numbers available to be read
if (Serial.available()) {
// Read one letter or number at a time
// Serial.read() returns the first (oldest) character in the buffer
// and removes that byte of data from the buffer
ch = Serial.read();
// Check for uppercase letters
if (ch >= 'A' && ch <= 'Z') {
Serial.println(ch);
flash_morse_code(letters[ch - 'A']);
}
// Check for lowercase letters
else if (ch >= 'a' && ch <= 'z') {
Serial.println(ch);
flash_morse_code(letters[ch - 'a']);
}
// Check for numbers
else if (ch >= '0' && ch <= '9') {
Serial.println(ch);
flash_morse_code(numbers[ch - '0']);
}
// Check for space between words
else if (ch == ' ') {
// Put space between two words in a message...equal to seven dots
delay(dot_duration * 7);
}
// Check for sentinel value
else if (ch == '!') {
done = true;
Serial.println("Thank you! Your messages were sent successfully.");
Serial.println("Goodbye.");
}
}
}
// Do nothing
while(true) {}
}
/**
* Flashes the Morse code for the input letter or number
* @param morse_code pointer to the morse code
*/
void flash_morse_code(char *morse_code) {
unsigned int i = 0;
// Read the dots and dashes and flash accordingly
while (morse_code[i] != NULL) {
flash_dot_or_dash(morse_code[i]);
i++;
}
// Space between two letters is equal to three dots
delay(dot_duration * 3);
}
/**
* Flashes the dot or dash in the Morse code
* @param dot_or_dash character that is a dot or a dash
*/
void flash_dot_or_dash(char dot_or_dash) {
// Make the LED shine
digitalWrite(led_pin, HIGH);
if (dot_or_dash == '.') { // If it is a dot
delay(dot_duration);
}
else { // Has to be a dash...equal to three dots
delay(dot_duration * 3);
}
// Turn the LED off
digitalWrite(led_pin, LOW);
// Give space between parts of the same letter...equal to one dot
delay(dot_duration);
}