Skip to content

Morse Code Translator with Arduino

You write in your computer, sends a message thought USB and Arduino translates it into a Morse code.

Just a Arduino board with a buzzer connected at the digital output 12 (one wire in the ground and the other in the 12).

Arduino

I tried to make the code as general as possible so you can easily adapt it for anthers ways of transmitting a Morse code. To do that you just need to rewrite a few functions.

                                                  +-------------------+
                                                  | 3) Interpretation |
                                                  +-------------------+
                                                  |   2) Translation  |
+-------------------+                             +-------------------+
|     Computer      |<========USB (Serial)=======>|     1) Reading    |
+-------------------+                             +-------------------+

  1. Reads a character from Serial. Main function loop().
  2. Translate a ascii char into a Morse code using a reference table. A letter ‘K’ becomes a string word “-.-“. Function say_char().
  3. Interpret the Morse word as light and sound. Mostly at function say_morse_word(). The Interpretation needs 5 functions to say all Morse words, dot(), dash(), shortgap(), mediumgap() and intragap().

For a more details on Morse code I strongly recommend the English Wikipedia article on it.

int led = 13;                   // LED connected to digital pin 13
int buzzer = 12;                // buzzer connected to digital pin 12
int unit = 50;                  // duration of a pulse

char * morsecode[] = {
    "-----",  // 0
    ".----",  // 1
    "..---",  // 2
    "...--",  // 3
    "....-",  // 4
    ".....",  // 5
    "-....",  // 6 
    "--...",  // 7
    "---..",  // 8
    "----.",  // 9
    "---...", // :
    "-.-.-.", // ;
    "",       // < (there's no morse for this simbol)
    "-...-",  // =
    "",       // > (there's no morse for this simbol)
    "..--..", // ?
    ".--._.", // @
    ".-",     // 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
};

void setup() {
  pinMode(led, OUTPUT);
  pinMode(buzzer, OUTPUT);
  Serial.begin(9600);
}

void say_morse_word(char * msg){
  int index = 0;
  while(msg[index]!='\0'){
    // say a dash
    if(msg[index]=='-'){
      dash();
    }
    // say a dot
    if(msg[index]=='.'){
      dot();
    }
    // gap beetween simbols
    intragap();
    index++;
  }
}

// beep
void beep(int time){
  int i;
  int t = 100; // period of the wav. bigger means lower pitch.
  int beepduration = (int)((float)time/t*1800);
  digitalWrite(led, HIGH);
  for(i=0;i='0')&&(letter<='Z')&&(letter!='<')&&(letter!='>')){
    Serial.print(morsecode[letter-'0']);
    Serial.print(' ');
    say_morse_word(morsecode[letter-'0']);
    shortgap();
  } else {
    if(letter==' '){
      Serial.print(" \\ ");
      mediumgap();
    }else{
      Serial.print("X");
    }
  }
}

void loop(){
  if(Serial.available()){
    say_char((char)Serial.read());
  }
}

Additionally you can put another function to say entire strings, like say_string(“HELLO WORLD”)

void say_string(char * asciimsg){
  int index = 0;
  char charac;  
  charac = asciimsg[index];
  while(charac!='\0'){
    say_char(morsecode[charac-'0']);
    Serial.println(morsecode[charac-'0']);
    charac = asciimsg[++index];
    shortgap();
  }
}

You can use the Arduino IDE itself or any other program that talks with the serial port USB.

arduino interface

Published inenglish

