refactor: complete LED type system simplification
This commit is contained in:
@ -85,6 +85,37 @@ Byte 3+: LED Color Data (variable length)
|
|||||||
|
|
||||||
All values are 0-255.
|
All values are 0-255.
|
||||||
|
|
||||||
|
## LED Chip Specifications
|
||||||
|
|
||||||
|
### WS2812B (RGB)
|
||||||
|
|
||||||
|
- **Type**: RGB
|
||||||
|
- **Data Format**: 3 bytes per LED
|
||||||
|
- **Color Order**: G-R-B (Green, Red, Blue)
|
||||||
|
- **Voltage**: 5V
|
||||||
|
- **Protocol**: Single-wire serial
|
||||||
|
- **Timing**: 800kHz data rate
|
||||||
|
|
||||||
|
### SK6812 (RGB)
|
||||||
|
|
||||||
|
- **Type**: RGB
|
||||||
|
- **Data Format**: 3 bytes per LED
|
||||||
|
- **Color Order**: G-R-B (Green, Red, Blue)
|
||||||
|
- **Voltage**: 5V
|
||||||
|
- **Protocol**: Single-wire serial
|
||||||
|
- **Timing**: 800kHz data rate
|
||||||
|
- **Features**: Improved PWM linearity compared to WS2812B
|
||||||
|
|
||||||
|
### SK6812-RGBW
|
||||||
|
|
||||||
|
- **Type**: RGBW
|
||||||
|
- **Data Format**: 4 bytes per LED
|
||||||
|
- **Color Order**: G-R-B-W (Green, Red, Blue, White)
|
||||||
|
- **Voltage**: 5V
|
||||||
|
- **Protocol**: Single-wire serial
|
||||||
|
- **Timing**: 800kHz data rate
|
||||||
|
- **Features**: Dedicated white channel for better color mixing and higher brightness
|
||||||
|
|
||||||
## Color Calibration
|
## Color Calibration
|
||||||
|
|
||||||
Colors are calibrated before transmission:
|
Colors are calibrated before transmission:
|
||||||
@ -201,10 +232,12 @@ Unknown → Connecting(1) → Connected
|
|||||||
|
|
||||||
- **Byte Order**: Big-endian for multi-byte values (offset field)
|
- **Byte Order**: Big-endian for multi-byte values (offset field)
|
||||||
- **Delivery**: Fire-and-forget UDP (no acknowledgment required)
|
- **Delivery**: Fire-and-forget UDP (no acknowledgment required)
|
||||||
- **Hardware Role**: Simple UDP-to-WS2812 bridge, no data processing
|
- **Hardware Role**: Simple UDP-to-LED bridge, no data processing
|
||||||
- **LED Type Logic**: Handled entirely on desktop side, not hardware
|
- **LED Type Logic**: Handled entirely on desktop side, not hardware
|
||||||
- **Mixed Types**: Same display can have both RGB and RGBW strips
|
- **Mixed Types**: Same display can have both RGB and RGBW strips
|
||||||
- **Data Flow**: Desktop → UDP → Hardware → WS2812 (direct forward)
|
- **Data Flow**: Desktop → UDP → Hardware → LED Strip (direct forward)
|
||||||
|
- **Color Order**: Hardware must handle color order conversion for different LED chips
|
||||||
|
- **LED Compatibility**: Supports WS2812B, SK6812, and SK6812-RGBW chips
|
||||||
|
|
||||||
## Hardware Implementation
|
## Hardware Implementation
|
||||||
|
|
||||||
@ -255,8 +288,9 @@ void handle_led_data(uint8_t* data, size_t len) {
|
|||||||
uint8_t* color_data = &data[3];
|
uint8_t* color_data = &data[3];
|
||||||
size_t color_len = len - 3;
|
size_t color_len = len - 3;
|
||||||
|
|
||||||
// Direct forward to WS2812 - no RGB/RGBW distinction needed
|
// Direct forward to LED strip - supports WS2812B, SK6812, SK6812-RGBW
|
||||||
ws2812_update(offset, color_data, color_len);
|
// Color order conversion handled by LED driver library
|
||||||
|
led_strip_update(offset, color_data, color_len);
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -278,13 +312,47 @@ void send_volume_control(uint8_t volume_percent) {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### LED Strip Driver Implementation
|
||||||
|
|
||||||
|
For SK6812-RGBW support, hardware must handle the G-R-B-W color order:
|
||||||
|
|
||||||
|
```c
|
||||||
|
// Example LED strip update function for SK6812-RGBW
|
||||||
|
void led_strip_update(uint16_t offset, uint8_t* data, size_t len) {
|
||||||
|
// For SK6812-RGBW: data comes as [R][G][B][W] from desktop
|
||||||
|
// Must be reordered to [G][R][B][W] for the LED chip
|
||||||
|
|
||||||
|
size_t led_count = len / 4; // 4 bytes per RGBW LED
|
||||||
|
uint8_t* output_buffer = malloc(len);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < led_count; i++) {
|
||||||
|
uint8_t r = data[i * 4 + 0];
|
||||||
|
uint8_t g = data[i * 4 + 1];
|
||||||
|
uint8_t b = data[i * 4 + 2];
|
||||||
|
uint8_t w = data[i * 4 + 3];
|
||||||
|
|
||||||
|
// Reorder to G-R-B-W for SK6812-RGBW
|
||||||
|
output_buffer[i * 4 + 0] = g; // Green first
|
||||||
|
output_buffer[i * 4 + 1] = r; // Red second
|
||||||
|
output_buffer[i * 4 + 2] = b; // Blue third
|
||||||
|
output_buffer[i * 4 + 3] = w; // White fourth
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send to LED strip with proper timing
|
||||||
|
sk6812_rgbw_send(offset, output_buffer, len);
|
||||||
|
free(output_buffer);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
### Key Implementation Notes
|
### Key Implementation Notes
|
||||||
|
|
||||||
- **Ping Response**: Must respond to ping (0x01) within 1 second
|
- **Ping Response**: Must respond to ping (0x01) within 1 second
|
||||||
- **LED Data**: Direct forward to WS2812, no processing required
|
- **LED Data**: Direct forward to LED strip, with color order conversion if needed
|
||||||
|
- **Color Order**: SK6812-RGBW requires G-R-B-W order, desktop sends R-G-B-W
|
||||||
- **Control Commands**: Optional feature for hardware with input capabilities
|
- **Control Commands**: Optional feature for hardware with input capabilities
|
||||||
- **mDNS Registration**: Essential for automatic device discovery
|
- **mDNS Registration**: Essential for automatic device discovery
|
||||||
- **UDP Server**: Must handle concurrent connections from multiple desktops
|
- **UDP Server**: Must handle concurrent connections from multiple desktops
|
||||||
|
- **LED Chip Support**: Must support WS2812B (RGB), SK6812 (RGB), and SK6812-RGBW
|
||||||
|
|
||||||
## Troubleshooting
|
## Troubleshooting
|
||||||
|
|
||||||
@ -318,7 +386,11 @@ void send_volume_control(uint8_t volume_percent) {
|
|||||||
- Check color calibration settings on desktop
|
- Check color calibration settings on desktop
|
||||||
- Verify RGB/RGBW data format matches LED strip type
|
- Verify RGB/RGBW data format matches LED strip type
|
||||||
- Monitor color data in packets (bytes 3+)
|
- Monitor color data in packets (bytes 3+)
|
||||||
- Check WS2812 color order (GRB vs RGB)
|
- Check LED chip color order:
|
||||||
|
- WS2812B: G-R-B order
|
||||||
|
- SK6812: G-R-B order
|
||||||
|
- SK6812-RGBW: G-R-B-W order
|
||||||
|
- Ensure hardware converts R-G-B(-W) from desktop to correct chip order
|
||||||
|
|
||||||
**Flickering or Lag**:
|
**Flickering or Lag**:
|
||||||
|
|
||||||
|
@ -150,12 +150,12 @@ const LedCountControlItem: Component<LedCountControlItemProps> = (props) => {
|
|||||||
<div class="mt-1">
|
<div class="mt-1">
|
||||||
<select
|
<select
|
||||||
class="select select-xs w-full text-xs h-6 min-h-0"
|
class="select select-xs w-full text-xs h-6 min-h-0"
|
||||||
value={config()?.led_type || LedType.RGB}
|
value={config()?.led_type || LedType.WS2812B}
|
||||||
onChange={handleLedTypeChange}
|
onChange={handleLedTypeChange}
|
||||||
title={t('ledConfig.ledType')}
|
title={t('ledConfig.ledType')}
|
||||||
>
|
>
|
||||||
<option value={LedType.RGB}>RGB</option>
|
<option value={LedType.WS2812B}>WS2812B</option>
|
||||||
<option value={LedType.RGBW}>RGBW</option>
|
<option value={LedType.SK6812}>SK6812</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -29,7 +29,7 @@ export const LedStripTest = () => {
|
|||||||
const [boards, setBoards] = createSignal<BoardInfo[]>([]);
|
const [boards, setBoards] = createSignal<BoardInfo[]>([]);
|
||||||
const [selectedBoard, setSelectedBoard] = createSignal<BoardInfo | null>(null);
|
const [selectedBoard, setSelectedBoard] = createSignal<BoardInfo | null>(null);
|
||||||
const [ledCount, setLedCount] = createSignal(60);
|
const [ledCount, setLedCount] = createSignal(60);
|
||||||
const [ledType, setLedType] = createSignal<'RGB' | 'RGBW'>('RGB');
|
const [ledType, setLedType] = createSignal<'WS2812B' | 'SK6812'>('WS2812B');
|
||||||
const [isRunning, setIsRunning] = createSignal(false);
|
const [isRunning, setIsRunning] = createSignal(false);
|
||||||
const [currentPattern, setCurrentPattern] = createSignal<TestPattern | null>(null);
|
const [currentPattern, setCurrentPattern] = createSignal<TestPattern | null>(null);
|
||||||
const [animationSpeed, setAnimationSpeed] = createSignal(33); // ~30fps
|
const [animationSpeed, setAnimationSpeed] = createSignal(33); // ~30fps
|
||||||
@ -259,10 +259,10 @@ export const LedStripTest = () => {
|
|||||||
<select
|
<select
|
||||||
class="select select-bordered w-full"
|
class="select select-bordered w-full"
|
||||||
value={ledType()}
|
value={ledType()}
|
||||||
onChange={(e) => setLedType(e.target.value as 'RGB' | 'RGBW')}
|
onChange={(e) => setLedType(e.target.value as 'WS2812B' | 'SK6812')}
|
||||||
>
|
>
|
||||||
<option value="RGB">RGB</option>
|
<option value="WS2812B">WS2812B</option>
|
||||||
<option value="RGBW">RGBW</option>
|
<option value="SK6812">SK6812</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
import { Borders } from '../constants/border';
|
import { Borders } from '../constants/border';
|
||||||
|
|
||||||
export enum LedType {
|
export enum LedType {
|
||||||
RGB = 'RGB',
|
WS2812B = 'WS2812B',
|
||||||
RGBW = 'RGBW',
|
SK6812 = 'SK6812',
|
||||||
}
|
}
|
||||||
|
|
||||||
export type LedStripPixelMapper = {
|
export type LedStripPixelMapper = {
|
||||||
@ -29,6 +29,6 @@ export class LedStripConfig {
|
|||||||
public readonly display_id: number,
|
public readonly display_id: number,
|
||||||
public readonly border: Borders,
|
public readonly border: Borders,
|
||||||
public len: number,
|
public len: number,
|
||||||
public led_type: LedType = LedType.RGB,
|
public led_type: LedType = LedType.WS2812B,
|
||||||
) {}
|
) {}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user