#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128 // OLED display width
#define SCREEN_HEIGHT 64 // OLED display height
#define OLED_RESET -1 // Reset pin not used
#define OLED_ADDR 0x3C
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
#define BUZZER_PIN 9 // Buzzer pin
#define LED_PIN 13 // LED pin
#define DOT_DURATION 200 // Dot length (ms)
#define DASH_DURATION 600 // Dash length (ms)
#define GAP_DURATION 200 // Gap between dot/dash (ms)
#define LETTER_SPACE 600 // Gap between letters (ms)
#define WORD_SPACE 1400 // Gap between words (ms)
// Morse code table for letters & numbers
const String morseTable[] = {
".-", "-...", "-.-.", "-..", ".", "..-.", "--.", "....", "..", ".---",
"-.-", ".-..", "--", "-.", "---", ".--.", "--.-", ".-.", "...", "-",
"..-", "...-", ".--", "-..-", "-.--", "--..", // A-Z
"-----", ".----", "..---", "...--", "....-", ".....", "-....", "--...", "---..", "----." // 0-9
};
// Morse code table for special characters
const char specialChars[] = {'.', ',', '?', '!', '@', '&', ':', ';', '(', ')', '=', '+', '-', '_', '/', ' '};
const String specialMorse[] = {
".-.-.-", "--..--", "..--..", "-.-.--", ".--.-.", ".-...", "---...", "-.-.-.", "-.--.", "-.--.-",
"-...-", ".-.-.", "-....-", "..--.-", "-..-.", "/"
};
// Function to get Morse code for a character
String getMorseCode(char c) {
if (c >= 'A' && c <= 'Z') return morseTable[c - 'A'];
if (c >= '0' && c <= '9') return morseTable[c - '0' + 26];
// Check special characters
for (int i = 0; i < sizeof(specialChars); i++) {
if (c == specialChars[i]) return specialMorse[i];
}
return ""; // Ignore unsupported characters
}
// Function to display Morse code on OLED and play with buzzer/LED
void playMorse(String morse, char character) {
// Clear OLED display
display.clearDisplay();
display.setTextSize(2);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 10);
// Show character on OLED
display.print("Char: ");
display.print(character);
// Show Morse code on OLED
display.setCursor(0, 40);
display.print("Morse: ");
display.print(morse);
display.display();
// Print to Serial Monitor
Serial.print("Char: ");
Serial.print(character);
Serial.print(" Morse: ");
Serial.print(morse);
Serial.print(" | "); // Separator
// Play Morse code with buzzer & LED
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); // Turn off buzzer
digitalWrite(LED_PIN, LOW); // Turn off LED
delay(GAP_DURATION); // Short gap between dots/dashes
}
delay(LETTER_SPACE); // Gap between letters
}
// Function to process and play the full Morse code
void textToMorse(String message) {
message.toUpperCase(); // Convert to uppercase
for (int i = 0; i < message.length(); i++) {
String morseChar = getMorseCode(message[i]);
if (morseChar.length() > 0) {
playMorse(morseChar, message[i]); // Show character & Morse on OLED
}
if (message[i] == ' ') {
delay(WORD_SPACE); // Longer pause between words
}
}
}
void setup() {
Serial.begin(9600);
pinMode(BUZZER_PIN, OUTPUT);
pinMode(LED_PIN, OUTPUT);
// Initialize OLED display
if (!display.begin(SSD1306_SWITCHCAPVCC, OLED_ADDR)) {
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'); // Read user input
input.trim(); // Remove extra spaces
Serial.print("Message: ");
Serial.println(input);
textToMorse(input); // Convert text to Morse and output
Serial.println(); // Move to a new line after each message is processed
Serial.println("Done! Enter another message:");
}
}