Skip to content

segfault16/modular-led-controller-workstation-v2

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

704 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

goLEDgo - Modular LED Controller Workstation v2

A high-performance, real-time LED control system designed for professional installations, live performances, and embedded deployments. Built with Go backend and React frontend, featuring a sophisticated filtergraph-based processing engine capable of 60 FPS LED control.

πŸš€ Quick Start - User Journey

This guide follows the complete user journey from installation to creating stunning LED displays on embedded hardware like Raspberry Pi or Orange Pi.

πŸ“¦ Installation & Deployment

Embedded System Setup (Raspberry Pi / Orange Pi)

Step 1: SD Card Preparation

Using Raspberry Pi Imager (recommended):

  1. Download Raspberry Pi Imager
  2. Select your device:
    • Raspberry Pi 3B: Use Raspberry Pi OS Lite (64-bit)
    • Raspberry Pi 4: Use Raspberry Pi OS Lite (64-bit)
    • Orange Pi 3: Use appropriate Orange Pi OS image
  3. Configure before flashing:
    • Hostname: deskpi (or orangepi3)
    • Username: pi
    • Password: Your choice
    • Enable SSH: βœ“ Use password authentication
    • WiFi: Configure your network
    • Locale: Set your timezone

Step 2: SSH Setup

After booting the device:

# Test SSH connection
ssh pi@deskpi.local
# or
ssh pi@orangepi3.local

# Set up SSH key for passwordless access
ssh-copy-id pi@deskpi.local

# Add convenient alias (optional)
echo 'alias deskpi="ssh pi@deskpi.local"' >> ~/.zshrc
source ~/.zshrc

Step 3: System Preparation & Security

SSH into your device and prepare the system:

# Update system
sudo apt update && sudo apt upgrade -y

# Create dedicated LED controller user (for security)
sudo useradd -m -s /bin/bash -G gpio,spi,i2c ledctl
sudo passwd ledctl

# Set up SPI permissions (enable SPI and configure group access)
# Enable SPI interface
echo 'dtparam=spi=on' | sudo tee -a /boot/firmware/config.txt

# Create SPI group if it doesn't exist and add user
sudo groupadd -f spi
sudo usermod -a -G spi ledctl

# Configure udev rules for device permissions
sudo tee /etc/udev/rules.d/99-led-controller.rules << 'EOF'
# GPIO and SPI access for LED controller
SUBSYSTEM=="spidev", GROUP="spi", MODE="0660"
KERNEL=="gpiomem", GROUP="gpio", MODE="0660"
KERNEL=="i2c-[0-9]*", GROUP="i2c", MODE="0660"
EOF

# Reload udev rules
sudo udevadm control --reload-rules && sudo udevadm trigger

# Install required system dependencies
sudo apt install -y curl wget unzip systemd

# Reboot to apply SPI and GPIO configuration
sudo reboot

# Check SPI is available:
ls /dev | grep spi

# Check SPI bufsize (defaults to 4096):
cat /sys/module/spidev/parameters/bufsiz

# Adjust SPI bufsize:
# Add spidev.bufsiz=32768 to /boot/firmware/cmdline.txt (modify existing line, don't append new line)
sudo sed -i 's/$/ spidev.bufsiz=32768/' /boot/firmware/cmdline.txt

# Verify the change (entire file should be one line):
cat /boot/firmware/cmdline.txt

# Reboot again
sudo reboot

# Check SPI bufsize is now increased:
cat /sys/module/spidev/parameters/bufsiz

Step 4: Binary Installation

After reboot, connect as the LED controller user:

# SSH as the dedicated user
ssh pi@deskpi.local
su ledctl
cd ~

# Create working directory
mkdir -p ~/ledserver
cd ~/ledserver

Method 1: Download via wget/curl (Production)

TODO: repository needs to be public

# Download binary for your architecture
# For Raspberry Pi 3B (ARM):
wget https://github.com/segfault16/modular-led-controller-workstation-v2/releases/latest/download/modular-led-controller-workstation-v2-linux-arm

# For Raspberry Pi 4 / Orange Pi 3 (ARM64):
wget https://github.com/segfault16/modular-led-controller-workstation-v2/releases/latest/download/modular-led-controller-workstation-v2-linux-arm64

# For x86_64 systems:
wget https://github.com/segfault16/modular-led-controller-workstation-v2/releases/latest/download/modular-led-controller-workstation-v2-linux-amd64

# Make executable
chmod +x modular-led-controller-workstation-v2-*
mv modular-led-controller-workstation-v2-* modular-led-controller-workstation-v2

# Test run
./modular-led-controller-workstation-v2

Method 2: SCP Copy from Local Machine

# Use docker to build the binary
task docker:build:linux-arm64
# Copy all binaries
task remote:copy TARGET_HOST=pi@deskpi.local TARGET_ARCH=linux-arm64

Step 5: Configuration & First Run

ssh pi@deskpi.local
chmod +x modular-led-controller-workstation-v2
./modular-led-controller-workstation-v2

Running the System

First Run

# Navigate to installation directory
cd ~/ledserver

# Start the LED controller
./ledcontroller

# Access web interface from your computer:
# - http://deskpi.local:3000  
# - http://orangepi3.local:3000
# - http://[device-ip]:3000

Production Service Setup

# Create systemd service file
sudo tee /etc/systemd/system/ledcontroller.service << 'EOF'
[Unit]
Description=LED Controller Service
After=network.target

[Service]
Type=simple
User=ledctl
Group=ledctl
WorkingDirectory=/home/ledctl/ledserver
ExecStart=/home/ledctl/ledserver/ledcontroller
Restart=always
RestartSec=10
StandardOutput=journal
StandardError=journal

# Security settings
NoNewPrivileges=true
ProtectSystem=strict
ProtectHome=true
ReadWritePaths=/home/ledctl/ledserver

