This website uses cookies

Read our Privacy policy and Terms of use for more information.

This issue is the first proper technical write-up. I am going to tell you about the NeoPixel LED cube: how I built it, what nearly went wrong and the fire effect algorithm that was the most satisfying thing I have written.

What it is.

The cube is a 4x4x4 matrix of 64 WS2812B LEDs, all hand-soldered onto a copper wire frame, controlled by an Arduino Uno. It has four animation modes, ambient brightness that adapts automatically to the room and physical button controls. No kit. No pre-made frame. Built from scratch as a university project that became something I am genuinely proud of.

The hardware problem nobody warned me about.

Before I could write a single line of firmware, I had to physically construct a three-dimensional wire frame and solder 64 LEDs onto it with every LED facing outward. That sounds manageable until you are on your fifteenth joint and the frame starts to twist.

The solution was a jig: a wooden block with holes drilled at precise intervals. Each LED sits in a hole, held in position while you solder. Each layer was tested for continuity before being stacked onto the previous one. A cold joint in the middle of a WS2812B chain is extremely difficult to find because everything after the fault goes dark with no indication of where the break is.

Testing each layer individually before stacking saved me hours of rework. That discipline, checking thoroughly before committing, applies well beyond soldering.

Power budgeting is not optional.

Each WS2812B LED draws up to 60 mA at full white brightness. Multiply that by 64 and you are looking at 3.84 A. A USB port cannot supply that, and running close to that limit causes voltage spikes that corrupt the LED data line and produce random colour flashes mid-animation.

Two things fixed this. First, I capped maximum brightness in software so the cube never runs all 64 LEDs at full white simultaneously. Second, I added a 1000 microfarad electrolytic capacitor across the 5V power rail. That capacitor does not appear in most beginner tutorials. It matters the moment you scale beyond a handful of LEDs.

The fire effect.

This was the most technically interesting animation to build. It uses a two-dimensional heat array representing the temperature at each LED position in the matrix. Every frame, heat propagates upward from the bottom layer with random variation and decays at a configurable rate. The heat value maps to a colour: deep red at low heat, orange in the mid range and bright yellow-white at maximum.

The result is a convincing upward flame in under 30 lines of C++. Getting the decay rate and propagation speed right required several iterations. Too fast and it looks like static. Too slow and it looks like a lava lamp. The right parameters produce something that genuinely resembles fire.

Adaptive brightness.

A light-dependent resistor on an analogue pin reads ambient light in real time. The raw 10-bit ADC reading maps inversely to LED brightness. In a bright room the cube runs brighter. In a dark room it dims automatically. This runs in a non-blocking loop using millis() so the brightness updates continuously without interrupting the animation.

What the timing constraint taught me.

The WS2812B data protocol uses specific pulse widths measured in hundreds of nanoseconds. On an Arduino at 16 MHz this is reliable, but any interrupt that fires mid-frame corrupts the entire frame. Disabling interrupts during LED updates was necessary for stable output. That is a detail you only find by reading the datasheet rather than following a tutorial.

Next issue: I built a free Git course with 217 files and no paywall. Here is why.

Zac

Reply

Avatar

or to participate

Keep Reading