LED Cube

4,096 individually addressable LEDs soldered together into a big cube.

Overview

I’d like to have a really good reason for this one, but there unfortunately isn’t one. This was originally supposed to be a summer-long project, but it ended up taking hundreds of hours over the course of nearly a year. The process of building the cube involved manually soldering together 4,096 individual LEDs, distributing up to 1.2 kW of power between them, building a custom control system to drive them all at once, and creating varied animations to display, including a couple of interactive multiplayer games.

Cube Structure

The very first step was deciding the size of the cube I wanted to build. I decided to go with a 16x16x16 layout, as it would provide a reasonable resolution and allow for lots of different animations. The cost of this choice meant there were 16³ = 4,096 LEDs which had to be manually soldered into a cube. It was clear that this soldering was going to be the most difficult and time-consuming task, so it made sense to solve that first. However, before soldering could begin, I first needed to figure out how to actually connect all the lights together. Each of the LEDs needs four connections: 5V power, ground, and a data in/out connected to the previous/next LED in the sequence.

Making sure the final construction was repairable was both the most important consideration, and the most difficult thing to get right. The first solution I considered was simply wiring each LED to the ones around it, making a single solid structure. However, this would be difficult to assemble, and any LEDs not on the edges would be impossible to reach or replace. I spent some time looking for existing examples, and found a similar project by MaltWhiskey on YouTube that uses LEDs built into 16x4x4 columns. Being able to remove a single 16x4x4 column would make repairs plausible, but making all of the power and data connections for each LED in this structure would be pretty complicated.

MaltWhiskey's 16x4x4 tower layout.

The final design I landed on is 16x16x1 sheets. The flat 2D layout means each LED is directly accessible by removing a single sheet, and routing power and data wires can be greatly simplified. My main concern with this layout was stability. It would be important to make sure each sheet was rigid enough to avoid flexing and touching adjacent ones, thus avoiding a short circuit. The chosen process for constructing a single sheet was to first build the 16x1x1 rows, then stack them vertically to reach the full height.

A segment of a 16x1x1 row with power/ground wires at the base, and diagonal data lines connecting data-in and data-out of each LED.
A full 16x16x1 sheet. Power is brought up through two central wires, and data is routed up from the base in a snaking path.

Soldering

The next step was the tedious task of actually making the 16,000+ individual connections needed to build the cube. I designed several 3D printed tools for holding components while soldering to make sure the spacing between LEDs was consistent. There is one tool to hold everything needed to solder the 16x1x1 rows, and a second set of tools to stack those into the full 16x16x1 sheets.

There was also a simple tool to make mass-cutting short wires for the data connection between LEDs easier, and one to bend wires into a specific shape for bridging the data connection over the vertical gap between each row when they are stacked in a sheet.

The first jig solders 16 LEDs into a single row, connecting each to power and routing data between them.
Second set of jigs combines 16 strips into a 16x16x1 sheet.

Power Distribution

With some freshly-soldered prototypes ready to test, the next step was figuring out how to power everything. With every LED on at full brightness, the cube draws 1.2 kW of power. A cursory search suggests this is roughly equivalent to running a microwave or hair dryer.

Despite this full-brightness mode not being at all nice to look at (it’s very bright), I made sure it could be handled by the power distribution system to avoid needing to protect components with a cap in software. The load is spread between 4x 300W (5V@60A) power supplies. This almost exactly matches the worst-case load, but it’ll never need to run at full brightness for an extended period of time. Splitting between four power supplies makes it much easier to route wires, and it removes the need to deal with relatively large high-current wire. After the supplies, power is distributed to the LED sheets via the rather inelegant method of a bunch of long wires and Wago splices.

Testing the power supplies chained together.

Small wires also bridge the power supplies to create a shared ground reference between the sheets and controller to prevent weird electrical magic from causing issues. This was also my first time doing anything directly wired to a wall outlet, and that made everything more exciting.

Enclosure Design

The full cube was designed in Onshape, and went through several iterations to reach its current form. The whole thing needs to be sturdy, look nice, and perhaps most importantly, allow easy access to the insides for repairs or updates.

Walls

The walls of the base were the main challenge while designing the cube. All iterations were 3D printed out of black PLA, and designed to fit on a 10”x10” bed. After I finalized the size of the cube, I ordered a thin 0.09” aluminum baseplate that would act as a heatsink for the power supplies and provide a source of truth that would make it easy to keep everything square.

My first wall design used large segments fit together with steel dowel pins. This was simple and had a perfectly smooth outer finish, but it was impossible to remove one panel at a time, and it was difficult to get a tight fit on the pins.

These walls were also the only things supporting the internal mounting rails for the LED sheets, and the panels couldn’t be removed without leaving them floating. Basically, everything had to go together and come apart in a very specific and difficult order, and no individual pieces could be removed without a full disassembly. This directly contradicted the need to keep it repairable, so I ultimately scrapped the design and restarted with a different approach.