[Install]
WantedBy=multi-user.target
EOF

# Enable and start service  
sudo systemctl daemon-reload
sudo systemctl enable ledcontroller
sudo systemctl start ledcontroller

# Check status
sudo systemctl status ledcontroller

πŸ“Š LED Hardware Setup

Output Methods

The system supports two distinct output methods for driving LEDs:

Method 1: Direct SPI LED Control

Best for: Single-channel, moderate LED counts (up to ~1000 LEDs)

Uses throttled SPI timing to directly drive LED protocols from the Raspberry Pi:

Supported LED Types:

  • WS2812B (NeoPixel) - 5V, single data line
  • WS2815 (12V addressable) - 12V, single data line
  • APA102 (DotStar) - Separate clock and data lines
  • Custom SPI protocols - Configurable timing

Characteristics:

  • SPI speed throttled to match LED protocol timing (~3.8 MHz for WS2812)
  • Direct bit-banging of LED data protocols
  • Limited to single output channel per SPI bus
  • Suitable for installations up to ~1000 LEDs

Performance Limits: Based on Hz = 4.0 / 1.05e-6 β‰ˆ 3.81 MHz SPI frequency:

  • Each LED requires 96 SPI bits (24 RGB bits Γ— 4 SPI bits encoding)
  • 60 FPS maximum: ~660 LEDs (3.81MHz Γ· 96 bits Γ· 60fps = 659 LEDs)
  • 30 FPS maximum: ~1,320 LEDs (3.81MHz Γ· 96 bits Γ· 30fps = 1,319 LEDs)
  • Real-world limits: ~500-800 LEDs at 60 FPS (accounting for overhead)

Method 2: High-Speed SPI with ESP32 Microcontroller

Best for: Multi-channel, high LED counts (1000+ LEDs per channel)

Uses full-speed SPI communication with ESP32 microcontrollers for multi-channel output:

Characteristics:

  • Full-speed SPI communication (up to 80 MHz)
  • ESP32 handles LED protocol timing on multiple channels
  • Supports thousands of LEDs per channel
  • Multiple independent output channels
  • Real-time data streaming to ESP32
  • ESP32 firmware manages hardware-specific LED output

Performance Limits:

  • Per Channel: 5,000+ LEDs at 60 FPS (limited by ESP32 processing power)
  • Total System: 10,000+ LEDs across multiple channels
  • Frame Rate: Consistent 60 FPS even with high LED counts
  • Latency: Low latency due to dedicated hardware processing

Device Configuration:

{
  "device": "candy",
  "candyServer": "esp32.local:7890", 
  "numPixel": 2000,
  "multiChannel": true
}

Wiring Guide

Direct SPI LED Control (Method 1)

Raspberry Pi SPI Connections:

  • MOSI (GPIO 10) β†’ LED Data Pin
  • SCLK (GPIO 11) β†’ LED Clock Pin (for 4-wire LEDs like APA102)
  • GND (Pin 6, 9, 14, 20, 25, 30, 34, 39) β†’ LED Ground

ESP32 SPI Communication (Method 2)

Raspberry Pi to ESP32:

  • MOSI (GPIO 10) β†’ ESP32 SPI MOSI
  • SCLK (GPIO 11) β†’ ESP32 SPI SCLK
  • CS (GPIO 8) β†’ ESP32 SPI CS
  • GND β†’ ESP32 GND

ESP32 to LEDs:

  • Multiple GPIO pins configured for LED output channels
  • Each channel drives separate LED strips independently
  • Hardware-optimized LED protocol generation

Power Supply (CRITICAL SAFETY):

  • NEVER connect Raspberry Pi 5V to LED power
  • Use separate dedicated 5V/12V power supply for LEDs
  • ONLY connect grounds together (Pi GND ↔ LED GND ↔ Power Supply GND)
  • Power supply must match LED strip voltage (5V for WS2812, 12V for WS2815)

Basic Safety:

  • Always use external power supply for LED strips (any length)
  • Add 470Ξ© resistor in series with data line
  • Use logic level shifter for 5V LED strips (3.3V β†’ 5V)
  • Shared ground is essential - never skip the ground connection

πŸŽ›οΈ Using the System

Web Interface Access

Once the LED controller is running, access the web interface from any device on your network:

# Open in browser:
http://deskpi.local:3000
http://orangepi3.local:3000
http://[device-ip]:3000

Basic Operation

  1. Device Configuration: Set up your LED hardware and SPI settings
  2. Project Management: Create or load LED projects
  3. Scene Creation: Design visual effects and transitions
  4. Real-time Control: Adjust parameters and trigger effects

🎯 Project Management

Installing Example Projects

Projects are JSON configuration files containing complete LED setups including scenes, effects, and device configurations.

Method 1: Git Repository Installation

# Using the built-in task system
task remote:init-project TARGET_HOST=orangepi3.local PROJECT=your-project-name

# This clones from https://github.com/segfault16/p2_desk_presets by default

Method 2: Manual Project Installation

  1. Create project directory:

    mkdir -p ~/.ledserver/projects/my-project
  2. Add project files:

File Path: ~/.ledserver/projects/[project-name]/[project-name].json Complete Project Structure:

// ~/.ledserver/projects/desk-setup/desk-setup.json
{
  "ID": "desk-setup",
  "Title": "Desk LED Setup", 
  "Description": "Multi-zone desk lighting with audio reactivity",
  "ActiveSceneID": 2,
  "Scenes": {
    "0": {
      "Metadata": {
        "Title": "Static Colors",
        "Group": "Basic",
        "SceneID": 0,
        "NumSlots": 2,
        "DeviceSlotTags": {
          "0": ["main", "desk"],
          "1": ["ambient", "background"]
        },
        "DeviceSlotMapping": {
          "0": 0,
          "1": 1
        }
      },
      "SceneSlots": {
        "0": {
          "nodes": [
            {
              "UUID": "static-color-node",
              "Effect": {
                "NumInputChannels": 0,
                "NumOutputChannels": 1,
                "R": {"Orig": 255},
                "G": {"Orig": 128},
                "B": {"Orig": 0}
              },
              "EffectType": "colors.staticRGBColor"
            },
            {
              "UUID": "output-node",
              "Effect": {
                "NumInputChannels": 1,
                "NumOutputChannels": 0,
                "Brightness": {"Orig": 0}
              },
              "EffectType": "effects.LedOutput"
            }
          ],
          "connections": [
            {
              "from_node_uid": "static-color-node",
              "from_node_channel": 0,
              "to_node_uid": "output-node",
              "to_node_channel": 0,
              "uid": "connection-1"
            }
          ],
          "modulationSources": [...],
          "modulation": [...]
        }
      }
    },
    "1": {
      "Metadata": {
        "Title": "Audio Reactive",
        "Group": "Dynamic", 
        "SceneID": 1
      }
    }
  }
}

Method 3: Web Interface Upload

  • Access Projects page in web interface
  • Use Import Project to upload JSON files
  • Supports both individual scenes and complete projects

Project Structure

~/.ledserver/
β”œβ”€β”€ projects/
β”‚   β”œβ”€β”€ my-project/
β”‚   β”‚   β”œβ”€β”€ project.json          # Main project configuration
β”‚   β”‚   β”œβ”€β”€ scene1.json           # Individual scenes
β”‚   β”‚   └── assets/               # Project assets (images, etc.)
β”‚   └── another-project/
β”œβ”€β”€ config.json                   # Global configuration
└── device-configs.json           # Hardware configurations

βš™οΈ Device Configuration

Device configuration is critical for proper LED output. The system supports multiple output types and complex routing scenarios.

Basic Device Setup

  1. Access Configuration Page in web interface
  2. Define Device Configurations:

File Path: ~/.ledserver/configuration.json Object Path: configuration.json β†’ DeviceConfigs β†’ DeviceConfigs β†’ [config-name]

{
  "DeviceConfigs": {
    "DeviceConfigs": {
      "desk-setup": [
        {
          "Name": "Main Strip",
          "NumPixel": 880,
          "Device": "spi",
          "ScaleBrightness": 1.0,
          "Order": 0,
          "Primary": true
        }
      ],
      "segmented-desk": [
        {
          "Name": "Right Side",
          "NumPixel": 120,
          "Device": "virtual",
          "VirtualReference": "desk-setup",
          "VirtualStartIndex": 0,
          "Tags": ["right", "main"],
          "Order": 0
        },
        {
          "Name": "Center Monitor",
          "NumPixel": 200,
          "Device": "virtual", 
          "VirtualReference": "desk-setup",
          "VirtualStartIndex": 120,
          "Tags": ["center", "monitor"],
          "Order": 1
        },
        {
          "Name": "Left Side",
          "NumPixel": 120,
          "Device": "virtual",
          "VirtualReference": "desk-setup", 
          "VirtualStartIndex": 320,
          "Tags": ["left", "main", "reverse"],
          "Order": 2
        }
      ]
    }
  }
}

Advanced Device Types

Direct SPI Control

Object Path: configuration.json β†’ DeviceConfigs β†’ DeviceConfigs β†’ [config-name] β†’ [device-index]

{
  "Name": "High Performance Strip",
  "Device": "ws2812SPI",
  "NumPixel": 500
}

ESP32 Microcontroller Integration

For high-performance multi-channel setups where timing determines LED stripe length: Object Path: configuration.json β†’ DeviceConfigs β†’ DeviceConfigs β†’ [config-name] β†’ [device-index]

{
  "Name": "ESP32 Multi-Channel",
  "Device": "candy",
  "CandyServer": "192.168.1.100:7890",
  "NumPixel": 1000
}

Virtual Output Mapping

For complex installations with multiple physical segments: Object Path: configuration.json β†’ DeviceConfigs β†’ DeviceConfigs β†’ [config-name] β†’ [device-index]

[
  {
    "Name": "Segment 1",
    "Device": "virtual",
    "NumPixel": 150,
    "VirtualReference": "main-strip",
    "VirtualStartIndex": 0
  },
  {
    "Name": "Segment 2", 
    "Device": "virtual",
    "NumPixel": 150,
    "VirtualReference": "main-strip",
    "VirtualStartIndex": 150
  }
]

Slot Tags and Device Routing

The system uses slot tags for flexible device routing:

Object Path: configuration.json β†’ DeviceConfigs β†’ DeviceConfigs β†’ [config-name] β†’ [device-index]

{
  "Name": "Ceiling Lights",
  "Device": "ws2812SPI",
  "NumPixel": 200,
  "SlotTag": "ceiling-lights",
  "Order": 1
}

Slot tags allow scenes to target specific hardware without hardcoding device indices.

🎬 Scene Architecture and Device Routing

Understanding Scenes and Slots is crucial - This is the most complex part of the system, enabling flexible multi-zone LED control with tag-based routing.

Core Concepts

Projects β†’ Scenes β†’ Scene Slots β†’ Devices

Project
β”œβ”€β”€ Scene 0: "Static Colors"
β”‚   β”œβ”€β”€ Scene Slot 0 β†’ [Filtergraph] β†’ Left LED Bar
β”‚   └── Scene Slot 1 β†’ [Filtergraph] β†’ Right LED Bar  
β”œβ”€β”€ Scene 1: "Audio Reactive"
β”‚   β”œβ”€β”€ Scene Slot 0 β†’ [Audio VU Meter] β†’ Left LED Bar
β”‚   β”œβ”€β”€ Scene Slot 1 β†’ [Audio Spectrum] β†’ Right LED Bar
β”‚   └── Scene Slot 2 β†’ [Audio Visualizer] β†’ Desk Strip
└── Scene 2: "Ambient"
    └── Scene Slot 0 β†’ [Color Wheel] β†’ All Devices

Scene Slots: Multi-Zone Control

Scene Slots enable independent control of different LED zones within a single scene. Each slot contains its own filtergraph that can drive different visual effects.

Use Case Example: Desk Setup

Physical Setup:
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  [Left Bar]  [Monitor]  [Right Bar] β”‚  ← Individual LED strips
β”‚              [Desk Strip]            β”‚  ← Under-desk lighting
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Scene Slot Mapping:
β€’ Scene Slot 0 β†’ Left Bar   (VU Meter visualization)
β€’ Scene Slot 1 β†’ Right Bar  (Audio spectrum)  
β€’ Scene Slot 2 β†’ Desk Strip (Color wheel effect)
β€’ Scene Slot 3 β†’ Monitor    (Ambient breathing)

Web Interface Layout

Scene Management

  • Scene Switches: Located above the filtergraph visualization
  • Scene Slots: Each row below the visualization represents one scene slot
  • Column Selection: Same filtergraph can drive multiple slots by selecting the same column
  • Live Preview: Visual feedback shows which devices are active

Filtergraph Editor

[Scene: Audio Reactive] [Scene: Static] [Scene: Ambient]  ← Scene switches

Slot 0: [Audio Input] β†’ [VU Meter] β†’ [LED Output]        ← Row = Scene Slot
        └─────────────── Column 1 β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Slot 1: [Audio Input] β†’ [Spectrum] β†’ [LED Output]        ← Independent slot  
        └─────────────── Column 1 β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜        ← Same input column

Slot 2: [Color Wheel] ──────────→ [LED Output]           ← Different effect
        └──── Column 2 β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Tag-Based Device Routing

The system uses flexible tag-based routing to map scene slots to physical devices without hardcoding connections.

How Routing Works

1. Device Configuration with Tags File Path: ~/.ledserver/configuration.json

{
  "DeviceConfigs": {
    "DeviceConfigs": {
      "desk-setup": [
        {
          "Name": "Left LED Bar",
          "Device": "ws2812SPI", 
          "NumPixel": 120,
          "SlotTag": "left-bar",
          "Tags": ["left", "bar", "audio-reactive"]
        },
        {
          "Name": "Right LED Bar",
          "Device": "virtual",
          "VirtualReference": "desk-setup",
          "VirtualStartIndex": 120,
          "NumPixel": 120, 
          "SlotTag": "right-bar",
          "Tags": ["right", "bar", "audio-reactive"]
        },
        {
          "Name": "Under Desk",
          "Device": "virtual",
          "VirtualReference": "desk-setup", 
          "VirtualStartIndex": 240,
          "NumPixel": 200,
          "SlotTag": "desk-ambient",
          "Tags": ["ambient", "desk", "background"]
        }
      ]
    }
  }
}

2. Scene Slot Tag Assignment File Path: ~/.ledserver/projects/[project-name]/[project-name].json

{
  "Scenes": {
    "1": {
      "Metadata": {
        "Title": "Audio Reactive Desk",
        "DeviceSlotTags": {
          "0": ["left", "audio-reactive"],      // Slot 0 targets left bar
          "1": ["right", "audio-reactive"],     // Slot 1 targets right bar  
          "2": ["ambient", "background"]        // Slot 2 targets ambient
        },
        "DeviceSlotMapping": {
          "0": 0,    // Device slot 0 β†’ Scene slot 0
          "1": 1,    // Device slot 1 β†’ Scene slot 1
          "2": 2     // Device slot 2 β†’ Scene slot 2
        }
      }
    }
  }
}

3. Runtime Routing Resolution The system automatically matches devices to scene slots:

Routing Logic:
Device "Left LED Bar" has tags: ["left", "bar", "audio-reactive"]
Scene Slot 0 requests tags: ["left", "audio-reactive"]
β†’ MATCH: Left LED Bar connects to Scene Slot 0

Device "Right LED Bar" has tags: ["right", "bar", "audio-reactive"] 
Scene Slot 1 requests tags: ["right", "audio-reactive"]
β†’ MATCH: Right LED Bar connects to Scene Slot 1

Device "Under Desk" has tags: ["ambient", "desk", "background"]
Scene Slot 2 requests tags: ["ambient", "background"] 
β†’ MATCH: Under Desk connects to Scene Slot 2

Default Behavior and Fallbacks

Automatic SlotTag Generation

When devices don't have explicit SlotTag values, the system auto-generates them:

// From serverConfig.go adjustSlotTags()
// Devices without SlotTag get: "unnamed_0", "unnamed_1", etc.
d.SlotTag = fmt.Sprintf("unnamed_%v", curCnt)

Default Scene Structure

File Path: ~/.ledserver/projects/[project-name]/[project-name].json

New scenes automatically get:

{
  "Metadata": {
    "DeviceSlotTags": {
      "0": ["unnamed_0", "unnamed_1", "unnamed_2"]  // All devices
    },
    "DeviceSlotMapping": {
      "0": 0  // Single slot drives all devices
    }
  }
}

Multi-Setup Compatibility

Scenes can target different hardware setups using tag ranges:

{
  "DeviceSlotTags": {
    "0": ["main", "primary"],           // Works with any "main" device
    "1": ["secondary", "accent"],       // Works with any "secondary" device  
    "2": ["ambient", "background"]      // Works with ambient lighting
  }
}

Example: Same scene works on different setups

Setup A (Desk):     Setup B (Room):        Setup C (Stage):
- Main Strip        - Ceiling Lights       - Front Wash
- Side Lights       - Wall Washers         - Back Lights  
- Ambient           - Floor Strips         - Effect Lights

