Skip to content

TexablePlum/PixelTree

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

5 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

PixelTree

A hand-built addressable-LED decoration with ESP32-S3 firmware and a cross-platform Flutter companion app. Built as an engineering thesis project at the Silesian University of Technology.

PixelTree is a physical string of WS2812D ARGB LEDs driven by a Seeed Studio XIAO ESP32-S3 microcontroller. The firmware renders 42 animated lighting effects in real time and exposes a REST API over Wi-Fi; the mobile app discovers devices on the local network, provisions Wi-Fi credentials securely over Bluetooth Low Energy, and controls effects, colors, parameters, and brightness. The hardware lives in a custom 3D-printed enclosure.

ESP32-S3 Arduino C++ FastLED Flutter Dart Bluetooth LE

PixelTree running an effect The PixelTree device

Repository layout

Path Contents
Firmware/ Arduino C++ firmware for the XIAO ESP32-S3 (the .ino sketch and its headers).
Mobile/ Flutter/Dart companion app for Android and iOS.
Case/ 3D-printable enclosure: OpenSCAD source and exported STL files.
LaTeX/ The engineering thesis, its LaTeX sources, schematics, renders, and screenshots.

The full thesis (Polish) with hardware schematics and design rationale is available at LaTeX/Projekt_inżynierski_Dominik_Porębski.pdf.

Features

  • 42 lighting effects across 9 categories: static, waves, chases, twinkle/sparkle, fire/organic, seasonal, special, breathing/fade, and alarm. Each effect exposes its own live-tunable parameters such as colors, speed, palette, density, and gravity.
  • Real-time rendering at a target 60 FPS. Animation runs in a dedicated FreeRTOS task pinned to Core 0, kept independent of the Wi-Fi/BLE stack on Core 1, with a brief crossfade when switching effects.
  • Cross-platform app: a single Flutter codebase for Android and iOS, with a layered architecture and English/Polish localization.
  • Two connectivity modes: connect the device to an existing home network in Station mode, or have it host its own access point in AP mode when no LAN is available.
  • Secure BLE provisioning: Wi-Fi credentials are exchanged over BLE using ECDH (P-256) key agreement, with the Wi-Fi password encrypted via AES-128 before transmission.
  • Zero-config discovery: devices advertise over mDNS, so the app finds every PixelTree on the network without manual IP entry. Each device gets a unique name derived from its MAC suffix, such as PixelTree-A1B2.
  • Persistent state: selected effect, its parameters, brightness, and Wi-Fi credentials survive reboots via the ESP32 NVS. A factory reset is available by holding the GPIO button for 5 seconds.

Architecture

graph LR
    subgraph Mobile App
        APP[Flutter app<br/>Android / iOS]
    end

    subgraph Transport
        BLE[Bluetooth LE<br/>secure provisioning]
        HTTP[Wi-Fi / REST + mDNS<br/>control & discovery]
    end

    subgraph Device
        ESP[XIAO ESP32-S3<br/>C++ firmware / FreeRTOS]
        LED[WS2812D LED string]
    end

    APP <-->|ECDH + AES| BLE
    APP <-->|JSON over HTTP| HTTP
    BLE <--> ESP
    HTTP <--> ESP
    ESP -->|single-wire data| LED
Loading

Typical flow: the app provisions Wi-Fi over BLE, or the user joins the device's AP directly, then the device joins the network and advertises an HTTP service via mDNS, and from then on the app controls lighting through the REST API.

Firmware

The firmware is organized as a set of single-responsibility modules included from the main sketch:

  • LEDController: owns the FastLED buffer and the rendering task; dispatches to the effect functions and applies parameter changes live.
  • Effects / EffectDefs / EffectParams / Palettes: the 42 effect implementations, their parameter structs and defaults, and color palettes.
  • WiFiManager: Station/AP mode handling, reconnection with exponential backoff, mDNS, and device naming.
  • BLEProvisioning: BLE GATT server with separate services for Wi-Fi scanning, credential transfer, and ECDH key exchange (mbedTLS).
  • HTTPProvisioning / LEDApi: the async HTTP server and the LED control REST endpoints.
  • NVSManager: persistent storage of credentials, effect, parameters, and brightness.
  • SerialLogger: leveled serial logging.

