Files
WS2812B-LED-RC-Controller/ARCHITECTURE.md
2026-01-05 21:01:26 +01:00

391 lines
12 KiB
Markdown

# Architecture Documentation
## System Overview
The ESP32 LED Controller is a real-time embedded system designed for model aircraft LED control with the following key components:
```
┌─────────────────────────────────────────────────────────┐
│ Application Layer │
│ ┌──────────┐ ┌───────────┐ ┌──────────────────────┐ │
│ │ main.c │ │ Web-BLE │ │ Animation Patterns │ │
│ └────┬─────┘ └─────┬─────┘ └──────────┬───────────┘ │
└───────┼──────────────┼────────────────────┼─────────────┘
│ │ │
┌───────┴──────────────┴────────────────────┴─────────────┐
│ Control Layer │
│ ┌──────────────────────────────────────────────────┐ │
│ │ control.c - System Orchestration │ │
│ │ - BLE GATT Server │ │
│ │ - NVS Configuration Storage │ │
│ │ - OTA Firmware Update │ │
│ │ - Subsystem Initialization │ │
│ └──────────────────────────────────────────────────┘ │
└──────────────────────────────────────────────────────────┘
│ │ │
┌───────┼──────────────┼────────────────────┼─────────────┐
│ │ │ │ │
│ ┌────▼────┐ ┌────▼─────┐ ┌────▼─────────┐ │
│ │ LED │ │ RC Signal│ │ Animation │ │
│ │ Driver │ │ Reader │ │ Engine │ │
│ └─────────┘ └──────────┘ └──────────────┘ │
│ │
│ Hardware Layer │
└──────────────────────────────────────────────────────────┘
│ │ │
┌───────┼──────────────┼────────────────────┼─────────────┐
│ ┌────▼────┐ ┌────▼─────┐ │
│ │ RMT │ │ GPIO │ │
│ │ (WS2812)│ │ (PWM) │ │
│ └─────────┘ └──────────┘ │
│ │
│ ESP-IDF HAL & Drivers │
└──────────────────────────────────────────────────────────┘
```
## Module Details
### 1. main.c - Application Entry Point
**Responsibilities:**
- System initialization orchestration
- Animation task creation and management
- System health monitoring
- Error handling and recovery
**Key Functions:**
- `app_main()`: Entry point, initializes control system
- `animation_task()`: FreeRTOS task for 60 FPS animation updates
**Task Priority:** Animation task runs at priority 5 (above default)
---
### 2. control.c/h - System Control & Orchestration
**Responsibilities:**
- BLE GATT server implementation
- Configuration management (NVS)
- OTA firmware update handling
- Subsystem initialization and coordination
**BLE Service Structure:**
```
Service UUID: 0x00FF
├── Config Characteristic (0xFF01)
│ ├── Read: Get current configuration
│ └── Write: Update and persist configuration
├── Mode Characteristic (0xFF02)
│ ├── Read: Get current animation mode
│ └── Write: Set animation mode
├── PWM Emulation (0xFF03)
│ └── Write: Trigger mode change
└── OTA Characteristic (0xFF04)
└── Write: Stream firmware binary
```
**Configuration Storage:**
```c
typedef struct {
int8_t led_pin_strip_a; // -1 = disabled
int8_t led_pin_strip_b; // -1 = disabled
int8_t pwm_pin; // -1 = disabled
ble_timeout_t ble_timeout; // 0, 60, 300 seconds
uint32_t magic; // 0xDEADBEEF validation
} controller_config_t;
```
**NVS Namespace:** `led_ctrl`
**NVS Key:** `config`
**BLE Timeout Logic:**
- Timer starts at boot
- Pauses when device connects
- Resumes when device disconnects
- Disables BLE advertising on timeout
**OTA Update Flow:**
1. Client writes firmware data in 512-byte chunks
2. ESP32 writes to inactive OTA partition
3. Last chunk (< 512 bytes) triggers completion
4. Validates partition, sets boot partition
5. Resets configuration and restarts
---
### 3. led.c/h - WS2812B LED Driver
**Technology:** ESP32 RMT (Remote Control) peripheral
**Why RMT?**
- Hardware timing generation (no CPU overhead)
- Precise WS2812B timing requirements:
- T0H: 350ns ±150ns
- T0L: 900ns ±150ns
- T1H: 900ns ±150ns
- T1L: 350ns ±150ns
- Reset: >280µs
**Implementation:**
```
RMT Channel → Custom Encoder → WS2812B Strip
↓ ↓ ↓
80 MHz GRB Encoding Serial Data
```
**Color Management:**
- Internal RGB buffer for each strip
- Thread-safe access via mutex
- Hardware converts RGB → GRB for WS2812B
- Support for HSV → RGB conversion
**Key Functions:**
- `led_init()`: Configure RMT channels
- `led_set_pixel_a/b()`: Set individual LED
- `led_fill_a/b()`: Set all LEDs same color
- `led_show()`: Update physical LEDs
- `led_fade_to_black()`: Fade effect for trails
**Memory Usage:**
- Strip A buffer: num_leds * 3 bytes (RGB)
- Strip B buffer: num_leds * 3 bytes (RGB)
- Default: 44 LEDs * 2 strips * 3 = 264 bytes
---
### 4. rcsignal.c/h - PWM Signal Reader
**Technology:** GPIO interrupt + software edge detection
**PWM Signal Specification:**
- Standard RC PWM: 1000-2000µs pulse width
- Detection threshold: 1500µs
- Timeout: 100ms (signal loss detection)
**Mode Change Logic:**
```
PWM < 1500µs → Set "pull_detected" flag
PWM > 1500µs AND pull_detected → Mode++
pull_detected = false
```
**Implementation:**
- ISR captures rising/falling edges
- Calculates pulse width in microseconds
- Monitor task (10ms interval) detects mode changes
- Callback notifies animation system
**Thread Safety:**
- Volatile variables for ISR communication
- Monitor task runs at priority 5
---
### 5. animation.c/h - Animation Engine
**Update Rate:** 60 FPS (16.67ms per frame)
**Global State:**
- `global_hue`: Slow color cycling (updates every 3 frames)
- `frame_counter`: Frame synchronization
- `current_mode`: Active animation pattern
**Animation Techniques:**
#### Fade Effects
```c
// Smooth trails for chase animations
led_fade_to_black(amount);
// Each LED: color = (color * (255 - amount)) / 255
```
#### Beat Synchronization
```c
// Sine wave based on BPM and time
beatsin16(bpm, min_val, max_val);
// Returns position oscillating between min and max
```
#### HSV Color Space
- Hue: 0-255 (color wheel)
- Saturation: 0-255 (color intensity)
- Value: 0-255 (brightness)
- Automatic RGB conversion
**Animation Modes Breakdown:**
1. **Static Colors** (Black, Red, Blue, Green, White)
- Single `led_fill()` call
- No per-frame updates needed
2. **Rainbow**
- HSV hue gradient across strip
- Hue offset per LED: `global_hue + (i * 7)`
- Global hue increments for animation
3. **Rainbow Glitter**
- Base rainbow + random white sparkles
- 80/255 chance per frame
- Random LED position
4. **Confetti**
- Fade to black (10/255 per frame)
- Random position + random hue
- Creates "fireworks" effect
5. **Sinelon**
- Sweeping dot using sine wave
- Position: `beatsin16(13 BPM)`
- 20/255 fade creates trails
6. **BPM**
- Color palette based on party colors
- Beat: `beatsin8(33 BPM)`
- Brightness modulation per LED
7. **Navigation**
- Fixed positions for aviation lights
- Red: LEDs 0-2 (left)
- Green: Last 3 LEDs (right)
- White blink: 30 Hz (half frame rate)
8. **Chase (Red)**
- Red dot with ±2 LED trail
- Position: `beatsin16(40 BPM)`
- No fade (instant clear)
9. **Chase RGB**
- Same as Chase but HSV color cycling
- Hue: `global_hue`
10. **Random**
- Random LED, random color each frame
- Rare full clear event
---
## Data Flow
### Configuration Update Flow
```
Web Browser → BLE Write → control.c → NVS Save → Restart (if pins changed)
```
### Animation Update Flow
```
animation_task (60Hz) → animation_update() → LED buffer → led_show() → RMT → LEDs
```
### PWM Mode Change Flow
```
RC Signal → GPIO ISR → rcsignal.c → Callback → control.c → animation.c
```
### OTA Update Flow
```
Web Browser → BLE Write (chunks) → control.c → esp_ota → Flash → Restart
```
## Thread Safety
### Mutexes Used
1. **led_mutex**: Protects LED buffer access
- Used by: animation_update(), led_show()
- Type: FreeRTOS mutex
### ISR Safety
- **rcsignal.c**: Volatile variables for ISR communication
- **Minimal ISR work**: Only timestamp and edge detection
- **Deferred processing**: Monitor task handles logic
### Task Priorities
```
Priority 5: animation_task, rcsignal_monitor_task
Priority 1: BLE stack tasks (default)
Priority 0: Idle task
```
## Memory Management
### Static Allocation
- Configuration structure: 11 bytes (NVS)
- Animation state: ~100 bytes (global variables)
### Dynamic Allocation
- LED buffers: `num_leds * 3 * 2` bytes (both strips)
- RMT encoder: ~200 bytes per strip
- BLE stack: ~30KB (ESP-IDF managed)
### Flash Usage
- Code: ~500KB (with BLE stack)
- OTA partitions: 2x 1MB (dual-boot)
- NVS: 24KB
- Factory: 1MB
### Heap Usage Estimate
- Total: ~50KB during operation
- Available: ~250KB on ESP32
## Power Optimization
### Active Mode
- CPU: 240 MHz (animation processing)
- BLE: Active (advertising/connected)
- Power: ~180mA (ESP32 only)
### BLE Disabled Mode
- CPU: 240 MHz (animation only)
- BLE: Disabled after timeout
- Power: ~100mA (ESP32 only)
### LED Power
- Per LED: ~60mA at full white
- 44 LEDs full white: ~2.6A
- Typical animation: ~500mA average
## ESP32 vs ESP32-C3 Differences
### ESP32 (Xtensa)
- Dual-core: FreeRTOS symmetric multiprocessing
- BLE + Classic Bluetooth controller
- More GPIO pins available
- Recommended for complex projects
### ESP32-C3 (RISC-V)
- Single-core: Simpler task management
- BLE only (no Classic Bluetooth)
- Fewer GPIO pins
- Lower cost option
### Compatibility
- Same codebase works on both
- Pin numbers differ (check datasheet)
- RMT peripheral identical
- BLE functionality identical
## Performance Characteristics
### Latency
- **PWM detection**: <10ms
- **BLE command**: <100ms
- **Mode change**: <20ms (next frame)
- **LED update**: 16.67ms (60 FPS locked)
### Throughput
- **LED data**: ~13.44 Mbps theoretical (RMT)
- **BLE**: ~1 Mbps (limited by MTU)
- **OTA**: ~40 KB/s (BLE transfer)
### Timing Precision
- **Animation frame**: ±0.5ms jitter
- **WS2812B timing**: ±50ns (RMT hardware)
- **PWM measurement**: ±1µs (ISR timing)
---
## Future Enhancement Ideas TODO
1. **Dynamic LED Count**: Auto-detect number of LEDs
2. **Multi-Strip Sync**: Synchronized patterns
3. **Pattern Editor**: Visual animation designer
4. **Scheduler**: Time-based mode changes