Advanced Routing Features

Virtual Device Mapping

Virtual devices enable complex routing within single physical strips:

{
  "Name": "Left Section",
  "Device": "virtual",
  "VirtualReference": "main-strip",     // References physical device
  "VirtualStartIndex": 0,               // Starts at pixel 0
  "NumPixel": 150,                      // Uses first 150 pixels
  "SlotTag": "left-zone"
}

Tag-Based Transformations

Device tags also control pixel transformations:

{
  "Tags": ["reverse", "left", "audio-reactive"],
  // "reverse" β†’ Pixels flow right-to-left
  // "reverse-first-half" β†’ Only first half reversed
  // "reverse-second-half" β†’ Only second half reversed
}

Brightness Scaling per Device

{
  "ScaleBrightness": 0.7,              // 70% brightness 
  "ScaleBrightnessActive": true,       // Enable scaling
  "Tags": ["bright-zone"]
}

Troubleshooting Routing Issues

Common Problems

  1. No devices light up: Check tag matching between scene slots and devices
  2. Wrong devices active: Verify DeviceSlotMapping in scene metadata
  3. Missing effects: Ensure scene slots have filtergraphs with LED output nodes

Debug Device Routing

# Check active device configuration
curl http://localhost:3000/api/config/device-configs

# Verify scene slot assignments  
curl http://localhost:3000/api/projects/[project-id]/scenes/[scene-id]

Default Behavior Validation

  • Devices without SlotTag get auto-generated tags: unnamed_0, unnamed_1...
  • Scenes without DeviceSlotTags get all device tags assigned to slot 0
  • Empty scenes get default LED output node in slot 0

This flexible routing system enables complex multi-zone installations while maintaining compatibility across different hardware setups through intelligent tag-based matching.

πŸ”— Filtergraph Architecture

The core of the system is a Directed Acyclic Graph (DAG) processing engine that processes LED data in real-time.

Graph Structure

File Path: ~/.ledserver/projects/[project-name]/[project-name].json Object Path: project.json β†’ Scenes β†’ [scene-id] β†’ SceneSlots β†’ [slot-id] β†’ nodes

{
  "SceneSlots": {
    "0": {
      "nodes": [
        {
          "UUID": "audio-input-main",
          "Effect": {
            "NumInputChannels": 0,
            "NumOutputChannels": 2,
            "AutoGain": {"Val": true},
            "AutoGainMax": {"Orig": 10.0},
            "AutoGainTime": {"Orig": 10.0}
          },
          "EffectType": "effects.AudioInput"
        },
        {
          "UUID": "vu-meter-left",
          "Effect": {
            "NumInputChannels": 1,
            "NumOutputChannels": 1,
            "Sensitivity": {"Orig": 1.0},
            "PeakHold": {"Orig": 0.8},
            "Falloff": {"Orig": 0.95}
          },
          "EffectType": "audioreactive.vuMeter"
        },
        {
          "UUID": "output-desk",
          "Effect": {
            "NumInputChannels": 1,
            "NumOutputChannels": 0,
            "Brightness": {"Orig": 0}
          },
          "EffectType": "effects.LedOutput"
        }
      ],
      "connections": [
        {
          "from_node_uid": "audio-input-main",
          "from_node_channel": 0,
          "to_node_uid": "vu-meter-left",
          "to_node_channel": 0,
          "uid": "connection-1"
        },
        {
          "from_node_uid": "vu-meter-left",
          "from_node_channel": 0,
          "to_node_uid": "output-desk",
          "to_node_channel": 0,
          "uid": "connection-2"
        }
      ]
    }
  }
}

Processing Flow

  1. Backward Propagation: Graph analysis determines required pixel counts
  2. Forward Processing: Real-time pixel data flows through nodes
  3. Buffer Management: Efficient memory allocation for 60 FPS operation
  4. Parallel Execution: Multi-threaded processing for performance

Data Flow Example

AudioInput(300px) β†’ Mixer(300px) β†’ LedOutput(300px)
RainbowGen(300px) β†—

🎨 Effects and Node Types

Generator Effects

Create pixel data from scratch:

  • Static RGB Color (colors.staticRGBColor): Solid colors with RGB control
  • Color Wheel (colors.colorWheel): Rotating rainbow patterns with speed control
  • Static Blob (generative.staticBlob): Procedural blob patterns
  • Swimming Pool (generative.swimmingPool): Ripple effects simulation
  • Generate Waves (generative.generateWaves): Sine wave patterns
  • Falling Stars (generative.fallingStars): Meteor-like effects
  • Pendulum (generative.pendulum): Swinging light effects

Modifier Effects

Transform existing pixel data:

  • After Glow (effects.afterGlow): Persistence/trail effects with decay
  • Mirror (effects.mirror): Mirror patterns at specified points
  • Shift (effects.shift): Move patterns along the strip
  • Swing (effects.swing): Pendulum-like movement modifier
  • Shapes (effects.shapes): Geometric shape overlay effects
  • Spring Combine (effects.springCombine): Physics-based combination

Audio-Reactive Effects

Respond to audio input:

  • Audio Input (effects.AudioInput): Live audio capture with auto-gain
  • VU Meter (audioreactive.vuMeter): Classic level visualization
  • Spectrum (audioreactive.spectrum): Frequency analysis display
  • Dual Spectrum (audioreactive.dualSpectrum): Stereo spectrum analyzer
  • Moving Light (audioreactive.movingLight): Audio-driven light movement
  • Bonfire (audioreactive.bonfire): Flame-like audio response
  • Falling Stars (audioreactive.fallingStars): Audio-triggered meteors
  • Blink (audioreactive.blink): Beat-synchronized flashing

Color Processing Effects