Mobile app

The app follows a layered structure under Mobile/lib/:

  • presentation/: onboarding, device list, connection-mode selection, the provisioning wizard, and the control screen.
  • data/: datasources (BLE, HTTP, crypto, local storage), services, repositories, and models.
  • core/: theme, colors, BLE UUIDs, and effect metadata.
  • l10n/: English and Polish localizations.

REST API

The firmware exposes the following endpoints (JSON, with permissive CORS):

Method Endpoint Purpose
GET /api/led/status Current power, brightness, and active effect.
GET /api/led/effects List of all effects with id, name, and category.
GET /api/led/params Parameters of the active effect.
POST /api/led/effect Switch effect ({"id": <n>}).
POST /api/led/params Update one or more parameters of the active effect.
POST /api/led/power Turn the LEDs on/off ({"on": true}).
POST /api/led/brightness Set brightness ({"value": 0-255, "save": false}).

Example:

# Switch to the "Fire" effect (id 18) and dim to ~70%
curl -X POST http://pixeltree-a1b2.local/api/led/effect   -H "Content-Type: application/json" -d '{"id":18}'
curl -X POST http://pixeltree-a1b2.local/api/led/brightness -H "Content-Type: application/json" -d '{"value":180,"save":true}'

Hardware

Component Notes
Seeed Studio XIAO ESP32-S3 Dual-core Xtensa LX7 @ 240 MHz, Wi-Fi + Bluetooth 5 (LE). Main compute unit.
WS2812D LED string Addressable RGB LEDs on a single-wire data line. The firmware is configured for 75 LEDs.
3D-printed enclosure Custom FDM-printed case; sources in Case/.

Key firmware pin/configuration defaults (see Firmware/Config.h):

  • LED data on GPIO44 (D7), 75 LEDs, 60 FPS target, 45 W power cap.
  • Factory-reset button on GPIO9 (active-low, hold 5 s); status LED on GPIO21.

Pin counts and LED count are compile-time constants in Config.h: adjust them to match your own build.

Getting started

Firmware

The firmware is an Arduino sketch. With the Arduino IDE (or arduino-cli):

  1. Install the ESP32 board support package (Espressif) and select the XIAO ESP32-S3 board.

  2. Install the required libraries via the Library Manager:

    The BLE stack and mbedTLS crypto come with the ESP32 core.

  3. Open Firmware/Firmware.ino, then compile and flash to the board.

  4. Open the serial monitor at 921600 baud to watch boot logs.

On first boot (no stored credentials) the device starts in provisioning mode: it raises an access point named PixelTree-XXXX and advertises over BLE for the app to configure.

Mobile app

Requires the Flutter SDK (Dart SDK ^3.10).

cd Mobile
flutter pub get
flutter run            # run on a connected device or emulator
flutter test           # run the unit/widget tests

To build release artifacts:

flutter build apk      # Android
flutter build ios      # iOS (requires macOS + Xcode)

Screenshots

The provisioning and control flows are captured in LaTeX/source/Screens/: onboarding, BLE/AP setup, network configuration, and the main control screen.

Splash screen Connection method Wi-Fi configuration Control screen

Tech stack

  • Firmware: C++ (Arduino), ESP32-S3, FreeRTOS, FastLED, ArduinoJson, ESPAsyncWebServer, mbedTLS.
  • Mobile: Flutter / Dart, flutter_blue_plus (BLE), pointycastle (ECDH/AES), dio (HTTP), bonsoir (mDNS), shared_preferences, flex_color_picker.
  • Hardware/CAD: WS2812D LEDs, XIAO ESP32-S3, OpenSCAD enclosure.

Author

Dominik Porębski: engineering thesis, "Design and implementation of an ARGB LED decorative lighting system using an ESP32 microcontroller with a dedicated mobile application", Silesian University of Technology, Gliwice, 2026.

About

Hand-built addressable-LED decoration: ESP32-S3 firmware (42 real-time effects, REST API) with a Flutter companion app and BLE Wi-Fi provisioning.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors