A Morse code translator program needs one lookup table and one loop. Store the code for each letter and digit, look up each character of the input, join the codes with a space between letters and a slash between words. The examples below do exactly that in C, Python, Java and JavaScript, and an Arduino sketch blinks the result on an LED.
The idea in four steps
Every Morse code program, in any language, follows the same plan.
- Store the table. Map each of the 26 letters and 10 digits to a string of dots and dashes. A dictionary, a map or an array indexed by letter all work.
- Split the text into words, then into letters.
- Look up each letter and skip characters that have no code.
- Join the codes: one space between letters and
/between words.
To go the other way, build the reverse table (code to letter), split the Morse string on / for words and on spaces for letters, and look each one up. Unknown codes should become a placeholder such as ?, so that one mistake does not hide the rest of the message.
All five programs below were run to check their output. The first four print .... . .-.. .-.. --- / .-- --- .-. .-.. -.. for "Hello world". The Arduino sketch was checked by running its timing with a stand-in for the board and decoding the pattern it produced, so test it on your own board before relying on it.
Morse code in C
A plain C program with an array of 36 strings, indexed by letter. Compile it with gcc morse.c -o morse and run it as ./morse "Hello world".
#include <stdio.h>
#include <ctype.h>
/* Morse code for A-Z (index 0-25) and 0-9 (index 26-35) */
static const char *CODE[36] = {
".-", "-...", "-.-.", "-..", ".", "..-.", "--.", "....", "..", ".---",
"-.-", ".-..", "--", "-.", "---", ".--.", "--.-", ".-.", "...", "-",
"..-", "...-", ".--", "-..-", "-.--", "--..",
"-----", ".----", "..---", "...--", "....-", ".....", "-....", "--...", "---..", "----."
};
static const char *lookup(int c) {
c = toupper(c);
if (c >= 'A' && c <= 'Z') return CODE[c - 'A'];
if (c >= '0' && c <= '9') return CODE[26 + c - '0'];
return NULL;
}
int main(int argc, char **argv) {
const char *text = argc > 1 ? argv[1] : "Hello world";
int first = 1, pending_word_gap = 0;
for (const char *p = text; *p; p++) {
if (*p == ' ') { pending_word_gap = 1; continue; }
const char *code = lookup((unsigned char)*p);
if (!code) continue; /* skip characters with no code */
if (!first) printf(pending_word_gap ? " / " : " ");
printf("%s", code);
first = 0; pending_word_gap = 0;
}
printf("\n");
return 0;
}The array holds A to Z first and then 0 to 9, so the index for a letter is c - 'A' and for a digit it is 26 + c - '0'. This is the simplest Morse code C program and the same table works for a microcontroller. For embedded code, keep the table in flash memory to save RAM.
Morse code in Python
Python's dictionaries make this the shortest version, and it also decodes. It runs in Python 3 on a PC, a Mac or a Raspberry Pi.
CODE = {
"A": ".-", "B": "-...", "C": "-.-.", "D": "-..", "E": ".", "F": "..-.", "G": "--.",
"H": "....", "I": "..", "J": ".---", "K": "-.-", "L": ".-..", "M": "--", "N": "-.",
"O": "---", "P": ".--.", "Q": "--.-", "R": ".-.", "S": "...", "T": "-", "U": "..-",
"V": "...-", "W": ".--", "X": "-..-", "Y": "-.--", "Z": "--..",
"0": "-----", "1": ".----", "2": "..---", "3": "...--", "4": "....-",
"5": ".....", "6": "-....", "7": "--...", "8": "---..", "9": "----.",
}
DECODE = {code: letter for letter, code in CODE.items()}
def to_morse(text):
words = []
for word in text.upper().split():
letters = [CODE[ch] for ch in word if ch in CODE]
if letters:
words.append(" ".join(letters))
return " / ".join(words)
def to_text(morse):
words = []
for word in morse.strip().split(" / "):
words.append("".join(DECODE.get(code, "?") for code in word.split()))
return " ".join(words)
if __name__ == "__main__":
message = to_morse("Hello world")
print(message) # .... . .-.. .-.. --- / .-- --- .-. .-.. -..
print(to_text(message)) # HELLO WORLDTo build a command-line Morse code translator in Python, read the text with input() or sys.argv and print to_morse() of it. A Morse code translator using a Raspberry Pi can flash an LED with the gpiozero library: turn the LED on for one unit for a dot and three for a dash, using time.sleep() between parts. The timing rules are the ones in the tapper guide.
Morse code in JavaScript
The same approach in JavaScript runs in a browser console or with Node.js (node morse-node.js). This site's translator is written this way.
const CODE = {
A: ".-", B: "-...", C: "-.-.", D: "-..", E: ".", F: "..-.", G: "--.", H: "....", I: "..",
J: ".---", K: "-.-", L: ".-..", M: "--", N: "-.", O: "---", P: ".--.", Q: "--.-", R: ".-.",
S: "...", T: "-", U: "..-", V: "...-", W: ".--", X: "-..-", Y: "-.--", Z: "--..",
0: "-----", 1: ".----", 2: "..---", 3: "...--", 4: "....-", 5: ".....",
6: "-....", 7: "--...", 8: "---..", 9: "----.",
};
const DECODE = Object.fromEntries(Object.entries(CODE).map(([letter, code]) => [code, letter]));
function toMorse(text) {
return text.toUpperCase().split(/\s+/)
.map((word) => [...word].filter((ch) => CODE[ch]).map((ch) => CODE[ch]).join(" "))
.filter(Boolean).join(" / ");
}
function toText(morse) {
return morse.trim().split(" / ")
.map((word) => word.split(/\s+/).map((code) => DECODE[code] ?? "?").join(""))
.join(" ");
}
console.log(toMorse("Hello world")); // .... . .-.. .-.. --- / .-- --- .-. .-.. -..
console.log(toText(toMorse("Hello world"))); // HELLO WORLDMorse code in Java
A Java translator with a Map. Compile it with javac Morse.java and run java Morse Hello world.
import java.util.Map;
import java.util.StringJoiner;
public class Morse {
private static final Map<Character, String> CODE = Map.ofEntries(
Map.entry('A', ".-"), Map.entry('B', "-..."), Map.entry('C', "-.-."), Map.entry('D', "-.."),
Map.entry('E', "."), Map.entry('F', "..-."), Map.entry('G', "--."), Map.entry('H', "...."),
Map.entry('I', ".."), Map.entry('J', ".---"), Map.entry('K', "-.-"), Map.entry('L', ".-.."),
Map.entry('M', "--"), Map.entry('N', "-."), Map.entry('O', "---"), Map.entry('P', ".--."),
Map.entry('Q', "--.-"), Map.entry('R', ".-."), Map.entry('S', "..."), Map.entry('T', "-"),
Map.entry('U', "..-"), Map.entry('V', "...-"), Map.entry('W', ".--"), Map.entry('X', "-..-"),
Map.entry('Y', "-.--"), Map.entry('Z', "--.."),
Map.entry('0', "-----"), Map.entry('1', ".----"), Map.entry('2', "..---"), Map.entry('3', "...--"),
Map.entry('4', "....-"), Map.entry('5', "....."), Map.entry('6', "-...."), Map.entry('7', "--..."),
Map.entry('8', "---.."), Map.entry('9', "----."));
static String toMorse(String text) {
StringJoiner words = new StringJoiner(" / ");
for (String word : text.toUpperCase().trim().split("\\s+")) {
StringJoiner letters = new StringJoiner(" ");
for (char ch : word.toCharArray()) {
String code = CODE.get(ch);
if (code != null) letters.add(code);
}
if (letters.length() > 0) words.add(letters.toString());
}
return words.toString();
}
public static void main(String[] args) {
System.out.println(toMorse(args.length > 0 ? String.join(" ", args) : "Hello world"));
}
}Morse code on Arduino
This sketch flashes the built-in LED in Morse code. Upload it from the Arduino IDE and the LED sends SOS over and over. Change MESSAGE to send anything else.
// Blinks the built-in LED in Morse code. Change MESSAGE to send something else.
const char *MESSAGE = "SOS";
const int UNIT_MS = 200; // length of one dot; about 6 words per minute
const char *CODE[36] = {
".-", "-...", "-.-.", "-..", ".", "..-.", "--.", "....", "..", ".---",
"-.-", ".-..", "--", "-.", "---", ".--.", "--.-", ".-.", "...", "-",
"..-", "...-", ".--", "-..-", "-.--", "--..",
"-----", ".----", "..---", "...--", "....-", ".....", "-....", "--...", "---..", "----."
};
void flash(int units) {
digitalWrite(LED_BUILTIN, HIGH);
delay(units * UNIT_MS);
digitalWrite(LED_BUILTIN, LOW);
}
void sendLetter(const char *code) {
for (int i = 0; code[i]; i++) {
flash(code[i] == '.' ? 1 : 3); // dot = 1 unit, dash = 3 units
if (code[i + 1]) delay(UNIT_MS); // 1 unit between parts of a letter
}
}
void sendMessage(const char *text) {
for (int i = 0; text[i]; i++) {
char c = text[i];
if (c == ' ') { delay(4 * UNIT_MS); continue; } // 3 already waited after the letter + 4 = 7
const char *code = 0;
if (c >= 'a' && c <= 'z') c -= 32;
if (c >= 'A' && c <= 'Z') code = CODE[c - 'A'];
else if (c >= '0' && c <= '9') code = CODE[26 + c - '0'];
if (!code) continue;
sendLetter(code);
delay(3 * UNIT_MS); // 3 units between letters
}
}
void setup() { pinMode(LED_BUILTIN, OUTPUT); }
void loop() {
sendMessage(MESSAGE);
delay(7 * UNIT_MS);
}The timing follows the standard rules: a dot is one unit, a dash is three, the gap inside a letter is one, between letters three and between words seven. Because sendMessage already waits three units after a letter, a space only adds four more to make seven. At UNIT_MS = 200, the speed is 6 words per minute. For a faster signal, lower the number; the unit in milliseconds is 1200 divided by the words per minute. To make sound instead of light, replace digitalWrite with tone(pin, 600) and noTone(pin) on a piezo buzzer.
Going further
- Add punctuation. Add more entries to the table, for example
.-.-.-for a full stop and--..--for a comma. The full list is on the alphabet page. - Check your program by comparing its output with the Morse code translator for a few messages, including numbers and mixed case.
- Make sound. In a browser, an oscillator and a gain node can play the code. See the sound generator, which also saves a WAV file.
- Decode audio. Detect the tone, measure the lengths of the beeps and classify them as dots or dashes. The audio decoder shows the result.
- Convert to binary or Base64 with the binary translator to compare your results.
Frequently asked questions
How do I make a Morse code translator in Python?
Create a dictionary from letters to codes, split the text into words and letters, look up each letter and join the codes with spaces and slashes. The Python example above is 30 lines.
How do I write a Morse code program in C?
Use an array of strings for the codes, index it by c - 'A' for letters and by 26 + c - '0' for digits, and print the codes with a space between them.
Can an Arduino send Morse code?
Yes. Set a pin as an output and turn it on and off with delays. The sketch above uses the built-in LED. The same timing can drive a buzzer or a radio key.
How do I translate Morse code to text in code?
Make a reverse dictionary from code to letter, split the input on / for words and on spaces for letters, and look each code up.
How do I make a Morse code translator in Java?
Use a Map<Character, String> for the codes and a StringJoiner for the output, as in the Java example above.
Source code and projects
The examples above are complete source code you can copy: C, Python, Node.js, Java and an Arduino sketch. Searching for a Morse code translator project, whether in Java, Python or Arduino, usually leads to the same few lines: a lookup table, a loop over the letters, and a pause between letters. The Java example uses only the standard library: no regular expressions and no external packages.