ExplorInk
GitHub

hardware

The hardware: an off-the-shelf reader, not a dev board

ExplorInk does not have hardware of its own. It runs on e-ink readers you can buy: an ESP32-C3, a four-grey e-ink panel, physical buttons, an SD card slot. No touch, no Android, no ADB, and a quarter of a megabyte of usable heap for everything. This page is what that hardware gives us and what it costs.

What one binary covers today

Xteink X4 and X3, from the same build. Both are ESP32-C3 and share a pinout. They differ in panel controller — X4 is an SSD1677 at 800×480, X3 a UC8253 at 792×528 — and in battery backend. The running firmware picks its own profile by probing the X3-only I2C chips (fuel gauge, RTC, IMU) twice and scoring the hits, so there is one binary, one flash path and one test pass for two devices.

The X4 is the device every measurement on this site was taken on. The X4 findings page has the numbers: refresh timings, heap, what the panel does with grey.

The specification we design against

Panel
4.3″ e-ink, 480×800 as the renderer sees it, 220 PPI, no touch
Refresh
500 ms fast (differential), 1,684 ms clean whole-panel — measured, waveform only
Grey
4 levels: black, dark grey, light grey, white. The map does not use them
SoC
ESP32-C3, RISC-V, WiFi and Bluetooth 5 LE — one radio at a time
Heap
247,156 bytes total; 58,540 free with the map screen and BLE up, measured
Storage
16 MB internal flash; map tiles live on a separate SD card
Input
Physical buttons only — a design premise, not a limitation: gloves
Recovery
USB serial, esptool, full flash backup and restore

Every one of those numbers pushes back on the software. A quarter of a megabyte of heap is why the BLE stack is torn down when you leave the map screen — bringing it up costs 57 KB of it. The four-grey panel is why the map is dithered instead of shaded. The buttons are why there is no touch UI to design. And the 1,684 ms refresh is why the map is a still picture with a moving marker: how it works follows that decision through the whole chain.

WiFi or the map, never both

The device runs one radio at a time. WiFi and the map screen are mutually exclusive in practice, so everything that has to work while riding goes over Bluetooth LE: position packets, the command console, and map files pushed onto the SD card. The BLE bridge is the whole wireless story on the trail.

Buttons, not a touchscreen

Four physical buttons drive everything on the map: zoom in and out, marker height, a menu behind the middle button, and a long press for zoom while panning in observation mode. This is deliberate. A rider wearing gloves in the rain cannot use a capacitive panel, and a display you have to look at closely to operate is the wrong display for a handlebar.

What a second device actually costs

Adding X3 alongside X4 was nearly free, because the two are the same machine with a different panel. The next device is not that cheap:

  • X4 Pro — an ESP32-S3 with its own panel bus, a capacitive digitizer and 8 MB of PSRAM. That is a second binary, a second test matrix and a UI premise (buttons) to revisit. Untested: no X4 Pro on this desk yet. The frontlight part is already handled in the SDK we build on.
  • Anything without our refresh control — the value here is a panel driven deliberately: partial refresh, chosen waveform, a redraw only when the map has to change. A device that does not let us choose those is a worse product than the C3, whatever else it can do.

The real cost of a second target is not writing the code once. It is that every release from then on needs two builds, two flashes and two passes on real hardware, forever. So the stance is: keep the C3 binary as the product, judge a new device when it is on the desk, and add nothing before a stranger can install this.

What is not tied to any device

The map renderer is not ESP32 code. The same MapRenderer sources build as a host binary with CMake and g++ through a canvas seam — the device passes its real GfxRenderer, the laptop passes a PPM writer. That binary runs every time somebody edits the map style, so the portability is exercised daily rather than claimed. The .tib tile format, the index, the freshness rule and the route file are format-level too, with no device in them.