Getting Started
Everything you need to set up Morse-Pi and start practicing Morse code.
Quick Start
SSH into your Raspberry Pi and run these three commands:
1. Update package lists
sudo apt update
2. Upgrade installed packages
sudo apt upgrade -y
3. Install Morse-Pi (Rust backend)
curl -sSL https://raw.githubusercontent.com/Nerd-or-Geek/Morse-Pi/main/install-rust.sh | sudo bash
http://<your-pi-ip>:5000
sudo reboot after the installer finishes to activate the kernel modules.
Features
| Feature | Description |
|---|---|
| SEND mode | Key Morse in real time and watch character-by-character decoding |
| ENCODE | Type any text and see the Morse equivalent instantly |
| DECODE | Enter dots and dashes, get the decoded text — quiz-style training |
| SPEED trainer | Practice sending at a target WPM and get scored on accuracy |
| STATS | Track accuracy, longest streak, and session history |
| Farnsworth timing | Stretch gaps between letters and words — great for beginners |
| Multi-Pi networking | Discover other Morse-Pi devices on your LAN and exchange messages |
| USB HID Keyboard | Pi acts as a USB keyboard — decoded Morse becomes real keystrokes |
| On-screen keys | Works without hardware: Space = straight key, Z/X = paddles |
| Physical GPIO key | Connect a real Morse key or iambic paddle via GPIO pins |
| Configurable tones | Separate dot/dash frequencies, volume, and WPM — all from the browser |
| Dual-pin speaker | Push-pull differential drive across two GPIO pins for louder, cleaner audio |
| Dark/light themes | Switch between dark and light UI from CONFIG |
Requirements
Minimum (software only)
- Rust backend: Any Linux system with a Rust toolchain (installed automatically)
- Python backend: Any computer with Python 3.9+
- A modern browser on the same machine or network
Full hardware setup (Raspberry Pi)
- Raspberry Pi — any model with 40-pin GPIO (Pi 3B+, Pi 4, Pi Zero 2 W, etc.)
- A piezo buzzer or small speaker wired to one or two GPIO pins
- A Morse key (straight key) or iambic paddle (two contacts)
For USB HID Keyboard mode
- Pi Zero, Zero W, Zero 2 W, or Pi 4 (must support USB OTG)
- A USB data cable (not power-only)
- Connect via the USB data port (on Pi Zero, the port labeled "USB" — not "PWR")
Installation
Option A — Rust backend Recommended
The Rust backend compiles to a single native binary with no runtime dependencies. SSH into your Raspberry Pi and run:
curl -sSL https://raw.githubusercontent.com/Nerd-or-Geek/Morse-Pi/main/install-rust.sh | sudo bash
The installer performs four steps:
- USB HID Keyboard Gadget — configures the Pi to appear as a USB keyboard when plugged into a computer
- Rust Toolchain — installs
rustup,cargo,pigpiodev headers, andbuild-essential - Build — clones the repo and runs
cargo build --release --features gpio - Auto-start — creates a systemd service so Morse-Pi runs on every boot
Option B — Python backend
The original Python/Flask backend. Faster to install, easier to modify:
curl -sSL https://raw.githubusercontent.com/Nerd-or-Geek/Morse-Pi/main/install.sh | sudo bash
The installer performs four steps:
- USB HID Keyboard Gadget — configures the Pi to appear as a USB keyboard
- Packages — installs
python3,pip,git,flask,gpiozero,pigpio - Repository — clones the code to
/opt/morse-pi - Auto-start — creates a systemd service so Morse-Pi runs on every boot
sudo reboot after the installer finishes.
Once running, open your browser to the IP address shown on screen:
http://192.168.1.42:5000
Switching from Python to Rust
Already running the Python backend? Transition in-place without losing your settings:
curl -sSL https://raw.githubusercontent.com/Nerd-or-Geek/Morse-Pi/main/transition-rust.sh | sudo bash
This installs the Rust toolchain, builds the binary, backs up your data, replaces the Python files, and restarts the service.
Manual installation (Rust)
# 1. Clone
git clone https://github.com/Nerd-or-Geek/Morse-Pi.git
cd Morse-Pi/morse-translator-rust
# 2. Install Rust toolchain
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
source "$HOME/.cargo/env"
# On Raspberry Pi, also install GPIO deps:
sudo apt install libpigpio-dev pigpio build-essential -y
sudo systemctl enable pigpiod --now
# 3. Build and run
cargo build --release --features gpio
./target/release/morse-pi
Manual installation (Python)
# 1. Clone
git clone https://github.com/Nerd-or-Geek/Morse-Pi.git
cd Morse-Pi
# 2. Install dependencies
sudo pip3 install flask --break-system-packages
# On Raspberry Pi, also:
sudo apt install python3-gpiozero pigpio python3-pigpio -y
sudo systemctl enable pigpiod --now
sudo usermod -aG gpio $USER
# 3. Run
cd morse-translator
python3 app.py
Then open http://localhost:5000 (or the Pi's IP from another device).
GPIO Wiring
Straight key (single-pin mode)
| Component | GPIO (BCM) | Physical Pin | Notes |
|---|---|---|---|
| Key signal | 17 | Pin 11 | Active-low (key shorts pin to GND) |
| Key ground | GND | Pin 9 or 14 | |
| Speaker + | 18 | Pin 12 | Speaker pin 1 |
| Speaker − | 13 | Pin 33 | Speaker pin 2 (push-pull) |
Iambic paddle (dual-pin mode)
| Component | GPIO (BCM) | Physical Pin | Notes |
|---|---|---|---|
| Dot paddle | 22 | Pin 15 | Active-low |
| Dash paddle | 27 | Pin 13 | Active-low |
| Speaker + | 18 | Pin 12 | Speaker pin 1 |
| Speaker − | 13 | Pin 33 | Speaker pin 2 (push-pull) |
GPIO header pinout (subset)
Ground output pins
If your paddle's common wire is soldered to a GPIO pin instead of a physical GND pin, you can assign that GPIO as a Ground Output in the CONFIG or diagnostic panels. The Pi will drive that pin permanently LOW so it acts as a ground reference.
Modes & Tabs
The Morse-Pi web UI is a single-page application with nine tabs along the top navigation bar:
| Tab | Purpose |
|---|---|
| SEND | Key Morse code in real time → live decoded text |
| ENCODE | Type plaintext → see Morse translation |
| DECODE | Quiz: see Morse → type the decoded answer |
| SPEED | Speed drill: key a phrase, measure WPM and accuracy |
| KB | USB HID keyboard settings and output |
| STATS | Accuracy and streak statistics |
| CONFIG | All settings (pins, tones, WPM, theme, Farnsworth, etc.) |
| RADIO | Multi-Pi networking: discover peers, send/receive messages, and live transmit |
| HELP | Built-in reference for shortcuts, wiring, and mode descriptions |
SEND Mode
SEND is the primary Morse code practice mode. Key Morse using your hardware key, on-screen buttons, or keyboard shortcuts, and watch your input decoded in real time.
How it works
- Press and hold your key (or Space) to generate dots and dashes
- The symbol buffer shows your current dots/dashes as you key them
- After a letter gap (3 dot units of silence), the character is decoded and appended to the output
- After a word gap (7 dot units), a space is inserted
Input methods
| Method | How |
|---|---|
| Straight key (single pin) | Physical key on GPIO or Space bar — duration determines dot vs dash |
| Iambic paddle (dual pin) | Physical paddles on GPIO or Z (dot) / X (dash) keys |
| On-screen buttons | Click/tap the DOT and DASH buttons in the UI |
dot_unit = 1200ms / WPM.
ENCODE Mode
Type or paste any text into the input field and instantly see the Morse code translation. Each character is broken down showing the letter and its Morse equivalent.
- Click Play to hear the Morse code through the buzzer/speaker
- Supports letters A–Z, numbers 0–9, and common punctuation
- Spaces between words are shown as
/
DECODE Mode
A quiz-style trainer: the app shows a random word or phrase in Morse code. You type your decoded answer and submit.
- Difficulty levels: Easy (short words), Medium, Hard (longer phrases)
- Click Play to hear the Morse phrase as an audio hint
- Tracks correct answers, wrong answers, current streak, and best streak
- New phrase generated on each submission or when switching to DECODE mode
SPEED Trainer
A speed drill that measures how fast and accurately you can key a displayed phrase.
- A phrase is displayed on screen
- Key the phrase using your paddle or keyboard
- A timer starts automatically when you begin keying
- Submit when done — the app compares your keyed Morse with the expected phrase
Results include:
- WPM — your measured words-per-minute
- Accuracy — character-by-character comparison
- Elapsed time
USB Keyboard (KB)
The KB tab controls USB HID keyboard mode. When enabled, decoded Morse characters are sent as real keystrokes to whatever computer the Pi is plugged into via USB.
| Mode | Behavior |
|---|---|
| Letters | Each decoded Morse character is sent as the corresponding keystroke. |
| Custom | Each dot/dash paddle press immediately sends a configured key (default Z/X). No decoding — raw key mapping. |
See the USB HID Keyboard page for full setup and configuration details.
Networking (RADIO)
Multiple Morse-Pi devices on the same LAN automatically discover each other — no configuration needed.
How discovery works
- Each Pi broadcasts a UDP beacon on port 5001 every 3 seconds
- The beacon contains the device name, IP address, and port
- Other Pis listen for these beacons and maintain a peer list
- Peers that haven't been seen for 15 seconds are automatically removed
Sending messages
- Open the RADIO tab
- Select a discovered peer from the list
- Type a message and click SEND, or key Morse using your paddle and send the decoded text
- The message is sent via HTTP to the peer's
/receive_morseendpoint - The receiving Pi plays the message through its speaker and shows it in the inbox
http://<pi-ip>:5000/network.
The older /radio URL is still supported as a compatibility alias.
Statistics
The STATS tab shows your practice history:
- Total attempts — decode and speed drills combined
- Correct answers
- Current streak — consecutive correct answers
- Best streak
Stats are saved to stats.json and persist across restarts and updates. Click Reset to start fresh.
Configuration
All settings are configurable live from the CONFIG tab — no files to edit, no restarts needed.
See the Settings Reference for a full table of every setting.
Key sections
- Input Mode — switch between straight key (single pin) and iambic paddle (dual pin)
- Pin Assignment — choose which BCM pins are used for data, dot, dash, speaker, and ground
- Audio — dot frequency, dash frequency, volume, output type (speaker PWM or LED on/off)
- Speed — WPM target with a "Test WPM" button that plays "PARIS" at the configured speed
- Farnsworth Timing — toggle extra spacing on/off and set Farnsworth speed (WPM) below Character WPM
- Quiz — difficulty level and word categories
- Theme — dark or light UI theme
- Device Name — the name shown to other Pis on the network
Keyboard Shortcuts
| Key | Action |
|---|---|
| Space | Straight key — hold to dash, tap to dot |
| Z | Dot paddle (iambic / dual-pin mode) |
| X | Dash paddle (iambic / dual-pin mode) |