Files
desktop/docs/hardware-protocol.md

13 KiB
Raw Permalink Blame History

LED Hardware Communication Protocol

Overview

UDP-based bidirectional protocol for communication between desktop application and ambient light hardware boards. The protocol supports LED color data transmission, device health monitoring, and remote control capabilities.

Connection

  • Protocol: UDP
  • Port: 23042
  • Discovery: mDNS (_ambient_light._udp.local.)
  • Example Board: 192.168.31.206:23042

mDNS Service Discovery

Service Registration (Hardware Side)

Hardware boards must register the following mDNS service:

  • Service Type: _ambient_light._udp.local.
  • Port: 23042
  • TXT Records: Optional, can include device information

Service Discovery (Desktop Side)

Desktop application continuously browses for _ambient_light._udp.local. services and automatically connects to discovered devices.

Protocol Messages

The protocol uses different message headers to distinguish message types:

Header Direction Purpose Format
0x01 Desktop → Hardware Ping (Health Check) [0x01]
0x01 Hardware → Desktop Pong (Health Response) [0x01]
0x02 Desktop → Hardware LED Color Data [0x02][Offset_H][Offset_L][Color_Data...]
0x03 Hardware → Desktop Display Brightness Control [0x03][Display_Index][Brightness]
0x04 Hardware → Desktop Volume Control [0x04][Volume_Percent]

Health Check Protocol (Ping/Pong)

Desktop → Hardware (Ping)

Byte 0: Header (0x01)

Hardware → Desktop (Pong)

Byte 0: Header (0x01)

Behavior:

  • Desktop sends ping every 1 second to each connected device
  • Hardware must respond with pong within 1 second
  • Timeout or incorrect response triggers reconnection logic
  • After 10 failed attempts, device is marked as disconnected

LED Color Data Protocol

Packet Format

Byte 0: Header (0x02)
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)

LED Color Data

RGB LEDs (3 bytes per LED)

[R][G][B][R][G][B][R][G][B]...

RGBW LEDs (4 bytes per LED)

[R][G][B][W][R][G][B][W][R][G][B][W]...

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)

  • 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

Colors are calibrated before transmission:

RGB:

calibrated_r = (original_r * calibration_r) / 255
calibrated_g = (original_g * calibration_g) / 255  
calibrated_b = (original_b * calibration_b) / 255

RGBW:

calibrated_r = (original_r * calibration_r) / 255
calibrated_g = (original_g * calibration_g) / 255
calibrated_b = (original_b * calibration_b) / 255
calibrated_w = calibration_w  // Direct value

Hardware Control Protocol (Hardware → Desktop)

Display Brightness Control

Hardware can send display brightness adjustment commands to the desktop:

Byte 0: Header (0x03)
Byte 1: Display Index (0-based display number)
Byte 2: Brightness (0-255, where 255 = 100% brightness)

Example: Set display 0 to 50% brightness

03 00 80
│  │  └─ Brightness (128 = ~50%)
│  └─ Display Index (0)
└─ Header (0x03)

Volume Control

Hardware can send system volume adjustment commands to the desktop:

Byte 0: Header (0x04)
Byte 1: Volume Percent (0-100)

Example: Set system volume to 75%

04 4B
│  └─ Volume (75%)
└─ Header (0x04)

Connection State Management

Connection States

  • Unknown: Initial state when device is first discovered
  • Connecting: Device is being tested, includes retry count (1-10)
  • Connected: Device is responding to ping requests normally
  • Disconnected: Device failed to respond after 10 retry attempts

State Transitions

Unknown → Connecting(1) → Connected
    ↓           ↓             ↓
    ↓      Connecting(2-10)   ↓
    ↓           ↓             ↓
    └─→ Disconnected ←────────┘

Retry Logic

  1. Initial Connection: When device discovered via mDNS
  2. Health Check Failure: If ping timeout or wrong response
  3. Retry Attempts: Up to 10 attempts with 1-second intervals
  4. Disconnection: After 10 failed attempts, mark as disconnected
  5. Recovery: Disconnected devices continue to receive ping attempts

Packet Examples

RGB Example

3 RGB LEDs starting at byte offset 0: Red, Green, Blue

02 00 00 FF 00 00 00 FF 00 00 00 FF
│  │  │  └─────────────────────────── 9 bytes color data
│  │  └─ Offset Low (0 bytes)
│  └─ Offset High (0)
└─ Header (0x02)

RGBW Example

2 RGBW LEDs starting at byte offset 40 (LED position 10): White, Warm White

02 00 28 FF FF FF FF FF C8 96 C8
│  │  │  └─────────────────────── 8 bytes color data
│  │  └─ Offset Low (40 bytes = 0x28)
│  └─ Offset High (0)
└─ Header (0x02)

