From 142332730f1bcb22be03400093b30ac915270d99 Mon Sep 17 00:00:00 2001 From: Ivan Li Date: Wed, 9 Jul 2025 14:26:25 +0800 Subject: [PATCH] fix: update 0x02 protocol to use byte offset instead of LED position offset --- docs/hardware-protocol.md | 41 ++++++++++++++++++------ src-tauri/src/ambient_light/publisher.rs | 8 +++-- src-tauri/src/main.rs | 8 ++--- 3 files changed, 40 insertions(+), 17 deletions(-) diff --git a/docs/hardware-protocol.md b/docs/hardware-protocol.md index b509bb5..29b80a6 100644 --- a/docs/hardware-protocol.md +++ b/docs/hardware-protocol.md @@ -64,8 +64,8 @@ Byte 0: Header (0x01) ```text Byte 0: Header (0x02) -Byte 1: Offset High (upper 8 bits of LED start position) -Byte 2: Offset Low (lower 8 bits of LED start position) +Byte 1: Offset High (upper 8 bits of data byte offset) +Byte 2: Offset Low (lower 8 bits of data byte offset) Byte 3+: LED Color Data (variable length) ``` @@ -85,6 +85,26 @@ Byte 3+: LED Color Data (variable length) All values are 0-255. +### Offset Calculation + +The offset field specifies the starting byte position in the LED data buffer: + +- **16-bit value**: Combines Offset High and Offset Low bytes (big-endian) +- **Range**: 0-65535 bytes supported +- **Purpose**: Allows partial updates of LED strip data at any byte position + +**Example Calculations:** + +- Byte position 0: `Offset High = 0x00, Offset Low = 0x00` +- Byte position 30: `Offset High = 0x00, Offset Low = 0x1E` (10 RGB LEDs × 3 bytes) +- Byte position 256: `Offset High = 0x01, Offset Low = 0x00` +- Byte position 1000: `Offset High = 0x03, Offset Low = 0xE8` + +**LED Position to Byte Offset Conversion:** + +- **RGB LEDs**: `byte_offset = led_position × 3` +- **RGBW LEDs**: `byte_offset = led_position × 4` + ## LED Chip Specifications ### WS2812B (RGB) @@ -206,24 +226,24 @@ Unknown → Connecting(1) → Connected ### RGB Example -3 RGB LEDs starting at position 0: Red, Green, Blue +3 RGB LEDs starting at byte offset 0: Red, Green, Blue ```text 02 00 00 FF 00 00 00 FF 00 00 00 FF │ │ │ └─────────────────────────── 9 bytes color data -│ │ └─ Offset Low (0) +│ │ └─ Offset Low (0 bytes) │ └─ Offset High (0) └─ Header (0x02) ``` ### RGBW Example -2 RGBW LEDs starting at position 10: White, Warm White +2 RGBW LEDs starting at byte offset 40 (LED position 10): White, Warm White ```text -02 00 0A FF FF FF FF FF C8 96 C8 +02 00 28 FF FF FF FF FF C8 96 C8 │ │ │ └─────────────────────── 8 bytes color data -│ │ └─ Offset Low (10) +│ │ └─ Offset Low (40 bytes = 0x28) │ └─ Offset High (0) └─ Header (0x02) ``` @@ -284,13 +304,14 @@ void handle_ping(uint8_t* data, size_t len) { void handle_led_data(uint8_t* data, size_t len) { if (len < 3) return; - uint16_t offset = (data[1] << 8) | data[2]; + uint16_t byte_offset = (data[1] << 8) | data[2]; uint8_t* color_data = &data[3]; size_t color_len = len - 3; // Direct forward to LED strip - supports WS2812B, SK6812, SK6812-RGBW + // byte_offset specifies the starting byte position in LED data buffer // Color order conversion handled by LED driver library - led_strip_update(offset, color_data, color_len); + led_strip_update(byte_offset, color_data, color_len); } ``` @@ -379,7 +400,7 @@ void led_strip_update(uint16_t offset, uint8_t* data, size_t len) { - Verify hardware processes 0x02 packets correctly - Check WS2812 wiring and power supply - Monitor packet reception on hardware side -- Verify offset calculations and LED strip configuration +- Verify byte offset calculations and LED strip configuration **Wrong Colors**: diff --git a/src-tauri/src/ambient_light/publisher.rs b/src-tauri/src/ambient_light/publisher.rs index 9ba8d36..159bb65 100644 --- a/src-tauri/src/ambient_light/publisher.rs +++ b/src-tauri/src/ambient_light/publisher.rs @@ -430,10 +430,12 @@ impl LedColorsPublisher { } } - let offset = group.start.min(group.end); + // Calculate byte offset based on LED position and LED type + let led_offset = group.start.min(group.end); + let byte_offset = led_offset * bytes_per_led; let mut tx_buffer = vec![2]; - tx_buffer.push((offset >> 8) as u8); - tx_buffer.push((offset & 0xff) as u8); + tx_buffer.push((byte_offset >> 8) as u8); + tx_buffer.push((byte_offset & 0xff) as u8); tx_buffer.append(&mut buffer); udp_rpc.send_to_all(&tx_buffer).await?; diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index 040b678..0e5628a 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -182,8 +182,8 @@ async fn send_test_colors_to_board(board_address: String, offset: u16, buffer: V })?; let mut packet = vec![0x02]; // Header - packet.push((offset >> 8) as u8); // Offset high - packet.push((offset & 0xff) as u8); // Offset low + packet.push((offset >> 8) as u8); // Byte offset high + packet.push((offset & 0xff) as u8); // Byte offset low packet.extend_from_slice(&buffer); // Color data socket.send_to(&packet, &board_address).await.map_err(|e| { @@ -351,8 +351,8 @@ async fn send_test_colors_to_board_internal(board_address: &str, offset: u16, bu let socket = UdpSocket::bind("0.0.0.0:0").await?; let mut packet = vec![0x02]; // Header - packet.push((offset >> 8) as u8); // Offset high - packet.push((offset & 0xff) as u8); // Offset low + packet.push((offset >> 8) as u8); // Byte offset high + packet.push((offset & 0xff) as u8); // Byte offset low packet.extend_from_slice(&buffer); // Color data socket.send_to(&packet, board_address).await?;