The date on this post is inaccurate, but this happened sometime in May.
I assembled an LED cube. These are interesting devices - they rely on a human feature called persistence of vision, and a microprocessor feature called ‘switching state really fast’.
The model I purchased came in a 4x4x4 configuration - this is 64 LEDs.
Wiring each LED in the cube to a single control pin on the microprocessor would require a 64 pin microprocessor - these are rare and expensive, and GPIO extenders are pretty slow.
Instead, the microprocessor controls the 3D array of LEDs by strobing through a matrix of enabled LEDs very quickly. The 3D cube is 4x distinct 2D layers of 4x4 LEDs. The LEDs are wired in a configuration with a controlled ground. This means each 2D layer of 4x4 LEDs needs 5 controllable pins on a microprocessor, with at least one pin being a sink, and all the others drivers.
Since there are 4 2D layers, 4x5 requires 20 pins to control. The software provided by the distributor is very basic to fit timing and resource constraints.
The critical code lives inside an interrupt timer that triggers ever 2.2ms. This code must be lightweight, so instead of setting individual GPIO ports, the code uses GPIO banks. This means it writes an 8bit value to each bank which represent the state of the inputs and the output. Doing this at such speed means it strobes through each layer of LEDs very quickly, imperceptable to us.
Since interrupts are triggering this critical but fast code, we can still do processing in the standard Arduino loop() function, which is called whenver you return from it. In here, I decided to expand the LED cube. I reflashed the device successfully.
Then I wanted to remotely control the device, without any USB cable connected to it. I soldered a 433mhz receiver, a superheterodyne model, onto one of the LED ports. This column of LEDs was now connected to the receiver. I disabled it by doing some bit bashing, meaning my code will never change the state of those LEDs. After adding more code, I could recieve 4 integers that represented the state of the LED cube.
I added some neat features
- Set a specific position to blinking for a short duration
- Added another Arduino to send data from MQTT, changing the states of the LEDs
- One layer is temperature gauges
- One layer represents my 3D printer and if it’s on, warmed up, idle, or the percentage of the way through the print it is.
- An animation plays if certain motion sensors move, letting me know if any of them are acting strangely