Project showcase
Morse Encoder & Displayer

Morse Encoder & Displayer © MIT

This project encodes serial messages into Morse code, and displays the characters on an LCD screen at the same time.

  • 1,587 views
  • 3 comments
  • 11 respects

Components and supplies

Apps and online services

About this project

This project is an Arduino program, that listen to the serial port (reception/emission) and outputs two things:

  • Firstly, it convert the text you sent it into morse, and emit it via pin 11 (you may want to connect to a potentiometer in serie with a buzzer).
  • Secondly, in the same time, on the LCD screen, it writes the letter it is encoding and prints the morse code on the second line. When it reaches the end of the first line, it clears the line.

It also send back what it received, prefixed with "Received: ".

When it does not recognize a character, it buzzes the length of 4 dots then wait the equivalent of 2 dots, send an error message with the character it didn't recognized and its binary value on the serial, and replace the character with a "?" on the LCD screen.

I have an idea to upgrade this project: add a third potentiometer to control the duration of a dot/dash/pauses.

Code

Arduino fileArduino
Copy and paste it into your Arduino project editor to use it
#include <LiquidCrystal.h>

LiquidCrystal lcd(2, 3, 4, 5, 6, 7);

#define BUZZER 11

#define SMALLER_DELAY 128

PROGMEM const uint8_t morse_code_a_z[26] = {
  0b01100000, // A .-
  0b10010101, // B -...
  0b10011001, // C -.-.
  0b10010100, // D -..
  0b01000000, // E .
  0b01011001, // F ..-.
  0b10100100, // G --.
  0b01010101, // H ....
  0b01010000, // I ..
  0b01101010, // J .---
  0b10011000, // K -.-
  0b01100101, // L .-..
  0b10100000, // M --
  0b10010000, // N -.
  0b10101000, // O ---
  0b01101001, // P .--.
  0b10100110, // Q --.-
  0b01100100, // R .-.
  0b01010100, // S ...
  0b10000000, // T -
  0b01011000, // U ..-
  0b01010110, // V ...-
  0b01101000, // W .--
  0b10010110, // X -..-
  0b10011010, // Y -.--
  0b10100101, // Z --..
};

void send_bit(const bool& dash) {
  lcd.print(dash ? '-' : '.');
  analogWrite(BUZZER, 63);
  delay((dash ? 3 : 1) * SMALLER_DELAY);
  digitalWrite(BUZZER, LOW);
  delay(1 * SMALLER_DELAY);
}

uint8_t hpos = 0;

void send_char(const char& c) {
  // Send the character to the LCD
  lcd.setCursor(hpos++, 0);
  lcd.print(c);
  
  // Position the cursor to the next line to start the .- sequence
  lcd.setCursor(0, 1);
  lcd.print("     ");
  lcd.setCursor(0, 1);
}

void print_number(const char& number) {
  if (!isDigit(number)) return;

  send_char(number);
  
  uint8_t num = number - '0';
  for (uint8_t i = 0 ; i < 5 ; i++) {
    if (num == i) num += 10;
    
    if (num < 6 + i) send_bit(false);
    else send_bit(true);
  }
}

void print_character(char character) {
  if (!isAlpha(character)) return;

  if (isLowerCase(character)) character += 'A' - 'a';

  send_char(character);

  uint8_t code = morse_code_a_z[character - 'A'];
  while (code != 0) {
    switch (code >> 6) {
      case 0:
      break;
      case 1:
      send_bit(false);
      break;
      case 2:
      send_bit(true);
      break;
      case 3:
      Serial.print("Error while printing character: ");
      Serial.println(character);
      Serial.print("Got 3 in the 2 leftmost bits of code ");
      Serial.println(code, BIN);
      break;
      default:
      Serial.print("Error while printing character: ");
      Serial.println(character);
      Serial.print("Got ? in the 2 leftmost bits of code ");
      Serial.println(code, BIN);
    }
    code <<= 2;
  }
}

