243 lines
6.7 KiB
Markdown
243 lines
6.7 KiB
Markdown
# TasmotaLED
|
||
|
||
A lightweight, high-performance library for controlling addressable LED strips on ESP32 microcontrollers.
|
||
|
||
## Overview
|
||
|
||
TasmotaLED is a streamlined replacement for NeoPixelBus, designed specifically for the Tasmota firmware. It focuses on efficient pixel pushing with minimal memory overhead while supporting multiple hardware acceleration methods.
|
||
|
||
**Key Features:**
|
||
- Hardware-accelerated via RMT (preferred), SPI, or I2S
|
||
- Support for WS2812 and SK6812 LED strips
|
||
- 3-byte (RGB) and 4-byte (RGBW) pixel formats
|
||
- Flexible pixel ordering (GRB, RGB, RBG, BRG, BGR, GBR)
|
||
- Minimal memory footprint (2 buffers only)
|
||
- ESP32 platform exclusive
|
||
|
||
## Quick Start
|
||
|
||
```cpp
|
||
#include "TasmotaLED.h"
|
||
#include "TasmotaLEDPusher.h"
|
||
|
||
// Create 60-LED WS2812 strip on GPIO 5
|
||
TasmotaLED strip(ws2812_grb, 60);
|
||
|
||
void setup() {
|
||
TasmotaLEDPusher *pusher = TasmotaLEDPusher::Create(TasmotaLed_HW_Default, 5);
|
||
strip.SetPusher(pusher);
|
||
strip.Begin();
|
||
|
||
// Set colors and display
|
||
strip.ClearTo(0xFF0000); // All red
|
||
strip.Show();
|
||
}
|
||
```
|
||
|
||
## Architecture
|
||
|
||
### Class Hierarchy
|
||
|
||
```
|
||
┌─────────────────────────────────────┐
|
||
│ TasmotaLED │
|
||
│ ┌──────────────┐ ┌──────────────┐│
|
||
│ │ _buf_work │ │ _buf_show ││
|
||
│ │ (editable) │─▶│ (internal) ││
|
||
│ └──────────────┘ └──────────────┘│
|
||
└──────────────┬──────────────────────┘
|
||
│ uses
|
||
▼
|
||
┌──────────────────────────────────────┐
|
||
│ TasmotaLEDPusher (Abstract) │
|
||
└──────────────┬───────────────────────┘
|
||
│
|
||
┌───────┼───────┐
|
||
▼ ▼ ▼
|
||
┌─────┐ ┌─────┐ ┌─────┐
|
||
│ RMT │ │ SPI │ │ I2S │
|
||
└─────┘ └─────┘ └─────┘
|
||
```
|
||
|
||
### Hardware Support
|
||
|
||
| Hardware | ESP32 | ESP32-S2 | ESP32-S3 | ESP32-C3 | ESP32-C2 | ESP32-C6 |
|
||
|----------|-------|----------|----------|----------|----------|----------|
|
||
| **RMT** | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ |
|
||
| **SPI** | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
|
||
| **I2S** | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ |
|
||
|
||
**Selection Priority:** RMT → I2S → SPI (auto-selected based on SOC capabilities)
|
||
|
||
## Configuration
|
||
|
||
### LED Type Encoding
|
||
|
||
LED types are encoded in a 16-bit value:
|
||
|
||
```
|
||
Bits 15-8: Timing (WS2812=0, SK6812=1)
|
||
Bit 7: W Position (0=after RGB, 1=before RGB)
|
||
Bits 6-4: Pixel Order (GRB, RGB, BGR, etc.)
|
||
Bits 3-0: Bytes/Pixel (3=RGB, 4=RGBW)
|
||
```
|
||
|
||
**Predefined Types:**
|
||
```cpp
|
||
ws2812_grb // WS2812 with GRB ordering (most common)
|
||
sk6812_grbw // SK6812 with GRBW ordering
|
||
sk6812_grb // SK6812 with GRB ordering (no white)
|
||
```
|
||
|
||
**Custom Types:**
|
||
```cpp
|
||
uint16_t custom = TasmotaLed_3_RGB | // 3 bytes per pixel
|
||
TasmotaLed_RGB | // RGB ordering
|
||
TasmotaLed_WS2812; // WS2812 timing
|
||
```
|
||
|
||
### Pixel Ordering Options
|
||
|
||
| Enum | Order | Description |
|
||
|------|-------|-------------|
|
||
| `TasmotaLed_GRB` | G, R, B | Green-Red-Blue (default) |
|
||
| `TasmotaLed_RGB` | R, G, B | Red-Green-Blue |
|
||
| `TasmotaLed_BGR` | B, G, R | Blue-Green-Red |
|
||
| `TasmotaLed_RBG` | R, B, G | Red-Blue-Green |
|
||
| `TasmotaLed_BRG` | B, R, G | Blue-Red-Green |
|
||
| `TasmotaLed_GBR` | G, B, R | Green-Blue-Red |
|
||
|
||
## Timing Specifications
|
||
|
||
### WS2812 Timing
|
||
```
|
||
T0H: 400ns (bit 0 high time)
|
||
T0L: 850ns (bit 0 low time)
|
||
T1H: 800ns (bit 1 high time)
|
||
T1L: 450ns (bit 1 low time)
|
||
Reset: 80µs (reset pulse)
|
||
```
|
||
|
||
### SK6812 Timing
|
||
```
|
||
T0H: 300ns (bit 0 high time)
|
||
T0L: 900ns (bit 0 low time)
|
||
T1H: 600ns (bit 1 high time)
|
||
T1L: 600ns (bit 1 low time)
|
||
Reset: 80µs (reset pulse)
|
||
```
|
||
|
||
### RMT Implementation
|
||
- Clock: 40 MHz (25ns resolution)
|
||
- Precision: ±25ns per timing parameter
|
||
- Memory: 192 symbols per channel
|
||
- Non-blocking with DMA
|
||
|
||
### SPI Implementation
|
||
- Clock: 2.5 MHz
|
||
- Encoding: 3 SPI bits per LED bit
|
||
- Bit 0: `100` pattern
|
||
- Bit 1: `110` pattern
|
||
- Memory: 3× pixel buffer size
|
||
|
||
## Memory Usage
|
||
|
||
| Configuration | Memory Required |
|
||
|---------------|-----------------|
|
||
| 60 RGB pixels | ~460 bytes |
|
||
| 144 RGB pixels | ~964 bytes |
|
||
| 300 RGB pixels | ~1,900 bytes |
|
||
| 512 RGB pixels | ~3,172 bytes |
|
||
| 60 RGBW pixels | ~580 bytes |
|
||
|
||
**Formula:** `~100 bytes + (2 × pixels × bytes_per_pixel)`
|
||
|
||
**SPI Additional:** Add `3 × pixels × bytes_per_pixel` for encoding buffer
|
||
|
||
## Performance
|
||
|
||
### Transmission Times (WS2812/SK6812)
|
||
- 60 pixels: ~1.8 ms (max 555 Hz)
|
||
- 144 pixels: ~4.3 ms (max 232 Hz)
|
||
- 300 pixels: ~9.0 ms (max 111 Hz)
|
||
- 512 pixels: ~15.4 ms (max 65 Hz)
|
||
|
||
### CPU Overhead
|
||
- **RMT:** <1% during transmission (DMA-based)
|
||
- **SPI:** <2% during transmission (DMA-based)
|
||
- **Format conversion:** ~124 µs for 512 RGB pixels
|
||
|
||
## API Highlights
|
||
|
||
### Core Methods
|
||
|
||
```cpp
|
||
// Initialization
|
||
bool Begin()
|
||
void SetPusher(TasmotaLEDPusher *pusher)
|
||
|
||
// Pixel manipulation
|
||
void SetPixelColor(int32_t index, uint32_t wrgb)
|
||
uint32_t GetPixelColor(int32_t index)
|
||
void ClearTo(uint32_t rgbw, int32_t first = 0, int32_t last = -1)
|
||
|
||
// Display
|
||
void Show()
|
||
bool CanShow()
|
||
|
||
// Configuration
|
||
void SetPixelCount(uint16_t num_leds)
|
||
void SetPixelSubType(uint8_t type)
|
||
|
||
// Query
|
||
uint16_t PixelCount() const
|
||
uint8_t PixelSize() const
|
||
uint8_t * Pixels() const
|
||
```
|
||
|
||
### Color Format
|
||
|
||
**RGB Strips (3 bytes):**
|
||
```cpp
|
||
0xRRGGBB
|
||
// Example: 0xFF0000 = Red
|
||
```
|
||
|
||
**RGBW Strips (4 bytes):**
|
||
```cpp
|
||
0xWWRRGGBB
|
||
// Example: 0xFF000000 = Pure white (W channel)
|
||
// Example: 0x00FF0000 = Red (RGB channels)
|
||
```
|
||
|
||
## Compile-Time Configuration
|
||
|
||
Enable/disable hardware support:
|
||
|
||
```cpp
|
||
#define TASMOTALED_HARDWARE_RMT 1 // Enable RMT (default: 1)
|
||
#define TASMOTALED_HARDWARE_SPI 0 // Enable SPI (default: 0)
|
||
#define TASMOTALED_HARDWARE_I2S 0 // Enable I2S (default: 0)
|
||
```
|
||
|
||
**Note:** If no hardware is enabled, SPI is automatically enabled as fallback.
|
||
|
||
## Documentation
|
||
|
||
For complete documentation including detailed API reference, integration guide, troubleshooting, and advanced usage, see:
|
||
|
||
**[TASMOTALED_DOCUMENTATION.md](TASMOTALED_DOCUMENTATION.md)**
|
||
|
||
## License
|
||
|
||
GNU General Public License v3.0
|
||
|
||
Copyright (C) 2024 Stephan Hadinger
|
||
|
||
## Credits
|
||
|
||
- **Author:** Stephan Hadinger
|
||
- **Project:** Tasmota Firmware
|
||
- **Inspired by:** NeoPixelBus library
|
||
- **RMT Encoder:** Based on ESP-IDF examples
|