# Morse Code Blinker with WS2812 LED
## Project Overview
This project creates a Morse code communication system using the built-in WS2812 LED on the Lonely Binary ESP32-S3. The LED blinks messages in Morse code, providing a visual communication method that can be used for debugging, status messages, or educational purposes.
### Learning Objectives
- Understand Morse code principles and timing
- Learn about string processing and character mapping
- Master precise timing control for communication
- Explore visual communication methods
- Develop systematic approach to encoding/decoding
## Understanding Morse Code
### What is Morse Code?
Morse code is a method of transmitting text information as a series of on-off tones, lights, or clicks that can be directly understood by a skilled listener or observer without special equipment. It was developed by Samuel Morse in the 1830s and 1840s.
### Morse Code Principles
- **Dots (.)**: Short signals (1 unit duration)
- **Dashes (-)**: Long signals (3 units duration)
- **Letter Space**: Gap between letters (3 units duration)
- **Word Space**: Gap between words (7 units duration)
### International Morse Code Chart
```
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: ----.
```
### Timing Standards
- **Dot Duration**: 1 unit (typically 0.2 seconds)
- **Dash Duration**: 3 units (typically 0.6 seconds)
- **Element Space**: 1 unit between dots/dashes in same letter
- **Letter Space**: 3 units between letters
- **Word Space**: 7 units between words
## Morse Code Blinker Implementation
### Basic Implementation
The Morse code blinker converts text messages into visual signals using the WS2812 LED. Each character is translated to its Morse code equivalent and then blinked using precise timing.
#### Code Explanation
```python
# morse_code.py - Blink messages in Morse code
import machine
import neopixel
import time
# Configure WS2812 LED on pin IO48
# neopixel.NeoPixel(pin, number_of_leds, bpp=3, timing=1)
np = neopixel.NeoPixel(machine.Pin(48), 1)
def set_color(r, g, b):
"""Set LED to specific RGB color"""
np[0] = (r, g, b) # Set the first (and only) LED
np.write() # Send the color data to the LED
def morse_code_blink(message="SOS"):
"""Blink LED in Morse code"""
# Morse code dictionary - maps letters to their Morse equivalents
morse_dict = {
'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': '--..', ' ': ' ' # Space character for word separation
}
print(f"Blinking Morse code: {message}")
# Process each character in the message
for char in message.upper(): # Convert to uppercase for consistency
if char in morse_dict: # Check if character has Morse equivalent
code = morse_dict[char] # Get Morse code for this character
print(f"'{char}' = {code}") # Debug output
# Process each signal in the Morse code
for signal in code:
if signal == '.': # Dot signal
set_color(255, 255, 255) # White LED ON
time.sleep(0.2) # Hold for 0.2 seconds
set_color(0, 0, 0) # LED OFF
time.sleep(0.2) # Gap between signals
elif signal == '-': # Dash signal
set_color(255, 255, 255) # White LED ON
time.sleep(0.6) # Hold for 0.6 seconds (3x dot)
set_color(0, 0, 0) # LED OFF
time.sleep(0.2) # Gap between signals
elif signal == ' ': # Word space
time.sleep(0.8) # Longer gap for word separation
time.sleep(0.6) # Letter space (3x element space)
print("Morse code complete!")
# Test different messages
messages = ["SOS", "HELLO", "WORLD"]
for message in messages:
morse_code_blink(message)
time.sleep(2) # 2 second pause between messages
```
#### Detailed Code Breakdown
**1. LED Configuration**
```python
np = neopixel.NeoPixel(machine.Pin(48), 1)
```
- Creates a NeoPixel object for the WS2812 LED
- Pin 48 is the data pin for the built-in LED
- `1` indicates we're controlling 1 LED
**2. Color Setting Function**
```python
def set_color(r, g, b):
np[0] = (r, g, b) # Set RGB values for LED
np.write() # Send data to LED
```
- `np[0]` accesses the first (and only) LED
- `np.write()` sends the color data to the LED
**3. Morse Code Dictionary**
```python
morse_dict = {
'A': '.-', 'B': '-...', 'C': '-.-.', ...
}
```
- Maps each letter to its Morse code equivalent
- Uses dots (.) and dashes (-) to represent signals
**4. Character Processing**
```python
for char in message.upper():
if char in morse_dict:
code = morse_dict[char]
```
- Converts message to uppercase for consistency
- Looks up each character in the Morse dictionary
- Gets the Morse code sequence for that character
**5. Signal Timing**
```python
if signal == '.':
set_color(255, 255, 255) # White ON
time.sleep(0.2) # Dot duration
set_color(0, 0, 0) # OFF
time.sleep(0.2) # Element space
```
- Dots: 0.2 seconds ON, 0.2 seconds OFF
- Dashes: 0.6 seconds ON, 0.2 seconds OFF
- Letter space: 0.6 seconds (3x element space)
- Word space: 0.8 seconds (longer gap)
## Conclusion
The Morse code blinker project demonstrates how a simple LED can be used for sophisticated communication. By understanding timing, character encoding, and visual signaling, you can create effective communication systems even with limited hardware.
The key to successful Morse code transmission is consistent timing and clear visual signals. Start with simple messages and gradually increase complexity as you become more comfortable with the timing and encoding principles.
This project serves as an excellent foundation for learning about communication protocols, timing-sensitive applications, and human-machine interfaces in embedded systems.
- Choosing a selection results in a full page refresh.