Skip to content

Repository files navigation

LED Cube

A 16×16×16 (4096 LED) WS2812B cube driven by a Teensy 4.1, with a web dashboard for flashing firmware and controlling animations live.

How it works

   Browser ──/api──▶  Flask backend  ──USB serial──▶  Teensy 4.1  ──▶  4096 LEDs
  (SvelteKit)         (Raspberry Pi)                  (firmware)
  • The Teensy runs C++ firmware (OctoWS2811) with a registry of animations. It listens on USB serial for commands to switch animations and tweak parameters live.
  • The Raspberry Pi runs a Flask backend that relays animation commands to the Teensy over serial and flashes new firmware (.hex) onto it.
  • The dashboard (SvelteKit) is the UI: pick an animation, adjust its parameters with auto-generated controls, and upload firmware.

Repository structure

ledcube/
├── dev.sh             # Run the dashboard dev server locally
├── deploy.ps1         # Build + deploy frontend & backend to the Pi (Windows/PowerShell)
├── setup.ps1          # One-time Pi provisioning (Windows/PowerShell)
├── ledcube.service    # systemd unit for the backend
├── firmware/          # Teensy 4.1 firmware (PlatformIO, env:teensy41)
└── dashboard/
    ├── backend/       # Python Flask API (status / animations / flash)
    └── frontend/      # SvelteKit + Svelte 5 + Tailwind 4 + TypeScript

See CLAUDE.md for detailed architecture, the serial protocol, the coordinate system, and conventions.

Quick start

Development environment (Nix)

This repo ships a flake.nix dev shell with the full toolchain — Node (for the dashboard), PlatformIO (for firmware), and Python + Flask/pyserial (for the backend). On a machine with Nix (flakes enabled):

nix develop          # drops you into a shell with node/npm, pio, and python
./dev.sh             # then run the dashboard (or `nix develop -c ./dev.sh`)

The lockfile (flake.lock) pins exact package versions, so the toolchain is reproducible across machines. To auto-activate the shell on cd, add an .envrc containing use flake and install direnv.

Just need Node once, without the project shell?

nix shell nixpkgs#nodejs_22

Not using Nix? Install Node 22+ and (for firmware) PlatformIO by your usual means; the commands below are the same.

Dashboard (frontend)

./dev.sh

Starts the SvelteKit dev server (default http://localhost:5173) for local, live-reload development. API requests are proxied to the Pi's backend — set the target in dashboard/frontend/vite.config.ts if the Pi's address changes.

In production the dashboard is served by the Pi at http://ledcube.local/, so it's reachable from any device on the network — no dev server needed. The frontend builds to a static bundle that the Flask backend hosts; deploy.ps1 builds and ships it (see below).

Firmware

Built with PlatformIO. From firmware/:

pio run              # build → .pio/build/teensy41/firmware.hex
pio run -t upload    # build + flash directly over USB

You can also flash through the dashboard by uploading the built .hex, or POST it to the backend:

curl -X POST -F "file=@.pio/build/teensy41/firmware.hex" http://<pi-host>/api/flash

Backend / Raspberry Pi

PowerShell scripts deploy the dashboard to the Pi over SSH (defaults: host ledcube.local, user ledcube):

.\setup.ps1     # once per Pi: installs teensy_loader_cli, venv, udev rules, systemd service
.\deploy.ps1    # each update: builds + ships the frontend and backend, restarts the service

The Pi's Flask backend serves both the JSON API and the built frontend on port 80, so the dashboard is reachable at http://ledcube.local/ from any device on the network. (On Linux the *.ps1 scripts don't apply — see the "Deploying from a Linux machine" section of CLAUDE.md.)

Animations

ID Name ID Name
0 Twinkle Fade 11 Wave
1 RGB Color Shift 12 Snow
2 Twinkle 13 Fireworks
3 Random 14 Helix
4 Solid 15 Sine
5 Rainbow Fade 16 Cube
6 Fill 17 Starfield
7 Plane Sweep 18 Atoms
8 Rain 19 Plasma
9 Test 20 Life
10 CenterPulse

Each animation lives in firmware/src/animations/ and has a matching entry in the backend's ANIMATIONS dict (dashboard/backend/app.py). See the "Adding a new animation" section of CLAUDE.md.

Helix, Sine, Cube, Starfield, Fireworks, Atoms, Plasma, and Life are ported from MaltWhiskey's Mega-Cube (see Credits). Several share the Vector3 + Quaternion math in firmware/src/Math3D.h — see README_3D_MATH.md for a walkthrough.

Hardware

  • Teensy 4.1 + OctoWS2811 library
  • 16 WS2812B strips × 256 LEDs (one strip per cube layer), WS2811_RGB | WS2811_800kHz
  • Raspberry Pi connected to the Teensy via USB (/dev/ttyACM0)

Credits

  • The Fireworks, Helix, Sine, Cube, Starfield, Atoms, Plasma, and Life animations are ported from MaltWhiskey's Mega-Cube (Software/LED Display/src/space/), adapted to this cube's coordinate system and animation framework. The Vector3/Quaternion math (firmware/src/Math3D.h) and the voxel/radiate drawing helpers are trimmed-down versions of its power/Math3D and core/Graphics. Thanks to MaltWhiskey for the original cube and its open-source animations.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages