The Mathematics of Empathy: Inside esp32-smooth-eye-blinking

How a minimalist C++ sketch uses partial framebuffers and procedural easing to turn a 240MHz microcontroller into a living character.

6 min read · dmtrKovalenko/esp32-smooth-eye-blinking

A pocket watch mechanism where the gears and springs are arranged to form the precise shape of a human eye, illustrating the concept of mechanical precision creating a biological illusion.
Procedural animation uses raw math to simulate biological imperfections.
Key Takeaways

The Illusion of Life

A screen displaying an eye usually looks exactly like what it is: a screen. To make a piece of silicon feel like a creature, the animation must embrace procedural imperfection. The esp32-smooth-eye-blinking repository tackles this challenge by rejecting heavy, full-screen framebuffers. Instead, it relies on surgical partial rendering and raw C++ math to cross the uncanny valley.

The behavioral logic is remarkably simple but effective. The project hardcodes a ten percent chance of a 300-millisecond quick double-blink. Combined with randomized open times between one and four seconds, this subtle mathematical choice mimics natural human ocular behavior. It transforms a repeating loop into a simulated personality.

The Bounding Box Trick

Drawing directly to an SPI display on an ESP32 causes visible tearing. The traditional solution is to allocate a full direct memory access (DMA) framebuffer, but this wastes precious RAM. This project finds an elegant middle path. It calculates a dynamic bounding box around the eye and allocates a localized software buffer strictly for those pixels.

buffer = (uint16_t *)malloc(bufferWidth * bufferHeight * sizeof(uint16_t));

By utilizing functions like bufferFillEllipse and flushBuffer, the developer only updates the necessary regions. This significantly reduces SPI overhead while maintaining the performance benefits of a single-burst write.

The localized framebuffer strategy saves RAM while preventing screen tearing.

Procedural Geometry Over Bitmaps

Instead of looping through pre-rendered PNG files like early smartwatches, the project uses a quadratic easing function and live square root calculations to draw ellipses on the fly. When closing, the easing uses a squared progression. When opening, it reverses the math. The current height of the eye is recalculated every frame.

A close-up of a drafting compass drawing a curved eyelid line that transitions from a solid ink stroke into discrete square pixels.
Mathematical easing functions are translated into raw display output in real time.

Calculating square roots is usually expensive for microcontrollers. However, by boosting the ESP32 CPU frequency to 240MHz and limiting the vertical resolution of the eyes to 50 pixels, this brute-force math becomes entirely viable without requiring complex lookup tables.

Escaping the Uncanny Valley

The landscape of microcontroller personalities is divided. Many popular projects rely on OLED displays and pre-rendered bitmaps inspired by commercial robotics. While bitmaps are easier to design, they are harder to transition smoothly. Procedural math requires more CPU power but yields infinite in-between frames.

FeatureProcedural TFT (esp32-smooth-eye)Bitmap OLED (esp32-eyes)
Rendering MethodLive math (sqrt, easing)Pre-rendered arrays
Memory FootprintLow (Partial buffer)High (Full frames)
Animation FluidityInfinite in-betweensFixed framerate

Ultimately, the value of this repository lies in its focused execution. It solves one specific graphical problem perfectly, proving that the right mathematical formula can breathe life into cold hardware.