Advanced color manipulation:

  • Color Blend (colors.colorBlend): Multi-layer color mixing
  • RGB to HSV (colors.rgbToHSV): Color space conversion
  • HSV to RGB (colors.hsvToRGB): Hue/saturation processing
  • Interpolate HSV (colors.interpolateHSV): Smooth color transitions

Utility Effects

System and control functions:

  • LED Output (effects.LedOutput): Hardware output interface
  • Append (effects.append2, effects.append4, etc.): Multi-channel concatenation
  • Router: Signal routing and distribution

Effect Parameters

Each effect exposes modulatable parameters:

Object Path: project.json β†’ Scenes β†’ [scene-id] β†’ SceneSlots β†’ [slot-id] β†’ nodes β†’ [node-index] β†’ Effect

{
  "Effect": {
    "NumInputChannels": 0,
    "NumOutputChannels": 1,
    "Speed": {
      "Orig": 0.3,
      "Min": 0.0,
      "Max": 2.0,
      "Step": 0.1
    },
    "Saturation": {
      "Orig": 1.0,
      "Min": 0.0,
      "Max": 1.0,
      "Step": 0.01
    },
    "Brightness": {
      "Orig": 0.8,
      "Min": 0.0,
      "Max": 1.0,
      "Step": 0.01
    }
  },
  "EffectType": "colors.colorWheel"
}

Audio-Reactive Effect Parameters: Object Path: project.json β†’ Scenes β†’ [scene-id] β†’ SceneSlots β†’ [slot-id] β†’ nodes β†’ [node-index] β†’ Effect

{
  "Effect": {
    "NumInputChannels": 1,
    "NumOutputChannels": 1,
    "Sensitivity": {
      "Orig": 1.0,
      "Min": 0.1,
      "Max": 5.0,
      "Step": 0.1
    },
    "PeakHold": {
      "Orig": 0.8,
      "Min": 0.0,
      "Max": 1.0,
      "Step": 0.01
    },
    "Falloff": {
      "Orig": 0.95,
      "Min": 0.5,
      "Max": 0.99,
      "Step": 0.01
    }
  },
  "EffectType": "audioreactive.vuMeter"
}

Modifier Effect Parameters: Object Path: project.json β†’ Scenes β†’ [scene-id] β†’ SceneSlots β†’ [slot-id] β†’ nodes β†’ [node-index] β†’ Effect

{
  "Effect": {
    "NumInputChannels": 1,
    "NumOutputChannels": 1,
    "Decay": {
      "Orig": 0.95,
      "Min": 0.5,
      "Max": 0.99,
      "Step": 0.01
    },
    "Threshold": {
      "Orig": 0.1,
      "Min": 0.0,
      "Max": 1.0,
      "Step": 0.01
    }
  },
  "EffectType": "effects.afterGlow"
}

πŸŽ›οΈ Modulation System

The modulation system enables dynamic parameter control and automation.

Modulation Sources

  • LFO (Low Frequency Oscillator): Sine, triangle, square waves
  • Audio Reactive: Beat, RMS, frequency bands
  • Manual Control: MIDI controllers, web interface
  • Time-based: Linear ramps, step sequences

Modulation Mapping

File Path: ~/.ledserver/projects/[project-name]/[project-name].json Object Path: project.json β†’ Scenes β†’ [scene-id] β†’ SceneSlots β†’ [slot-id] β†’ modulation

{
  "SceneSlots": {
    "0": {
      "modulation": [
        {
          "modulation_source_id": "95453dd7-47b8-453a-bc4d-6634f61650a8",
          "target_node_id": "output-main",
          "target_param": "Brightness",
          "amount": 1.0,
          "inverted": false,
          "uid": "brightness-modulation-1"
        },
        {
          "modulation_source_id": "d075134f-2d87-436a-ab57-6b3037d00f04", 
          "target_node_id": "static-color-node",
          "target_param": "R",
          "amount": 1.0,
          "inverted": false,
          "uid": "color-red-modulation"
        }
      ],
      "modulationSources": [
        {
          "UUID": "95453dd7-47b8-453a-bc4d-6634f61650a8",
          "ModulationSourceType": "modulations.externalLinearController",
          "ModulationSource": {
            "Amount": 1.0,
            "Controller": "Brightness"
          }
        },
        {
          "UUID": "d075134f-2d87-436a-ab57-6b3037d00f04",
          "ModulationSourceType": "modulations.externalColourAController", 
          "ModulationSource": {
            "ControllerR": null,
            "ControllerG": null,
            "ControllerB": null
          }
        }
      ]
    }
  }
}

Real-time Control

  • MIDI Integration: Hardware controllers for live performance
  • Web Interface: Real-time parameter adjustment
  • Bluetooth: Wireless control via custom protocol
  • Audio Reactive: Automatic response to music

πŸ”§ Advanced Configuration

Performance Tuning

Frame Rate Optimization

{
  "maxSPISpeedMHz": 4.0,        // SPI bus speed
  "targetFPS": 60,              // Rendering target
  "audioBufferSize": 512        // Audio latency vs quality
}

Memory Management

  • Buffer Pooling: Efficient pixel buffer reuse
  • Garbage Collection: Optimized for real-time performance
  • Channel Optimization: Minimize unnecessary allocations

Hardware-Specific Settings

ESP32 Integration

For multi-channel high-performance setups:

{
  "device": "candy",
  "candyServer": "esp32.local:7890",
  "numPixel": 2000,
  "multiChannel": true,
  "timingCritical": true
}

Raspberry Pi SPI Configuration

# Enable SPI in /boot/firmware/config.txt (or /boot/config.txt on older systems)
dtparam=spi=on

# Adjust SPI buffer size for large LED counts (IMPORTANT: keep cmdline.txt on one line)
# Check current buffer size:
cat /sys/module/spidev/parameters/bufsiz

