A single-key Morse-code communicator built on the ESP32-C5, in two independent designs — a BLE HID keyboard (v1) and a pairing-free wireless link between units (v2).
![]() |
![]() |
|---|---|
| v1 · Morse Keyer → | v2 · Morse Link → |
| 🎥 Watch v1 on YouTube | 🎥 Watch v2 on YouTube |
Both versions strip a keyboard down to a single physical button. Press it in short (dot) and long (dash) patterns; the device decodes the sequence into a character (A–Z, 0–9) and shows it on a tiny 0.85-inch display. The difference is where the character goes:
- v1 — Morse Keyer sends it as a real BLE HID keystroke to a paired host (macOS / iOS / Android), so the device acts as a one-key Bluetooth keyboard. It also doubles as a standalone Morse-code practice tool — the live on-screen decoding gives instant feedback on your keying even with no host connected.
- v2 — Morse Link broadcasts it over ESP-NOW directly to other units — no phone, no host, no pairing — turning a pair of devices into a standalone two-way Morse communicator.
The two folders are fully self-contained ESP-IDF projects; pick the one that matches what you want to build.
v1 · Morse Keyer — BLE HID keyboard
🎥 Watch the v1 demo on YouTube →
A single-key wireless keyboard that turns Morse button presses into genuine BLE keyboard reports sent to any paired host — and, just as importantly, a standalone tool for learning and practicing Morse code.
- Morse practice tool — live on-screen symbols and instant decoding give immediate feedback on your keying, usable as a trainer even with no host connected
- BLE HID keyboard — standard 8-byte HID report, no custom host driver
- Cross-platform — tested on macOS, iOS, and Android
- Secure pairing with bonding — LE Secure Connections, bond stored in NVS
- Bond recovery — auto re-advertises as
MC_Pairafter repeated link failures - NimBLE host stack on ESP-IDF 5.5.4
→ Full documentation: v1-Morse_Keyer/README.md
v2 · Morse Link — pairing-free ESP-NOW
🎥 Watch the v2 demo on YouTube →
Two (or more) units talk to each other directly over ESP-NOW — no phone, no host, no pairing. Each unit is both transmitter and receiver and shows sent (white) and received (green) characters live.
- Bidirectional ESP-NOW link — broadcast to all peers, zero pairing
- Long-Range (LR) PHY — 250 Kbps at 20 dBm for greatly extended reach
- Redundant, seq-tagged transmit — survives an edge-of-range frame loss
- Selectable antenna — on-board PCB or external IPEX/u.FL via RF switch
- Live RSSI signal meter and public / private network isolation
→ Full documentation: v2-Morse_Link/README.md
| v1 · Morse Keyer | v2 · Morse Link | |
|---|---|---|
| Role | One-key BLE keyboard | Two-way device-to-device link |
| Talks to | A paired host (macOS / iOS / Android) | Other units running the same firmware |
| Wireless | BLE 5 HID (NimBLE / HOGP) | ESP-NOW broadcast, Long-Range PHY |
| Pairing | Secure pairing + bonding | None — power on and go |
| Board | ESP32-C5-WiFi6-KIT (Li-Po + charger) | ESP32-C5-Zero (ultra-compact) |
| Power | 3.7 V Li-Po over USB-C | 5 V USB power bank over USB-C |
| Antenna | On-board | On-board or external IPEX/u.FL |
Both versions share the same physical and software foundation:
- MCU — Espressif ESP32-C5 (RISC-V, 240 MHz, Wi-Fi 6 + BLE 5 + 802.15.4)
- Key module — Waveshare 0.85inch ScreenKey: one MX-compatible part providing both the 0.85-inch IPS display (ST7735, 128 × 128, RGB565) and the mechanical button
- UI — LVGL v9.5.0 via
esp_lvgl_port, over a 4-wire SPI ST7735 driver - Button — Espressif
buttoncomponent, with the same short/long/hold gestures - Build — ESP-IDF 5.5.4 + CMake/FreeRTOS
- Enclosure — a custom 3D-printed two-part case (
Body_Case.stl+Lid.stl) in each version's3d_print/folder
| Action | Result |
|---|---|
| Short press (< 300 ms) | Add dot . to current sequence |
| Long press (≥ 300 ms, < 3 s) | Add dash - to current sequence |
| 1 second silence | Decode accumulated sequence → send the character |
| Press & hold ≥ 3 s | Clear the current sequence and history |
.
├── v1-Morse_Keyer/ # BLE HID keyboard (see its README.md)
│ ├── main/ # main.c, ble_hid/, lcd_driver/, lvgl_driver/
│ ├── 3d_print/ # enclosure STLs
│ └── misc/ # photos & demo gif
└── v2-Morse_Link/ # Pairing-free ESP-NOW link (see its README.md)
├── main/ # main.c, espnow_comm/, lcd_driver/, lvgl_driver/
├── 3d_print/ # enclosure STLs
└── misc/ # photos & demo gif
Each version builds and flashes independently with the standard ESP-IDF flow
(idf.py build flash monitor) from inside its own folder.
See LICENSE.



