Morse Code Transmitter
The Morse Code Transmitter turns the basic “blinking light” demonstration into a desktop app that transmits Morse code. Using an RGB LED module and a Buzzer module driven by an SMD Red, the project converts any text you type into audible + visual Morse code. A simple Tkinter GUI lets you enter the text, follow progress on a bar, and see the exact “dot-dash” string before you send it. All this feedback and these features help the user to understand Morse code better.
About Tools and Materials:
SMD USB Gateway (Purchase Here)
Arduino Gateway Module (Purchase Here)
RGB LED Module (Purchase Here)
Step 1: Hardware and Software Overview
SMD Red The SMD acts as a bridge between the script and the modules. It is responsible for interpreting the commands the script sends and translating them into actions that actuate the RGB LED Module and the Buzzer Module.
RGB LED Module Flashes white light for each dot or dash so you can “see” the code in real time. Long flashes for dashes and short flashes for dots.
Buzzer Module Generating short and long beeps that match the LED flashes adds an audible feedback to the user. This feedback helps the user follow along with the Morse code while reading it.
SMD Libraries The official Acrome SMD Python library handles low-level serial communication, device scanning, and module control, letting you focus on the Morse logic and GUI.
Project Key Features
Visual + Audible Morse Output
Every symbol is simultaneously flashed and beeped for clear feedback.
Real-time Progress Indicator
A GUI progress bar moves from 0% to 100% as the message transmits.
Dot-dash Visualization
The dots and dashes get visualized in the Tkinter UI.
Adjustable Timing
Modify the DOT_DURATION constant to speed up or slow down transmission of the Morse code.
Step 2: Assemble
Getting Started
Hardware Setup
Connect the SMD to the PC or Arduino board using the USB Gateway Module or the Arduino Gateway Module.
Connect the RGB LED Module and the Buzzer Module to the SMD using an RJ-45 cable.
Make sure that the SMD is powered and all connections are correct.
Project Wiring Diagram
Step 3: Run & Test
Install Libraries and Run the Script
Install necessary libraries such as Tkinter, serial, and acrome-smd.
Execute the script, initiating the Morse Code Transmitter project and opening the Tkinter UI where you can enter your text.
Experience the Morse Transmission
Observe the synchronized light and sound for each dot and dash.
Write longer texts to experience longer Morse transmissions.
Customize and Experiment
Experiment with changing symbol timings to create “fast” or “slow” Morse.
Explore switching LED colors
Codes
import os, sys
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
import time
import threading
import tkinter as tk
from tkinter import ttk, messagebox
from serial.tools.list_ports import comports
from platform import system
from smd.red import Master, Red
# Morse-code timing
DOT_DURATION = 0.2
DASH_DURATION = DOT_DURATION * 3
SYMBOL_PAUSE = DOT_DURATION
LETTER_PAUSE = DOT_DURATION * 3
WORD_PAUSE = DOT_DURATION * 7
# Morse lookup
def build_morse_map():
return {
'A': '.-', 'B': '-...', 'C': '-.-.', 'D': '-..', 'E': '.',
'F': '..-.', 'G': '--.', 'H': '....', 'I': '..', 'J': '.---',
'K': '-.-', 'L': '.-..', 'M': '--', 'N': '-.', 'O': '---',
'P': '.--.', 'Q': '--.-', 'R': '.-.', 'S': '...', 'T': '-',
'U': '..-', 'V': '...-', 'W': '.--', 'X': '-..-', 'Y': '-.--',
'Z': '--..',
'0': '-----', '1': '.----', '2': '..---', '3': '...--', '4': '....-',
'5': '.....', '6': '-....', '7': '--...', '8': '---..', '9': '----.'
}
MORSE_CODE = build_morse_map()
# Hardware layer
def find_usb_port():
ports = list(comports())
os_name = system()
usb_names = {
"Windows": ["USB Serial Port"],
"Linux": ["/dev/ttyUSB"],
"Darwin": ["/dev/tty.usbserial", "/dev/tty.usbmodem", "/dev/cu.usbserial"]
}
for port, desc, hwid in sorted(ports):
if any(name in port or name in desc for name in usb_names.get(os_name, [])):
return port
return None
class MorseHardware:
def __init__(self, port, baud=115200, smd_id=0, led_id=5, buzzer_id=5):
self.master = Master(port, baud)
self.master.attach(Red(smd_id))
self.master.scan_modules(smd_id)
self.smd_id = smd_id
self.led_id = led_id
self.buzzer_id = buzzer_id
def led_on(self):
self.master.set_rgb(self.smd_id, self.led_id, 255, 255, 255)
def led_off(self):
self.master.set_rgb(self.smd_id, self.led_id, 0, 0, 0)
def beep(self, dur):
# dur in seconds
ms = int(dur * 1000)
# Start beep
self.master.set_buzzer(self.smd_id, self.buzzer_id, ms)
time.sleep(dur)
# Stop beep
self.master.set_buzzer(self.smd_id, self.buzzer_id, 0)
def close(self):
ser = getattr(self.master, 'serial', None)
if ser and hasattr(ser, 'close'):
ser.close()
# Morse logic
def transmit_symbol(symbol, hw):
dur = DOT_DURATION if symbol == '.' else DASH_DURATION
hw.led_on()
hw.beep(dur)
hw.led_off()
time.sleep(SYMBOL_PAUSE)
def transmit_message(msg, hw, on_progress=None):
cleaned = msg.strip().upper()
symbols = [sym for ch in cleaned if ch != ' ' for sym in MORSE_CODE.get(ch, '')]
total = len(symbols)
count = 0
for word in cleaned.split():
for ch in word:
for sym in MORSE_CODE.get(ch, ''):
transmit_symbol(sym, hw)
count += 1
if on_progress and total:
on_progress(int(count / total * 100))
time.sleep(LETTER_PAUSE - SYMBOL_PAUSE)
time.sleep(WORD_PAUSE - LETTER_PAUSE)
if on_progress:
on_progress(100)
# GUI
def to_morse_string(msg):
words = []
for word in msg.strip().upper().split():
letters = [MORSE_CODE.get(ch, '') for ch in word]
words.append(' '.join(filter(None, letters)))
return ' / '.join(words)
class MorseGUI(tk.Tk):
def __init__(self):
super().__init__()
self.title("Morse Code Transmitter")
self.resizable(False, False)
port = find_usb_port()
if not port:
messagebox.showerror("Error", "No USB gateway detected.")
self.destroy()
sys.exit(1)
self.hw = MorseHardware(port)
ttk.Label(self, text="Enter message:").grid(row=0, column=0, padx=8, pady=(10, 2), sticky="w")
self.msg_var = tk.StringVar()
entry = ttk.Entry(self, textvariable=self.msg_var, width=42)
entry.grid(row=1, column=0, columnspan=2, padx=8, sticky="ew")
entry.focus()
self.msg_var.trace_add("write", self._update_code)
ttk.Label(self, text="Morse code:").grid(row=2, column=0, padx=8, pady=(6, 2), sticky="w")
self.code_lbl = tk.Label(self, text="", font=("Courier", 10), justify="left", wraplength=300)
self.code_lbl.grid(row=3, column=0, columnspan=2, padx=8, sticky="w")
self.tx_btn = ttk.Button(self, text="Transmit", command=self._start)
self.tx_btn.grid(row=4, column=0, padx=8, pady=10, sticky="e")
self.progress = ttk.Progressbar(self, mode="determinate", length=200)
self.progress.grid(row=4, column=1, padx=(0, 8), pady=10, sticky="w")
self.protocol("WM_DELETE_WINDOW", self._on_close)
def _update_code(self, *_):
self.code_lbl.config(text=to_morse_string(self.msg_var.get()))
def _start(self):
msg = self.msg_var.get().strip()
if not msg:
messagebox.showinfo("Input", "Enter a message.")
return
self.tx_btn.state(["disabled"])
self.progress["value"] = 0
threading.Thread(target=self._worker, args=(msg,), daemon=True).start()
def _worker(self, msg):
try:
transmit_message(msg, self.hw, self._prog)
except Exception as e:
messagebox.showerror("Error", str(e))
finally:
self.tx_btn.state(["!disabled"])
self.progress["value"] = 0
def _prog(self, p):
self.progress["value"] = p
def _on_close(self):
self.hw.close()
self.destroy()
if __name__ == '__main__':
MorseGUI().mainloop()
Last updated