// HACKER NEWS — CYBERSECURITY
How my e-reader lost its stripes
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?
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.
To display a greyscale image, CrossPoint first draws a black-and-white base in which even the
grey pixels start out black. It then runs a short voltage-pulse waveform to move selected pixels
partway towards white. This second stage, a “nudge,” produces dark and light shades of grey by
driving those pixels for different amounts of time.