391 lines
12 KiB
Markdown
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
|
|
|