This is a library that handles Morse code inputs and outputs on Phi-1 and Phi-2 shields, as pictured above. You can modify it to work on any display with a couple of buttons and a speaker. With this library, you can ask user to key in Morse code, get the character corresponding to the Morse code. You can also pass a string to the library and get it translated into di and dah output on a speaker. The example code is an interactive Morse code translator, which also shows off the elaborate Phi_prompt interactive user interface you may be interested in using.


I have always wanted to learn Morse code. Who knows when a fateful event happens and I could be stranded on an island with Morse code my only means of communication?! Anyway, I have made several attempt at a Morse code translator/trainer in the past. This is the most recent post with the trainer. Now it time to turn my codes into a library so others can readily use Morse code input/output in their own program without having to go through what I went through.

What it does:

Takes user keyed in Morse inputs and translates into characters.

Takes a text string and translates into Morse output on a speaker.

Determine the character corresponding to a string with di and dah. Eg. if you provide “.-..” the function will return ‘L’.

Pictures and Videos:

Here is a video of the example program in action on a Phi-2 shield:


A reference manual is included in the library download.

Sample code:

First you need to initialize the library. Please follow the sample code to initialize the library. These code snippets work after the initialization.

void morse_period(int p);

This sets the period of a di.

Eg. morse_period(90);

void morse_out(char* message);

This outputs the message to the speaker at the previously decided period.




char msg=”SOS”;


char morse_in(byte col, byte row);

This returns the character keyed in by the operator. The Morse code di and dah will be displayed at LCD location (col,row). So if you key in ‘L’, the Morse code “.-..” will display at location (col,row).

It calls morse_find() to determine the character.
Returns -1 if input is invalid – . combination.
Returns -2 if detected too long. This may be used as erase previous character.


char a=morse_in(10,0);

//This returns one character keyed in.

char morse_find(char *detected);

This returns a character if the provided character array detected is a valid Morse code sequence.

Returns -1 if the sequence is invalid.


char msg[]=”.-..”;

char ret;


Serial.print(ret); // This prints an L.

The following are static functions only called by the above library functions. You don’t need to call them anyway.

void di();

This makes a short beep corresponding to di.

void dah();

This makes a short beep corresponding to dah.

char di_or_dah(void);

This monitors the keypad and returns the following results:

Returns 0 if detected a pause. You can discard this value.
Returns -1 if detected up button.
Returns -2 if detected down button.
Returns -3 if detected left button. This may be used to erase previous character.
Returns -4 if detected right button. This may be used as adding space.
Returns -6 if detected escape button. This may be used to escape.
Returns -127 if detected invalid signal or too short.
Returns -128 if detected too long.
Returns ‘-‘ or ‘.’ otherwise
The function doesn’t check if enough pause is used after the – or .


Library and phi_morse translator project code:

Everything is on my libraries and code download page:

Click here

This version is compatible with Arduino 1.6.0

It needs phi_interfaces and phi_prompt (only for sample code) library version 1.6.0, both of which are on the download page.

Reference manual is included.

Sample code:

The library download includes an example project, the Morse code translator for Phi-2 shield. If you have a Phi-1 shield, please follow the instruction in the code to make one modification. It provides the following functions:

  • Interactive menu (constructed with phi_prompt library)
  • Encode: enter text and listen to Morse code di and dah (use up and down to cycle through characters and left right to move within a word)
  • Decode: key in di and dah and get translated into characters (use B button to key in Morse code, left and right to move cursor, escape to end)
  • Library: listen to Morse code of a bunch of preselected words, revise the code and add your words (function made possible by phi_prompt library)
  • Change Morse code translator speed
  • Show credit

If you like this project, please consider purchasing a Phi-2 shield.


First download the package, then extract the files under your Arduino Sketchbook/Libraries folder, so that the three files will be under c:/Arduino22/Sketchbooks/Libraries/phi_morse/ (Just example, your directory may be different)

Then install all dependent libraries listed in the dependencies section below.

Close all Arduino IDE windows.

Reopen Arduino IDE, open a sketchbook you want to use the phi_buttons. Then choose under the Arduino IDE menu Sketch->Import library->phi_morse

The Arduino IDE automatically creates a line in the beginning of your sketchbook: #include <phi_morse.h>

OK you’re done!

