#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
#define BUZZER_PIN 9
#define LED_PIN 13
#define DOT_DURATION 200
#define DASH_DURATION 600
#define GAP_DURATION 200
#define LETTER_SPACE 600
#define WORD_SPACE 1400
// Morse code table for letters & numbers
const String morseTable[] = {
".-", "-...", "-.-.", "-..", ".", "..-.", "--.", "....", "..", ".---",
"-.-", ".-..", "--", "-.", "---", ".--.", "--.-", ".-.", "...", "-",
"..-", "...-", ".--", "-..-", "-.--", "--..", // A-Z
"-----", ".----", "..---", "...--", "....-", ".....", "-....", "--...", "---..", "----." // 0-9
};
// Special characters and their Morse code
const String specialChars[] = {".", ",", "?", "!", "@", "&", ":", ";", "(", ")", "=", "+", "-", "_", "/", " "};
const String specialMorse[] = {
".-.-.-", "--..--", "..--..", "-.-.--", ".--.-.", ".-...", "---...", "-.-.-.", "-.--.", "-.--.-",
"-...-", ".-.-.", "-....-", "..--.-", "-..-.", "/"
};
// Function to get Morse code for a character (stores in reference parameter)
void getMorseCode(char c, String &morseOut) {
morseOut = ""; // Clear output
if (c >= 'A' && c <= 'Z') {
morseOut = morseTable[c - 'A'];
return;
}
if (c >= '0' && c <= '9') {
morseOut = morseTable[c - '0' + 26];
return;
}
for (int i = 0; i < sizeof(specialChars) / sizeof(specialChars[0]); i++) {
if (String(c) == specialChars[i]) {
morseOut = specialMorse[i];
return;
}
}
}
// Function to display Morse code on OLED and play with buzzer/LED
void playMorse(String morse, char character) {
display.clearDisplay();
display.setTextSize(2);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 10);
display.print("Char: ");
display.print(character);
display.setCursor(0, 40);
display.print("Morse: ");
display.print(morse);
display.display();
Serial.print("Char: ");
Serial.print(character);
Serial.print(" Morse: ");
Serial.print(morse);
Serial.print(" | ");
for (int i = 0; i < morse.length(); i++) {
if (morse[i] == '.') {
tone(BUZZER_PIN, 1000, DOT_DURATION);
digitalWrite(LED_PIN, HIGH);
delay(DOT_DURATION);
} else if (morse[i] == '-') {
tone(BUZZER_PIN, 1000, DASH_DURATION);
digitalWrite(LED_PIN, HIGH);
delay(DASH_DURATION);
}
noTone(BUZZER_PIN);
digitalWrite(LED_PIN, LOW);
delay(GAP_DURATION);
}
delay(LETTER_SPACE);
}
// Function to process and play the full Morse code
void textToMorse(String message) {
message.toUpperCase();
String morseChar;
for (int i = 0; i < message.length(); i++) {
getMorseCode(message[i], morseChar);
if (morseChar.length() > 0) {
playMorse(morseChar, message[i]);
}
if (message[i] == ' ') {
delay(WORD_SPACE);
}
}
}
void setup() {
Serial.begin(9600);
pinMode(BUZZER_PIN, OUTPUT);
pinMode(LED_PIN, OUTPUT);
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println("SSD1306 allocation failed");
for (;;);
}
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(10, 20);
display.print("Morse Ready!");
display.display();
delay(2000);
display.clearDisplay();
Serial.println("Enter a message to convert:");
}
void loop() {
if (Serial.available() > 0) {
String input = Serial.readStringUntil('\n');
input.trim();
Serial.print("Message: ");
Serial.println(input);
textToMorse(input);
Serial.println();
Serial.println("Done! Enter another message:");
}
}