# Add spidev.bufsiz=32768 to /boot/firware/cmdline.txt (modify existing line, don't append new line)
sudo sed -i 's/$/ spidev.bufsiz=32768/' /boot/firware/cmdline.txt

# Verify the change (entire file should be one line):
cat /boot/firware/cmdline.txt

Network Configuration

mDNS Discovery

  • Automatic device discovery on local network
  • Service advertisement for remote management
  • Zeroconf integration for plug-and-play setup

Remote Management

  • SSH Access: Command line management
  • Web Interface: Full remote control
  • Update System: Over-the-air updates

🌐 Web Interface Features

Dashboard

  • Real-time FPS Monitoring: Performance metrics
  • Device Status: Hardware connection status
  • Scene Control: Quick scene switching
  • Parameter Control: Live effect adjustment

Project Management

  • Project Browser: Visual project selection
  • Import/Export: Project file management
  • Version Control: Project history tracking
  • Asset Management: Image and resource handling

Configuration Pages

  • Device Setup: Hardware configuration wizard
  • Audio Settings: Input device selection
  • Network Settings: Connectivity configuration
  • Update Management: System updates

Preview System

  • Real-time Preview: Visual feedback before deployment
  • Pixel Visualization: Individual LED state display
  • Performance Metrics: Processing time analysis
  • Debug Information: Detailed system status

🎡 Audio Integration

Audio Input Sources

  • System Audio: Computer audio output
  • Microphone: Live audio capture
  • Audio Streaming: Network audio sources
  • File Playback: Pre-recorded audio

Audio Processing

  • FFT Analysis: Frequency domain processing
  • Beat Detection: Rhythm extraction
  • RMS Calculation: Audio level analysis
  • Multi-channel: Stereo and surround support

Audio-Visual Mapping

{
  "audioReactive": {
    "fftBands": 64,
    "beatSensitivity": 0.7,
    "frequencyRange": {"low": 20, "high": 20000},
    "smoothing": 0.8
  }
}

πŸ”„ Self-Update System

The system includes automated update capabilities for production deployments.

Update Architecture

  • Signed Updates: RSA cryptographic verification
  • Multi-platform: Updates for all supported architectures
  • Atomic Updates: Safe binary replacement
  • Rollback Support: Version history management

Update Sources

  • HTTP/HTTPS: Remote update servers
  • Local Files: USB or network storage
  • Version Archives: Historical version access

Update Process

  1. Version Check: Compare current vs available
  2. Download: Fetch signed binary
  3. Verification: Cryptographic signature check
  4. Installation: Atomic binary replacement
  5. Restart: Automatic service restart

Remote Update Control

  • Web Interface: Manual update triggers
  • MIDI Controller: Hardware-based updates
  • Automatic: Scheduled update checks
  • Emergency: Force update capabilities

πŸ”§ Development Guide

Note: This section is for developers who want to modify the software. Production users should use the binary installation above.

Prerequisites

  • VS Code with Remote SSH extension
  • SSH access to your embedded device configured
  • Basic knowledge of Go and TypeScript

Remote Development Environment

For the best development experience, use VS Code with Remote SSH extension to develop directly on the embedded hardware:

Step 1: Connect via VS Code Remote SSH

  1. Install Remote - SSH extension in VS Code
  2. Open Command Palette (Cmd+Shift+P / Ctrl+Shift+P)
  3. Run Remote-SSH: Connect to Host...
  4. Enter: ledctl@deskpi.local (or your device hostname)
  5. VS Code will connect and you can develop directly on the hardware

Step 2: Install Development Environment on Device

# Install Go 1.24+ (in VS Code terminal on remote device)
wget -c https://golang.org/dl/go1.24.5.linux-arm64.tar.gz
sudo tar -C /usr/local -xzf go1.24.5.linux-arm64.tar.gz
echo 'export PATH=$PATH:/usr/local/go/bin' >> ~/.bashrc
source ~/.bashrc
go version

# Install Task (build tool)
sudo sh -c "$(curl --location https://taskfile.dev/install.sh)" -- -d -b /usr/local/bin

# Install Node.js for frontend development  
curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash -
sudo apt-get install -y nodejs

Step 3: Clone and Setup Project

# In VS Code integrated terminal on remote device
git clone https://github.com/segfault16/modular-led-controller-workstation-v2.git
cd modular-led-controller-workstation-v2

# Install Go dependencies
go mod download

# Install frontend dependencies  
cd server && npm install && cd ..

# Generate API bindings
task local:protogen

# Build and run
task local:build
./build/local/modular-led-controller-workstation-v2

Backend Development

Architecture

  • Go 1.24+: High-performance backend
  • gRPC: API communication layer
  • Protocol Buffers: Efficient serialization
  • Real-time Processing: 60 FPS pixel processing

Key Components

// Effect interface
type Effect interface {
    Process()
    Update(ctx context.Context, dt float64)
    GetNumInputPixel(channel int) int
    GetNumOutputPixel(channel int) int
}

// Device interface  
type Device interface {
    Show(pixels *mat.Dense) error
    GetMaxPixels() int
}

Development Workflow

# Code generation
task local:protogen

# Backend development
go run main.go --config-location ./dev-config

# Testing
go test ./...

# Benchmarking
task benchmark

Frontend Development

Technology Stack

  • React 18: Modern UI framework
  • TypeScript: Type-safe development
  • Vite: Fast development server
  • Material-UI: Component library
  • gRPC-Web: Backend communication

Development Server

cd server
npm install
npm run start  # Development server on :3001

Build Process

# Production build
task build:frontend

# This creates optimized build in server/dist/
# Which gets embedded in Go binary via go:embed