15 Responses to Phi_morse

  1. Pingback: Phi_morse library is rolled out « Liudr's Blog

  2. Pingback: Morse code translator new version « Liudr's Blog

  3. Drew says:

    Hi– Regarding your phi_morse device: can you tell me what the maximum programmable code speed is, either in Words-Per-Minute or dit/dah timing and element lengths? From your video I estimate the higher speed setting (“delay = 50 ms”) to be approx 20 WPM. I am asking because I would like to know if it is feasible to do code speeds up to at least 70 or 80 WPM with this device/library.

    Also, what waveform is being output to produce the sound? Is it a square wave? Is it possible to program the shape of the waveform (i.e., rise and fall times)?


    • liudr says:


      My code is based on the function millis(), which delays milliseconds. So if you just download my example with the interactive menu, you can go into the setting and change the delay (length of a di). Right now, min is 40ms and max is 200ms, determined by these two lines of code in the example_menu.ped:

      myIntegerInput.low.i=40; // Lower limit
      myIntegerInput.high.i=200; // Upper limit

      You may change it to any number you want but I don’t know if the Morse code is understandable by regular humans like me below 40ms 🙂 Go ahead and change it if you like anyway, it’s fun.

      BTW, when controlling the period by program, use this function to change period on the fly: morse_period(int millisecond).
      When indicating the delay at startup, this line does it, required to initialize the library in setup().

      init_morse(&lcd1, btns_1, &btn_5, buzzer, 90);

      So 90ms delay.

      • Drew says:

        Thanks. I should have clarified: I don’t currently have a microprocessor available to try your code library. I would like to develop a Morse Code player and am just trying to find out which microprocessor device might be suitable for my purposes.

        I suspect the question of whether the high speed code generated by such an application/device would be suitable is something I will have to determine by trial.

        BTW, Morse Code is quite humanly understandable at speeds higher than the 40ms limit you use, which is approx 2 Morse characters per second; even up to and well beyond five characters per second are possible. It takes lots of practice to attain such speeds, of course!

        Beside sufficient processor speed and instruction space I would also require a device that could access (read-only) a large memory space of stored ASCII text files; say at least 256 MB. I would hope to be able to play such files as Morse Code while being able to adjust pitch and speed. So, I am looking for the best micro device to accomplish this.

      • liudr says:


        I would strongly recommend the Arduino microcontroller platform. If you’re concerned with processor speed and memory, here it is:

        16MHz processor. Most commands takes 1 cycle
        accuracy of the delayMicrosecond() command is accurate to 4micro seconds, far exceeds your requirement.
        On memory issue, most microcontrollers don’t control that much memory such as 256MB. They store info on SD cards. You can get an SD card shield for arduino for around $20. Then you can go as much as a few gigs of space.

        Besides, arduino has the best online community and software library/hardware out there. Busy bees like myself develop both software and hardware for the platform every day.

  4. Mike says:

    Hi John,

    Thank-you for your excellent work on this Morse Library. I am curious how far it can be cut back to just allow the
    sending of precanned morse messages without having to use either Phi-1 or an attached LCD. I was thinking along the lines of a command number is received via serial and the corresponding morse is sent out. Any insight would be most helpful.

    • liudr says:

      Sorry for the late reply, the library needs no hardware support. You tell the hardware which digital pins are connected to the speaker and input key and that’s it. Everything else you see in videos are done extra to the library with the help of more software/hardware support on phi-1 or phi-2 shield.

  5. daniel says:

    hi ,
    im looking for a simple way to transmit a code over an rf link, i think this will be perfect, obviously the rf link is capable of transmitting morse, the code doesnt have to change, just a few preset ones dependant on external events,

    i hope to have a look through the code and work out how to adapt it,
    in the meantime if you have any suggestions ……… 🙂

    thanks for the hard work

  6. James says:

    I came across this while searching for a way to build a portable QRP CW-only rig in a Pelican case that included an automatic CW decoder (something I could leave in my Jeep, in case of emergencies). Your demonstrations show digital input, which seems to work quite well, but is it possible to have analog audio in (for example, RX being handed to the Arduino somehow) and still have the Morse be interpreted properly? It seems fairly easy to have the auto-transmit go out through the transceiver, even though I don’t plan on using that part, but the input is still somewhat confusing to me. Thanks.

    • liudr says:

      I am a novice using Morse code myself and didn’t try decoding audio. I suppose if you can filter the audio and feed it to an input that phi morse is treating as the button, you could. You need some circuit to do this though. I am thinking triggers could do it.

  7. Dan says:

    I love your project and would like to try and incorporate a IR Rx/Tx Morse Code trainer device. I see there are a couple of other libraries to get this to run.

    Can you help me figure out the process of this great project?

  8. Chaiyush says:

    I’m Ham radio…..I found this great project on youtube that make me very interesting on that. I downloaded main code and library (V5 for arduino 1.0). I have try to compile it on Arduino 1.6.5 (Current version ) but found that after complied it get me struck with many error. ……Its seam the code need to be revise match with Arduino current version (1.6.5) ……could you pls help to revise and convert it?


    • liudr says:


      I’m in the process to update my code. It will take me a few days before I get it all done and upload it. After that it will be Arduino 1.6.x compatible. Arduino folks always love to make us jump through hoops when they do something major. This time it was how the PROGMEM keyword is used, due to the fact they now include a more recent version of avr gcc. Fun stuff. Stay tuned.

Leave a Reply