void print_whitespace() {
  send_char(' ');
  delay(3 * SMALLER_DELAY);
}

void print_char(const char& character) {
  if (isWhitespace(character)) print_whitespace();
  else if (isAlpha(character)) print_character(character);
  else if (isDigit(character)) print_number(character);
  else if (isPunct(character)) { send_char(character); delay(1 * SMALLER_DELAY); }
  else if (character == '\0') {}
  else if (character == '\1') { /* This happens at the end of every string, don't know why */ }
  else {
    Serial.print("Error: unknown character ");
    Serial.print(character);
    Serial.print(" (0b");
    Serial.print((uint8_t)character, BIN);
    Serial.println(")");
    send_char('?');
    analogWrite(BUZZER, 63);
    delay(4 * SMALLER_DELAY);
    digitalWrite(BUZZER, LOW);
    delay(1 * SMALLER_DELAY);
  }
  
  delay(2 * SMALLER_DELAY);
}

void print_string(const char* characters, int len = 15) {
  for (uint8_t pos = 0 ; pos <= len ; pos++) {
    print_char(characters[pos]);
  }
}

void reset_LCD() {
  hpos = 0;

  lcd.clear();
  lcd.noCursor();
  lcd.setCursor(0, 0);
}

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  
  lcd.begin(16, 2);
  reset_LCD();

  pinMode(BUZZER, OUTPUT);
}

char* readStr() {
  uint8_t idx = 0;
  char* str = (char*)malloc(128 * sizeof(char));
  
  while (Serial.available() && idx < 128) {
    str[idx] = Serial.read();
    idx++;
    delay(2);
  }
  for ( ; idx < 128 ; idx++) {
    str[idx] = '\0';
  }

  return str;
}

void serialEvent() {
  while (Serial.available()) {
    char* string;
    Serial.setTimeout(-1);
    string = readStr();
    Serial.print("Received: ");
    Serial.println(string);
    
    char substr[16];
    for (uint8_t c = 0 ; c < 128 && string[c] != '\0' && string[c] != '\r' && string[c] != '\n' ; c += 16) {
      for (uint8_t offset = 0 ; offset < 15 ; offset++) {
        if (string[c + offset] != '\0' && string[c + offset] != '\r' && string[c + offset] != '\n') {
          substr[offset] = string[c + offset];
        } else {
          substr[offset] = '\0';
        }
      }

      reset_LCD();
      print_string(substr);
    }

    free((void*)string);
  }
  lcd.setCursor(0, 1);
  lcd.print("     ");
  lcd.setCursor(0, 0);
}

void loop() {
}

Schematics

Fritzing file
This is the sketch of this project. Use it with Fritzing.
morse_sketch_BKx2zBzzgq.fzz

Comments

Author

Default
rajdakin
  • 1 project
  • 1 follower

Additional contributors

  • Giving me the inspiration by Arduino team

Published on

March 3, 2019

Members who respect this project

AdambenzPhotoDefaultPhotoXi logo o5kcouvjnuProfilepic

and 5 others

See similar projects
you might like

Similar projects you might like

Morse Code Machine

Project showcase by brzi

  • 3,152 views
  • 1 comment
  • 7 respects

Morse Code Translator

Project showcase by Team ONYX

  • 12,557 views
  • 2 comments
  • 16 respects

RFID Based Automatic Door System

Project showcase by Robodia Technology

  • 37,817 views
  • 22 comments
  • 102 respects

Start/Stop Chronometer

Project showcase by Gabriele Scordamaglia

  • 4,135 views
  • 0 comments
  • 5 respects

AI LCD friend!

Project tutorial by aip06

  • 3,728 views
  • 8 comments
  • 7 respects

Multifunctional Watch With Arduino Uno

Project showcase by shaqibmusa94

  • 3,282 views
  • 2 comments
  • 8 respects
Add projectSign up / Login