15 Comments

  1. Great stuff!
    What do you think, on the other side, could there be a Morse code -> Text translating Arduino? That would be pretty practical….

  2. @Greg: I will start to work on such a project in the coming weeks. An Arduino will be connected to an LCD display that displays the translation from morse input. Way to input morse will be non standard. Project is to be used as a communication tool for a person with severe physical disabilities.

  3. Marc Marc

    Yes, I would like to see an example of a working morse decoder with LCD! 🙂 Great! Thanks!

  4. Chad Chad

    I’m just starting on my arduino and want to know how to go about decoding morse and display to an LCD my self thanks!!!

    Nice work

    Chad

  5. Hyde Hyde

    Hi There. Really nice project you have there. I was interested in implementing morse code in arduino, however I did i the other way around – user flashes the flashligh or other source of light near the photo diode, and arduino board translates it into letters, works pretty well 🙂

    Btw. How did you configure your IDE to have serial monitor directly below the code in the same window (it’s pretty annoying to open serial monitor every time from the menu, and the Keyboard shotcuts always puts empy line in the code…).

  6. Daniel Daniel

    Hi! I wonder if you ever made the morse code decoder – if so, could you send me the sourcecode for it ?
    I am making a project which I could share with you later on.. 🙂

  7. Daniel, the source is in this post. You can use it in the Creative Commons Attribution Share-Alike license or GPLv3 license.

  8. tom tom

    Hi all

    I’m working on an art piece at the moment which will decode morse but the difference is that the morse will be sent by human operated morse key so will obviously have to account for slightly variable timings. I have made some code in processing – the idea being that i will use analog in from arduino and send that by serial to processing. I’m happy to post the code if anyone is interested? at the moment it jsut works with a key press.

  9. Cees Cees

    hai

    I am learning Java from a friend and am also interested in Arduino so now I can combine the two.

    many thanks!

    Cees

  10. kia kia

    Hi Tom,

    would love to see how you dealed with sliding timing when a human is
    producing the morse code.

    Kia

  11. if anyone needs a “passive” version of this (i.e no delays) so the rest of your code runs without delay … I’m just blinking the LED & printing to Serial, but it can easily be modified for sound, or even LCD display:

    const char * morsecode[] = {
    “—–“, // 0
    “.—-“, // 1
    “..—“, // 2
    “…–“, // 3
    “….-“, // 4
    “…..”, // 5
    “-….”, // 6
    “–…”, // 7
    “—..”, // 8
    “—-.”, // 9
    “—…”, // :
    “-.-.-.”, // ;
    “”, // (there’s no morse for this symbol)
    “..–..”, // ?
    “.–._.”, // @
    “.-“, // 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
    };

    int count_Morse = 1;
    int word_index = 0;
    int morse_index = 0;
    unsigned long LED_current_time = millis();
    unsigned long LED_time_unit_CONST = 0;

    #define LED_PIN 13

    void setup() {
    Serial.begin(9600);
    pinMode(LED_PIN, OUTPUT);
    Serial.println();
    }

    void loop() {
    LED_blink_morse(200,1023,”Hello World!”);
    }

    void LED_blink_morse(int LED_blink_time_unit, int LED_ON_strength, String MORSE_CODE_string) {
    LED_ON_strength = constrain(LED_ON_strength,100,1023);
    LED_blink_time_unit = constrain(LED_blink_time_unit, 100,1000);

    char charac = toUpperCase(MORSE_CODE_string.charAt(word_index));

    if(charac!=’\0′){
    if((charac>=’0′)&&(charac<='Z')&&(charac!='’)){
    String morse_word = morsecode[charac-‘0′];

    if(morse_word[morse_index]!=’\0′){

    if(morse_word[morse_index]==’-‘ && !digitalRead(LED_PIN) && (millis() – LED_current_time >= LED_time_unit_CONST)){
    Serial.print(“-|”);
    LED_time_unit_CONST = LED_blink_time_unit * 3;
    digitalWrite(LED_PIN, LED_ON_strength); //turn ON LED
    //Serial.print(digitalRead(LED_PIN));
    LED_current_time = millis();
    count_Morse = 1;
    }

    if(morse_word[morse_index]==’.’ && !digitalRead(LED_PIN) && (millis() – LED_current_time >= LED_time_unit_CONST)){
    Serial.print(“.|”);
    LED_time_unit_CONST = LED_blink_time_unit;
    digitalWrite(LED_PIN, LED_ON_strength); //turn ON LED
    //Serial.print(digitalRead(LED_PIN));
    LED_current_time = millis();
    count_Morse = 1;
    }

    if (digitalRead(LED_PIN) && millis() – LED_current_time >= LED_time_unit_CONST) { //===== intergap
    Serial.print(” |”);
    LED_time_unit_CONST = LED_blink_time_unit;
    digitalWrite(LED_PIN, 0);
    //Serial.print(digitalRead(LED_PIN));
    morse_index++;
    LED_current_time = millis();
    count_Morse = 1;
    }

    if (!digitalRead(LED_PIN) && millis() – LED_current_time >= LED_blink_time_unit*count_Morse && count_Morse = LED_blink_time_unit*count_Morse && count_Morse < LED_time_unit_CONST/LED_blink_time_unit) { //===== intergap
    Serial.print("-|");
    count_Morse++;
    }

    } else if(morse_word[morse_index]=='\0'){
    LED_time_unit_CONST = LED_blink_time_unit * 3; //====================================== space between letters
    morse_index = 0;
    word_index++;
    LED_current_time = millis();
    }

    } else if(charac==' '){
    LED_time_unit_CONST = LED_blink_time_unit * 7; //======================================== space between words
    morse_index = 0;
    word_index++;
    LED_current_time = millis();

    } else {
    Serial.println("MORSE: not a character ");
    word_index++;
    }

    } else if(charac=='\0'){
    word_index = 0;
    morse_index = 0;
    LED_time_unit_CONST = LED_blink_time_unit * 7; //======================================== space between words
    LED_current_time = millis();

    } else {
    Serial.println("MORSE: 404:Failed ");
    word_index++;
    }

    }

Leave a Reply

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