
Heart Pixel
Heart-Shaped Reactive LED Jewelry
This project is a custom-designed LED heart badge that responds to the way you move. I’ve spent years working on it, making countless prototypes, carefully optimizing both the hardware and software to create something that’s both technically sophisticated and aesthetically pleasing.
What makes it special
What makes this pendant different is how it establishes a relationship with you:
- It reacts organically to your movements, creating a unique visual response to how you move and hold yourself.
- It becomes an extension of your body language, almost like a piece of clothing that adapts to you rather than you adapting to it.
- The different modes can express different feelings - from calm flowing patterns to energetic particles, allowing you to match it to your mood.
The combination of technical performance and emotional expressiveness makes this a unique piece that doesn’t exist anywhere else. After months of development, I’ve created something that doesn’t get old because it’s constantly responding to you in new ways - if it were just cycling through static patterns, you’d quickly get bored of it.
One thing I like about this is I feel like I’m creating something new, something that no one else is doing. This is the only place you can get this interactive jewelry that sits at the intersection of wearable art and responsive technology.
Technical Details
The badge uses an ATtiny1616 microcontroller which drives an LED matrix in a charlieplex topology, with a LIS2DH12 accelerometer for motion and tilt sensing. Key features include:
- Motion-activated operation – it only wakes up when you move it, preserving battery life; the badge goes into low-power mode after the animation cycle is complete.
- Ultra-low power idle mode that consumes less than 5 µA when idle, allowing it to last for years on a single watch battery. You don’t need to worry about turning it off too much.
- Over 35 different animation modes – These include pendulum simulations, flowing patterns, particle effects, spiral animations, and even scrolling text. Each mode took a least a couple of days to develop. All modes are motion and/or tilt sensitive in some way.
- Persistent memory saves your preferred mode between uses.
- Efficient code that maximizes visual effects while minimizing clock cycles and power consumption.
Hardware development
One of my design goals was to make a charlieplexed badge as small as possible, which means designing around the pin bar and batttery holder, and I made the PCB as small as possible and crammed components in the few spaces left. For the first time I settled on the CR1632 battery size, to accomodate the small space.
I spent a long time trying to design a heart-shaped pixel grid where the number of pixels is as close as possible to the max number of LEDs I could support with an 8 bit port register.
It was extremely time consuming doing the trace routing given the extremely constrained space, since I was still using the free version of Eagle at this point which only support two layer routing. It’s more difficult to get boards manufactured with 4 layers with red soldermask in any event.
I had the idea to programmatically rotate the LEDs on the board, rather than having them uniformly 45° as is more typical for LED matrices. I spent way too much time developing and comparing different rotation formulas (and much layer wrote a whole GUI LED-rotating shader system) and eventually settled on rotating the LEDs at a 90° angle from their polar angle from a centroid way off-center for a more subtle effect.
I also wrote a program to generatively optimize the LED assignments to each position given the charlieplex network topology and the non-standard arrangement of the pixel heart. I spent way too much time on this trying to encorporate principles of gradient descent and one-armed bandit models, but it made the otherwise almost impossible routing much easier.
Algorithms, firmware and development
All of the animations are implemented as 8-bit state machines, without ever using floating point or division, operations which the ATtiny microcontroller does not natively support. This makes developing the trigonometry and linear algebra calculations that the animations extremely time-consuming. I also needed to underclock the microcontroler by 90% to prevent brownouts when an LED is switched on while powered by a small watch battery with an extremely high internal resistance and discharge capacity; this further constrains your computing capacity when you need the microcontroller to manage computing animation frames, driving the LED matrix animation cycle directly, and communicating with the accelerometer.
I borrowed heavily from FastLED’s 8 bit math functions, but have to develop/discover some techniques of my own, such as a method of computing hypotenuses using using only shifts and adds.
Fortunately since I spent so much time on optimization there was plenty of the microcontroller’s 2kb of RAM left for precomputed lookup tables. For instance, on small orthogonal uniform grid the set of possible Euclidean distances between any two leds is equal to the number of leds; you can just store a 2D lookup table where the indexes are the x/y deltas. I store precomputed Carestian and polar coordinates of every LED, scaled to fit into an 8 bit integer range.
This was the first project where I supported user-selected animation modes via a pushbutton, since I was now using a more modern (though extrmely basic) ATtiny1616 microcontroller than the ATtiny24’s I had been using up until this point.
I spent an enormous amount of time developing animation modes, and optimizing them to use as little compiled space as possible to fit onto the extremely limited flash space of the microcontroller.
I eventually made more than 35 of them. They took a couple of days each, probably. All are based on acceleration and/or tilt in some way. It was extremely difficult to work out the math for some of them, though some of it was simple in hindsight, especially when you’re limited to simulated 8 bit trigonometry functions. I was able to encorporate particle simulations and procedural generation.
I was pleased with how much I was able to do with it, and although I still have ideas for more, I eventually completely exhausted the flash space.
It was several years between the initial concept and the point where I finished the flash space.
Current modes
- Expanding cell: Simple pixel heart frame animation
- Noisefield: Creates dynamic noise patterns that respond to tilt
- Sweep: Animates a sweeping line across the heart
- Fireball: Displays a fireball effect moving through the heart
- Arrow: Shows an animated arrow that sweeps across the heart based on tilt
- Space Core: Creates a space-themed animation with a central pulse
- Digital Sparkle: Randomly lights up LEDs with a sparkle effect based on recent number of taps
- Level indicator: Demonstrates the current tilt angle with a beam
- Wide Radar: Creates a radar-like scanning effect (non-double version)
- Wide Radar Double: Similar to wide radar but with double beams
- Heartbreak: Shows a heart breaking with a crack effect
- Doomfire: Creates a fire effect rising from the bottom
- Raindrops (Tap): Simulates raindrops that are tilt-corrected, activated on top
- Raindrops (Continuous): Raindrops pattern continuous, tilt corrected
- Pendulum (Wedge): A pendulum with wedge visualization
- Pendulum (Lava): A pendulum with lava-like visualization
- Pendulum (Level): A pendulum with level visualization
- Spiral Point (Fast): Fast-moving spiral point animation
- Spiral Point (Slow): Slow-moving spiral point animation
- Spiral (Fast): Fast spiral animation
- Spiral (Slow): Slow spiral animation
- Expanding Circle (Fast): Fast expanding circle animation
- Expanding Circle (Slow): Slow expanding circle animation
- Flowing Heart: Heart animation that flows in a compass pattern
- Cross: Cross animation at base position with tilt offset
- Expanding arms: Rotating arms with tilt offset
- Cross (Rotating): Rotating cross animation
- Droplet: Water droplet-like ripple effect, tap triggered
- Lines (Random Walk): Lines that move in random walks
- Lines (Walls, Single): Single line bouncing off walls
- Lines (Walls, Double): Double lines bouncing off walls
- Lines (Rough Circle, Single): Single particle moving in a chaotic circle pattern
- Lines (Rough Circle, Double): Double particle moving in chaotic circle patterns
- Bouncy: Physics-based bouncing ball animation
- Hello Message: Scrolling “HELLO” text message
- I Love You Message: Flashing “I LOVE YOU” text
- Friend Message: Scrolling “FRIEND” text message