Key Frontend Components

  • Graph Editor: Visual filtergraph editing
  • Parameter Controls: Real-time effect adjustment
  • Project Manager: Project file handling
  • Device Configuration: Hardware setup wizard

API Development

gRPC Services

  • Configuration: System and device configuration
  • Project: Project and scene management
  • Filtergraph: Graph manipulation
  • Stats: Performance monitoring
  • Preview: Visual feedback

Protocol Buffer Schema

service Configuration {
  rpc GetServerConfiguration(Empty) returns (ServerConfiguration);
  rpc UpdateServerConfiguration(ServerConfiguration) returns (ServerConfiguration);
  rpc CheckForUpdates(Empty) returns (UpdateCheckResponse);
  rpc UpdateNow(Empty) returns (Empty);
}

Testing Strategy

Unit Tests

# Run all tests
go test ./...

# Specific package tests
go test ./effects
go test ./filtergraph

Integration Tests

  • Hardware Mocking: Device simulation
  • End-to-end: Full system testing
  • Performance: FPS and latency testing

Manual Testing

  • Device Testing: Physical LED verification
  • Audio Testing: Live audio processing
  • Network Testing: Remote connectivity

Development Workflow

  • Edit code directly in VS Code with full IntelliSense
  • Use integrated terminal for build commands
  • Live debugging with Go extension
  • Frontend development with hot reload: cd server && npm run start
  • Access web interface at http://deskpi.local:3000

Recommended VS Code Extensions

  • Go (golang.go)
  • TypeScript and JavaScript Language Features
  • ESLint
  • GitLens
  • Remote - SSH

Contributing

  1. Fork the repository
  2. Create feature branch
  3. Follow Go and TypeScript best practices
  4. Add tests for new functionality
  5. Submit pull request

Code Standards

  • Go: Follow gofmt and golangci-lint
  • TypeScript: ESLint configuration provided
  • Testing: Maintain test coverage
  • Documentation: Update README for new features

πŸš€ Production Deployment

Embedded System Preparation

Raspberry Pi Setup

# Update system
sudo apt update && sudo apt upgrade -y

# Enable SPI
sudo raspi-config
# Interface Options β†’ SPI β†’ Enable

# Install dependencies
sudo apt install -y systemd avahi-daemon

Orange Pi Setup

# Similar to Raspberry Pi
sudo apt update && sudo apt upgrade -y

# Enable SPI in device tree
# (Device-specific configuration)

Service Configuration

Systemd Service

[Unit]
Description=goLEDgo LED Controller
After=network.target

[Service]
Type=simple
User=pi
WorkingDirectory=/home/pi/ledserver
ExecStart=/home/pi/ledserver/modular-led-controller-workstation-v2
Restart=always
RestartSec=5
Environment=HOME=/home/pi

[Install]
WantedBy=multi-user.target

Network Services

# mDNS configuration
sudo systemctl enable avahi-daemon

# Firewall (if needed)
sudo ufw allow 3000/tcp  # Web interface
sudo ufw allow 22/tcp    # SSH

Deployment Automation

Remote Deployment

# Deploy to remote device
task remote:deploy TARGET_HOST=orangepi3.local TARGET_ARCH=linux-arm64

# Initialize projects
task remote:init-project TARGET_HOST=orangepi3.local

Monitoring

  • System Logs: journalctl -u goledgo -f
  • Performance: Built-in FPS monitoring
  • Remote Access: Web interface + SSH

πŸ“š Troubleshooting

Common Issues

SPI Permission Errors

# Add user to SPI group
sudo usermod -a -G spi $USER

# Or run with elevated permissions
sudo setcap 'cap_net_raw,cap_net_admin+eip' ./modular-led-controller-workstation-v2

Audio Device Issues

# List available audio devices
./modular-led-controller-workstation-v2 --list-audio-devices

# Specify audio device
./modular-led-controller-workstation-v2 --audio-device 2

Performance Issues

  • Check FPS: Monitor real-time FPS in web interface
  • Reduce LED Count: Lower pixel count for testing
  • SPI Speed: Adjust maxSPISpeedMHz in configuration
  • CPU Usage: Monitor system resources

Network Connectivity

# Check service status
sudo systemctl status goledgo

# Check network interface
ip addr show

# Test web interface
curl http://localhost:3000

Debug Mode

# Enable verbose logging
./modular-led-controller-workstation-v2 --log-level debug

# No configuration mode (for testing)
./modular-led-controller-workstation-v2 --no-config --num-pixel 100

Recovery Procedures

Configuration Reset

# Backup current config
cp ~/.ledserver/config.json ~/.ledserver/config.json.backup

# Start with default configuration
./modular-led-controller-workstation-v2 --no-config

System Recovery

# Emergency stop
sudo systemctl stop goledgo

# Manual binary replacement
# (for update failures)

πŸ“„ License

[License information would go here]

πŸ™ Acknowledgments

  • periph.io: SPI and hardware interface library
  • go-selfupdate: Update system foundation
  • React: Frontend framework
  • gRPC: High-performance API layer

Quick Reference

Essential Commands

# Production deployment
./modular-led-controller-workstation-v2

# Development mode
task local:build && ./build/local/modular-led-controller-workstation-v2

# Update check
curl http://localhost:3000/api/config/updates

# Service control
sudo systemctl {start|stop|restart|status} goledgo

Default Ports

  • Web Interface: 3000
  • gRPC API: 50051
  • MIDI Bridge: Various (auto-detected)

Configuration Locations

  • Global Config: ~/.ledserver/config.json
  • Projects: ~/.ledserver/projects/
  • Device Config: ~/.ledserver/device-configs.json

This comprehensive guide covers the complete user journey from initial installation through advanced development scenarios, providing both newcomers and experienced developers with the information needed to successfully deploy and customize the goLEDgo system.

About

🎡 🌈 Real-time audio-reactive LED strip music visualization

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages