Morse Code Translator

by Kartik Gupta in Circuits > Arduino

41 Views, 1 Favorites, 0 Comments

Morse Code Translator

Morse-Code-Apps-to-Learn-Type-in-Dots-Dash_4d470f76dc99e18ad75087b1b8410ea9.png

My last project in this course, is a Morse Code Translator that I assembled with an Arduino Uno coupled with LCD display. This project gives the user opportunity to enter words in Morse code through a button and to instantly see the converted letters on a screen. I selected this concept because I have always been interested in how the communication systems developed, especially the Morse code as one of the first kinds of digital signaling. It also was an excellent way of integrating timing-based interaction, output verifications, and troubleshooting of real-life situations with the help of Arduino framework. This project is also very code heavy and requires minimal circuitry which is a good thing for me as I believe that is one of my biggest strengths.


This project allowed me to put to practice all that I learned this semester: circuits and components such as buzzers and buttons, as well as how to write well-structured Arduino programs. It is also practical and informative and makes something historical into a project that can be extended digitally.

Downloads

Supplies

image_2025-06-15_120625196.png

IDEATE

de119a87e0cd148670611f0ddfab97b5.jpg
Research-a-book-featured-image-1080x628.jpg
5887-Figure3.png

My Project Idea: Morse Code Translator with Arduino

Why I chose it:

I wanted to build a project that uses real input (like a button press) and translates it into readable output (on an LCD). Morse code was the perfect system because it's based on short and long button presses — and it’s a great challenge that combines timing logic, LCD output, and code structure. I was also inspired by how early telegraphs worked, and I thought it would be fun to recreate something similar using modern tools.


Components I planned to use:

Component & Purpose

Arduino Uno Main - microcontroller

Pushbutton - Input Morse code (short/long presses)

LCD I2C Display (16x2) - Display translated letters

Breadboard + Jumper Wires - Building the circuit

Resistors (10kΩ) - For button pull-down

USB Cable - To power and upload code to Arduino

Buzzer - To make audio feedback on button press


Worklog Entry (for Step 1):

  1. I reviewed past Arduino projects we did (like LED blinkers, buzzer feedback, sensors).
  2. I decided I wanted something that uses timing and message display.
  3. I explored ideas like password systems, reaction timers, and Morse code.
  4. I picked Morse code because it's a challenge, it’s creative, and it allows me to use both analog timing logic and digital output.
  5. I listed components I’ll need and confirmed I have them available.

RESEARCH

image_2025-06-15_123033533.png
image_2025-06-15_123103949.png

Programming of the Morse code translator would require me to research how to work with buttons, timing manage and LCD display in Arduino.

The main problem was how to code a dot and a dash by means of a single button. I found out that I could count the duration of the button press by comparing it with millis(): when it took less than 200ms, I could construct dots, and when more than 200ms, dashes. This interpreting of Morse code depends on this timing based input.

I also read about the means of identifying spaces between letters and words by timing the time of releasing the button. As an individual example, in case of the pause duration more than 1.5s the program exits letter and converts the stored dot/dash sequence to a letter. There is a space between words as the pause is longer (e.g. 5 seconds).

I learnt to operate an I2C LCD display with Arduino in order to present the decoded text. Working with LiquidCrystal_I2C library helped me to wire easier and print characters and easily control the cursor location.

  1. I gained knowledge in organizing the code as follows:
  2. Saving Morse entries in coded form: as strings of dots and dashes.
  3. Developing procedures to decode to letters in Morse strings.
  4. Controlling editing of cursor and blacking screen.
  5. Monitoring both button presses and releases, using state variables, without code blocking.


Some of these ideas appeared in other Arduino tutorials, such as on debouncing the button, non-blocking time-based in milliseconds () and algorithm to translate Morse Code to text. A combination of them allowed me to create clean and efficient code that would be good when applied to real-time Morse code input.

BUILD & CODE

image_2025-06-15_124505019.png
image_2025-06-15_124734820.png

The Build:


Physical arrangement contains:


  1. Arduino Uno (mind of the project)
  2. A single button that is used to enter Morse code (by short or long presses)
  3. A single clear button which cleans the LCD screen
  4. Output- 16x2 I2C LCD display to output translated text
  5. Clean and neat connections are done by using breadboard, wires and resistors


Its parts have been hooked up easily:


  1. The Morse entry button is connected to pin 8 digital.
  2. The clear button gets connected to pin 9 digital
  3. The A4 and A5 are utilized to I2C with the LCD


The Code


The most difficult and exciting was the code. I organized it into a number of functions and they each had a specific feature:


void setup()

  1. Initial Censor LCD and set up modes of the pins.
  2. Starts serial transmission (to debug it).
  3. Positioning is the first cursor on the LCD.
  4. Initialize both buttons as input


void loop()

  1. The loop is repeated and takes care of everything that goes on in the real-time. It:
  2. Reads both the Morse on and clear buttons.
  3. Pressed to start a timer by pressing the Morse button.
  4. Computes the length of a press to know whether it is a dot or a dash.
  5. Inserts the Morse code in a string buffer (buff).
  6. Identifies gaps to determine the time to convert the buffer into a letter.
  7. Returns the buffer to be translated and showing the character.
  8. Can add space in case the pause lasts so long to convey word break.
  9. Clears the screen when reset button is pressed.


Function Seperation:


void updateState()

  1. Invoked upon a depression of the morse button.
  2. Records the duration that the button was pressed.
  3. Short press tacked on a -.- (dot, dot, dot).
  4. Adds a -, in case of long presses (dash).
  5. To accurately time things non-blocking, used millis().


String retBuf()

  1. Transforms the Morse buffer to the readable letter morseToChar().
  2. Returns the resulting character as an ascii string.


String morseToChar(String& morse)

  1. Scans an already defined Morse array (letters[]) to find a match.
  2. Returns the the A-Z character corresponding to it should it be found.
  3. Makes a call to the printToLCD and prints the result.
  4. Returns "ERROR" in case the MorseCode is not valid.


void clearBuf()

  1. Resets the Morse buffer string so a new letter can be entered.


char void printToLCD(char c)

  1. Position a character at the character position of a current LCD cursor.
  2. Chooses right after characters.
  3. Resets and clears the screen and cursor in case of a filled up screen.


void clearScreen()

  1. Clears the LCD and restores the cursor at the top-left.


What I Learned In Coding:


The project made me learn:

  1. About how to use millis() to track input real-time as opposed to delay()
  2. The programming of how to read the press of the buttons and accumulation of the hold time
  3. The next question is how to employ arrays to map from inputs to outputs (Morse to English)?
  4. I2c and cursor control on how to manage an LCD screen
  5. The methods of creating and cleaning up the modular code by breaking functions into tasks

REFINE

image_2025-06-15_125840402.png

Once having created the basic build and code, I was able to find some areas to optimize that boosted the consistency and overall usability of the Morse code translator in a major way.


Code Optimizations

Fixed Timing Bug Unsigned long

Initially I had int variables to hold the values of time of millis() which caused results to be found incorrect with value overflowing. These bugs were fixed by changing all time variables to unsigned long and the results were much better with button presses being detected much more accurately.


Better Dot/Dash Decoding Depth

Initially, the code would have difficulty differentiating a short and a long press. By experiment I was able to optimize its timing threshold a bit ( e.g. 300ms ) which was a significant enhancement in the accurateness with which it interpreted dots and dashes.


Functions in Modular Code

I broke down repeated code into specific functions such as morseToChar () and clearLCD () so as to make the program more readable and easy to maintain and modify. It also cleared up the loop() and made it less cluttered.


Physical Improvements

New Clear Button

The second button was included to reset the LCD, and due to it, users could easily clear their typing and start over without restarting Arduino.


Neat Wiring Diagram

I rewired the breadboard with color-coded jumper wire. This turned the circuit more presentable, simpler to debug and document as well as demo.

Downloads