Old pin-based wall design.

The final version of the base sacrifices the smooth outer panels to have 12 independent sections, all bolted together with hardware accessible from the outside. This was more complicated to design, but the bolts provided a much more rigid connection than the loose pins, making the whole base a lot stiffer. Additionally, I moved the LED sheet mounting to separate bolted-on pieces so that any outer panel could be freely removed while the mounting rails remained supported by the baseplate.

New panel walls with separate piece (blue) supporting the sheet mounting rail (yellow) by resting on the baseplate.

Sheet Mounting Rails

Another challenge in the design was finding a way to mount the LED sheets. Each sheet has three pairs of thin wires extending into the base, and these need to support the sheet, allow electrical connection, and be able to slide straight up through the small holes in a decorative top plate (no bending or soldering to the wires).

My solution for this was to slide the wires through holes in 3D printed brackets which can be clamped together to hold the sheet in place. Then, easily removable Wago connectors can be attached to the bottom of the main power wires. This method also allows the height of the sheets to be precisely adjusted when mounting. The clamps are attached to three sheet metal rails that run the length of the cube, and each rail captures one pair of wires from each sheet.

A single row of clamps with the paired wires from each sheet.
Mounting of a single sheet, through clamps and into Wagos. Shows half of the decorative top panel the wires must fit through.

Control System & Software

The control system of the cube is split into two main components. A Teensy 4.1 microcontroller hosts the firmware that runs animations and displays them on the cube. It is wired to all 16 LED sheets, and connects to the second half of the system, an old Raspberry Pi. The Pi allows for remote firmware updates and animation changes without needing to physically access the inside of the cube. In addition to firmware updates, the pair also communicates live over USB serial, enabling a Pi-hosted web dashboard to switch animations and otherwise control the cube.

Animations

There are many animations of varying quality, and it’s very easy to add more. Each animation has configurable parameters such as speed and color, and these can be live updated while it runs. Most of them were designed and iterated through Claude Code, and several were directly adapted from MaltWhiskey’s cube. Some animations, like a US flag or spinning soccer ball, were created in a single prompt for an occasion (4th of July, World Cup). Others, like a live fluid simulation, took lots of iterations and unique approaches to get working.

1 / 5

A fun bonus of the cube’s wireless capability is the ability to connect multiple devices to run “game mode”. There are currently two games: a two-player 3D pong game, and a Flappy Bird-esque game where up to six players attempt to move their player to dodge incoming walls. It’s unfortunately quite difficult to accurately judge positions and control a player in the 3D space of the cube, and nobody is very good at either game. Both games have a lobby system where players can customize controls, choose player colors, and tweak different aspects of the game like paddle size, ball speed, etc. There is a dedicated countdown animation, and an existing fireworks animation is reused when the game is won to indicate the color of the champion.

Issues

Despite my best efforts it is still quite difficult to repair or change anything about the cube, though it’s at least possible with a little motivation. This is primarily due to the fact that getting enough room to fit hands or tools inside the ~3” tall base requires the bottom to come off. Unfortunately, getting the bottom off involves balancing the rest of the cube on a pair of suitcases, and that is a very scary task with the thousands of delicate solder connections hanging in the balance. To make matters worse, the only access to a cat-free room where the cover can come off involves a trip up stairs. Ultimately, it’s not worth moving the cube to fix a single connection when the trip back is likely to break another.

Cube under construction.

Occasionally a few flickers will still appear from loose connections. It’s incredibly annoying, but it works most of the time, and so far everything has been mostly fixable with a little nudge or careful soldering from the outside. The removable sheet design was very useful when working out all the initial problems, and I still haven’t been able to come up with a solution without the access issues. The most plausible idea so far is integrating the entire cube into a custom table of some kind that can take the place of the suitcases and give permanent access to the sheet mounting rails, but that’s not happening any time soon.

Fortunately everything else works really well. There haven’t been any issues with the control system, and the base itself is durable and works exactly as intended.

Scrapped Features

Many things ended up in the final version, but there were several ideas that were never implemented for various reasons.

Custom PCB

While setting up and testing the Teensy controller, I took the opportunity to learn a bit of PCB design and made a simple board in KiCad. The idea was to build a single board that could house the Teensy and all the resistors, level shifters, etc. and have 16 easy-to-use outputs for the sheets. I didn’t end up ordering it because of shipping time, lack of flexibility, and doubt that it would actually work (though I couldn’t find anything wrong with it either).

Active Cooling

The case has four spots for 80mm PC fans which were intended to actively cool the power supplies when running under load. However, it turns out most animations only have a fraction of the lights on at a time, and the fans built into the power supplies are sufficient. The initial setup had the fans always running while the cube was on, but they were pretty noisy once dust filters were added, thus prompting their removal. The specific fans I used were chosen for their support of PWM speed control, so if they ended up being necessary they could be controlled based on temperature sensors or a software-calculated load metric of some kind.