I’ve been a lifelong reader, which has proved a fragile habit in our era of endless trivial distraction. While books and e-ink readers solve the problem of competition for attention, they can’t compete with a phone for convenience. That tiny device in my pocket has made reading both easier and more vulnerable to displacement whenever a notification pops up.
A few days ago, I learned for the first time about a recent generation of tiny e-ink readers. Since they’re cheap, it was easy to give into curiosity: I bought an Xteink X3. Not only is it astonishingly tiny, I could immediately install the delightful open-source CrossPoint firmware. I was very quickly able to install a few books. I also appreciated being able to install custom fonts, though I was a little surprised by their indifferent rendering (foreshadowing…).
CrossPoint is very configurable out of the box, so I converted a photo to a dithered black and white bitmap as my “device sleep” screen, and was pleased with how pretty this looked. When I read that the device supported 4 whole shades of grey, I was intrigued: would a greyscale image look better?
Down the rabbit hole: first image bugs#
This revealed what looked like a bug: the sleep screen was displaying greyscale images with very murky dark areas. Either my middle-aged eyes were finally failing me, or was dark grey rendering as black? I created a quick test image and verified that dark grey really was black, while light grey was extremely pale (almost white). Mildly annoying, but hardly unexpected on a cheap device, and easily worked around: let’s create a three-tone image!
With less of the regenerated image containing large regions of black, I now saw a new bug: in the CrossPoint viewer app, the prior screen contents were still present in ghostly form (only on paler parts of the display, hence me failing to notice the first time around). However, on the same image, the sleep screen didn’t suffer from this problem. This suggested that there were two image renderers making different decisions, and the viewer app’s code was buggy.
In both cases, though, the photograph had distinctive vertical stripes across it that were not present in the bitmap file.
A phone photo of my tri-tone image. The fine vertical stripes are easiest to see in the background.
Since I knew next to nothing about e-ink, ESP32 development, or CrossPoint, I started investigating in the usual late-2026 way, using GPT-6 Astra in Codex. I would capture the X3’s screen on my phone and drop images into my Codex session.
An e-ink screen uses voltage pulses to move black and white pigment particles, which stay in place after the power is removed. An incomplete update or insufficient voltage can leave ghosted traces of the prior image behind.
... continue reading