Implementation Notes

  • Byte Order: Big-endian for multi-byte values (offset field)
  • Delivery: Fire-and-forget UDP (no acknowledgment required)
  • Hardware Role: Simple UDP-to-LED bridge, no data processing
  • LED Type Logic: Handled entirely on desktop side, not hardware
  • Mixed Types: Same display can have both RGB and RGBW strips
  • 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

The hardware board handles multiple protocol functions: UDP-to-WS2812 bridge for LED data, health monitoring, and optional control input capabilities.

Required Functions

  1. mDNS Service Registration: Advertise _ambient_light._udp.local. service
  2. UDP Server: Listen on port 23042 for incoming packets
  3. Packet Processing: Handle different message types based on header
  4. Health Monitoring: Respond to ping requests with pong
  5. LED Control: Forward color data to WS2812 strips
  6. Optional Control: Send brightness/volume commands to desktop

Packet Processing Logic

void process_packet(uint8_t* data, size_t len) {
    if (len < 1) return;

    switch (data[0]) {
        case 0x01: // Ping request
            handle_ping(data, len);
            break;

        case 0x02: // LED color data
            handle_led_data(data, len);
            break;

        default:
            // Unknown packet type, ignore
            break;
    }
}

void handle_ping(uint8_t* data, size_t len) {
    if (len != 1) return;

    // Respond with pong
    uint8_t pong = 0x01;
    udp_send_response(&pong, 1);
}

void handle_led_data(uint8_t* data, size_t len) {
    if (len < 3) return;

    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(byte_offset, color_data, color_len);
}

Optional Control Features

Hardware can optionally send control commands to desktop:

// Send display brightness control
void send_brightness_control(uint8_t display_index, uint8_t brightness) {
    uint8_t packet[3] = {0x03, display_index, brightness};
    udp_send_to_desktop(packet, 3);
}

// Send volume control
void send_volume_control(uint8_t volume_percent) {
    uint8_t packet[2] = {0x04, volume_percent};
    udp_send_to_desktop(packet, 2);
}

LED Strip Driver Implementation

For SK6812-RGBW support, hardware must handle the G-R-B-W color order:

// 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

  • Ping Response: Must respond to ping (0x01) within 1 second
  • 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
  • mDNS Registration: Essential for automatic device discovery
  • UDP Server: Must handle concurrent connections from multiple desktops
  • LED Chip Support: Must support WS2812B (RGB), SK6812 (RGB), and SK6812-RGBW

Troubleshooting

Device Discovery Issues

Device Not Found:

  • Verify mDNS service registration on hardware
  • Check service type: _ambient_light._udp.local.
  • Ensure port 23042 is accessible
  • Verify network connectivity between desktop and hardware

Device Shows as Disconnected:

  • Check ping/pong response implementation
  • Verify hardware responds to 0x01 packets within 1 second
  • Monitor network latency and packet loss
  • Check UDP server implementation on hardware

LED Control Issues

No LED Updates:

  • Verify hardware processes 0x02 packets correctly
  • Check WS2812 wiring and power supply
  • Monitor packet reception on hardware side
  • Verify byte offset calculations and LED strip configuration

Wrong Colors:

  • Check color calibration settings on desktop
  • Verify RGB/RGBW data format matches LED strip type
  • Monitor color data in packets (bytes 3+)
  • 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:

  • Monitor packet rate and network congestion
  • Check power supply stability for LED strips
  • Verify WS2812 data signal integrity
  • Consider reducing update frequency

Control Protocol Issues

Brightness/Volume Control Not Working:

  • Verify hardware sends correct packet format (0x03/0x04)
  • Check desktop receives and processes control packets
  • Monitor packet transmission from hardware
  • Verify display index and value ranges

Connection State Issues

Frequent Disconnections:

  • Check network stability and latency
  • Verify ping response timing (< 1 second)
  • Monitor retry logic and connection state transitions
  • Check for UDP packet loss

Stuck in Connecting State:

  • Verify ping/pong packet format
  • Check hardware UDP server implementation
  • Monitor ping response timing
  • Verify network firewall settings

Network Debugging

Packet Monitoring:

# Monitor UDP traffic on port 23042
tcpdump -i any -X port 23042

# Check mDNS service discovery
dns-sd -B _ambient_light._udp.local.

Hardware Debug Output:

  • Log received packet headers and lengths
  • Monitor ping/pong timing
  • Track LED data processing
  • Log mDNS service registration status

Protocol Version

  • Current: 1.0
  • Headers: 0x01 (Ping/Pong), 0x02 (LED Data), 0x03 (Brightness), 0x04 (Volume)
  • Future: Additional headers for new features, backward compatibility maintained