Readable in full sun
Reflective panel, no backlight. The brighter the day, the better it looks. Visor down, glance, done.
Heavy development · nothing here is finished
ExplorInk turns a pocket e-ink reader into an offline map display for motorcycles and trails. No backlight to wash out, no battery gone by lunch. One still picture: where you are, where the route goes, what is around you.
Built on CrossPoint Reader. Map data © OpenStreetMap contributors.
01 · why e-ink
The screen washes out in direct sun. It cooks in a handlebar mount. The battery does not last a day of riding. E-ink has the opposite properties, and one hard cost you have to design around.
Reflective panel, no backlight. The brighter the day, the better it looks. Visor down, glance, done.
Holding an image costs nothing. Power goes only into changing the picture, so the X4 runs for tens of hours.
A full refresh takes about 1.7 s; four grey levels cost an extra waveform pass, and lose their grey to the next one. That rules out a moving map.
Position, route, surroundings: redrawn rarely, readable at a glance at speed. No rerouting, no voice, no traffic. The route is planned before you leave.
02 · the screen
The ones tagged device came off the panel over USB: send a coordinate and the device draws what is around it from tiles on its SD card. The one tagged preview is the same renderer running on a laptop against the same tiles, which is how styling gets tuned without reflashing. We keep the two labelled apart on purpose.
Honest caveat: the device renderer follows most of the style spec now: road widths and casings, buildings, forest, built-up, filled water with waves, and railways as a blocked line all draw on the panel, and the route draws with them. Place labels and junction dots exist in the spec, not yet on the glass. The laptop preview is the other way round for the route: it renders everything here except the route line, so that one is judged on the device only.
03 · how it is built
Fetches an area from OpenStreetMap, projects and clips it, routes along real
roads, and writes binary .tib tiles at three zoom levels. A browser
tuning tool renders a pixel-exact 480×800 preview, so the styling gets judged
as e-ink instead of as a pretty vector map.
A fork of CrossPoint Reader. Map screen, BLE position receiver, tiles off the SD card, zoom and marker height on the physical buttons, ride / hike / cycle filter, and a command console over USB serial and BLE. The e-reader stack comes out; maps go in.
Sends the phone's GPS fix to the device over BLE every few seconds and records every fix and packet for replay. One window, no settings screen, foreground service: it keeps sending with the phone locked in a bag. A GPS liveness gate throws away network fixes that would jump you across town.
04 · status
Formats, the render spec and the BLE protocol all still change without notice. Do not depend on any of it yet.
.tib tiles, three zoom levelsworks05 · development log
The map is built once and copied onto the card. Fix a mistake in how a street is drawn, rebuild, publish, and every reader that already had that square kept the wrong one, because nothing on the device could tell that what it holds is no longer what the map says. A tram line drawn wrong in one Bratislava district proved it: fixed at the source, still wrong on the device.
The device can now ask. Each square carries a short number worked out from the shapes drawn in it, and that number moves only when the drawing really changes, not when the map is merely rebuilt. Two obvious candidates were tried and measured first, and both failed: the age of the source data did not move at all across a genuine fix, and the build time moves on every build, including one that changes nothing. The device sends the numbers it holds, the phone looks them up against the published map, and only the squares that actually differ come down.
Off unless switched on, because it spends the phone's data. Two moments to choose from: only on the sync screen, or continuously as you ride. Verified on the X4 with the phone app, against the live map server. The device held two neighbouring squares, one out of date and one current; the current one was never touched, the stale one came down and afterwards matched the published map exactly.
The sync-screen half was broken and the tests all passed. It asked whether the phone was there at the instant the screen opened, and the phone arrives about two seconds later, so the question was always answered no and the check never ran. Nothing wrong with the logic, only with when it ran, which is exactly the kind of thing only real hardware finds.
The X4 has no barometer, so any elevation profile for hike mode has to come from the phone's own GPS. The link between phone and device now carries altitude alongside position, heading and speed, wired end to end, nothing drawn with it yet. Groundwork for a hike-mode feature that has not been built.
The map has always turned to face the way you are riding. Good most of the time, less good if you want it to just stay put. Reading a map while stopped is easier when it is not spinning under your finger every time you turn your head.
Two new settings, Map rotation and Heading mode, sit in Settings under Map and as quick-toggle rows in the map's own CONFIRM menu, so either can be flipped mid-ride without leaving the screen. Rotation switches between the usual heading-up view and a fixed north-up one; heading mode freezes the frame at whatever direction it already had, ignoring new GPS headings until switched back. A third setting, Zoom mode, is on the same row for now with nothing behind it yet. The place is reserved for an automatic zoom that reacts to speed and upcoming turns, not built.
Verified on the X4: both toggles change the picture on screen from the map menu, confirmed north-up holds still through simulated heading changes and a frozen heading stays frozen until switched back.
The map used to have one job: follow you. Useful on the road, less useful when you stop to figure out what is around the next bend or check a turn you cannot see yet on screen. Zoom and marker height only move a fixed window centred on where you are. There was no way to look sideways.
A new row in the map menu, Observation mode, hands the four direction buttons a different job: pan the view half a screen at a time, any direction, button hints turn into arrows so it is obvious what they do now. Your GPS position keeps arriving in the background the whole time, it just will not yank the screen back while you are looking around. Pick Follow mode and it snaps straight back to where you actually are.
Verified on the X4: panned around a loaded ride, confirmed the fix kept arriving underneath, confirmed Follow mode returned to the real position and not wherever panning had left off.
Hitting a patch of map the device never had used to mean stopping, backing out to the menu and running a sync of the whole list: two hundred squares of bookkeeping for the nine in front of you. Nobody does that at a junction.
Switch on auto-sync and the map asks for a square the moment it draws the hatching that means “no data here”. It asks only for what is on the screen, not for everything it has ever been short of, because out on a road that is somebody’s mobile data. A small globe in the corner says data is moving, and the map redraws itself once the squares land.
Tested by deleting the square under the rider and reopening the map: the ask went out, the phone brought 318 kB down from the tile server in 35 seconds, and the street grid appeared without anyone touching a button. A square the server does not have is remembered as unavailable and never asked for twice. Otherwise standing at the edge of the map would beg for the same missing square forever.
Off by default. It spends your phone’s data, so it is a decision you make once, on purpose.
The map used to swing round every time you turned far enough, because it kept your direction pointing up. Through hairpins that is constant: over one 3.4 km pass it redrew the whole screen eleven times into nine different orientations, twice ending up back where it started.
With a route loaded it now stays the way the route runs, and only the marker moves. Its arrow turns instead of the map. The same pass measured zero redraws in one orientation, and a recorded 7.4 km morning commute went from twelve down to two, both of those because the rider genuinely rode off the edge of the picture. On a screen that blanks to redraw, the picture holding still is the feature.
It works now, all the way through. The device knows which map squares it never had, asks the phone for them, and the phone brings them down from a public tile server and hands them over Bluetooth. Five squares, 322 kB, 43 seconds, with a progress bar per square on the panel and a plain “not available” for anything the server has not been given yet.
The phone keeps nothing. A map square belongs on the device or on the server, so the phone holds one only for the seconds it takes to pass it along. Nothing quietly fills up.
It also got three times faster than the first attempt, and not by sending more at once. Bluetooth waits for an answer after every small piece, so the time between answers was the whole limit. The phone now asks for a faster rhythm while a transfer is running, and gives it back the moment it finishes, because holding it costs battery for nothing.
The full dated log lives in the repo, alongside one topic document per hardware finding: how the panel actually behaves, why the obvious approach fails. Read it on GitHub →
06 · the hardware
A pocket e-ink reader, bought off the shelf. Not a dev board, not Android, no ADB: an ESP32-C3 with a display driver and physical buttons. Everything ExplorInk does has to fit in that.
07 · get in touch
I ride, and I wanted a display that survives a sunny day on a handlebar. If you are doing something similar on Xteink hardware, or you want to try it, or you just want to tell me the map style is wrong, write to me.