
A handheld e-book reader built on an ESP32 and a 3.5" ILI9488 TFT display — a self-contained device that reads plain-text books straight off an SD card, no phone or computer needed once it's loaded up. Four physical buttons drive the whole interface: a folder browser, a paginated reading view with proper pixel-based word wrap, an auto-detected table of contents, and a settings screen for tuning font, color, and spacing to taste. A DS3231 real-time clock tracks reading streaks day to day, and a built-in Wi-Fi access point lets you drop new books onto the SD card wirelessly instead of pulling the card every time. Bookmarks, per-book page caches, and file management (move/delete, straight from the device) all persist across power cycles, so the reader picks up exactly where you left it.
in development
Firmware: Arduino framework on an ESP32, written in C++. Display driving goes through TFT_eSPI (Bodmer), which handles the ILI9488 over its own dedicated VSPI bus — chosen for its speed with large color TFTs and its built-in support for proportional GFXFF fonts alongside the classic bitmap font. Storage runs on a second, independent HSPI bus so the SD card and display never contend for the same SPI lines, which matters since both get hit constantly during page turns and file scans.
Text layout is done from scratch: a pixel-based word-wrap engine measures actual glyph widths via tft.textWidth() rather than counting characters, so wrapping stays correct whether the active font is the monospaced Classic style or one of the proportional Sans/Sans Bold TrueType-style fonts. Page boundaries are computed once per book and cached to a sidecar .pgifile on the SD card, so reopening a previously-indexed book skips the (slower) full re-scan. Bookmarks, reading stats, and settings all persist through the ESP32's NVS flash partition via the Preferences library — no SD write needed for anything except the books themselves and their page-index caches. Time and streak tracking runs off a DS3231 RTC module over I2C. Wireless file transfer is a minimal WebServer instance running in ESP32 soft-AP mode, serving a single-page upload form with no external dependencies.
TFT (ILI9488, default VSPI bus): VCC → 3.3V, GND → GND, CS → GPIO 5, RESET → GPIO 33, DC/RS → GPIO 27, SDI/MOSI → GPIO 23, SCK → GPIO 18, SDO/MISO → GPIO 19, LED → GPIO 32 (PWM-driven for brightness control).
SD card module (separate HSPI bus, independent from the TFT): 3V3 → 3.3V, GND → GND, CS → GPIO 4, MOSI → GPIO 16, SCK → GPIO 17, MISO → GPIO 35. MISO sits on an input-only pin specifically to free up GPIO 21/22 for the RTC's I2C bus — safe to do since MISO only ever receives data from the ESP32's side.
DS3231 RTC module (I2C): VCC → 3.3V, GND → GND, SDA → GPIO 21, SCL → GPIO 22. The SQW/32K pins are unused and left disconnected.
Buttons (INPUT_PULLUP, one leg to GND, other leg to GPIO): UP → GPIO 13, DOWN → GPIO 14, SELECT → GPIO 25, BACK → GPIO 26.
Arduino IDE with ESP32 board support installed. Two libraries from the Library Manager: TFT_eSPI (Bodmer) and RTClib (Adafruit) for the DS3231. WiFi.h, WebServer.h, Wire.h, Preferences.h, and SD.h all ship with the ESP32 core, so nothing further to install there. TFT_eSPI needs its User_Setup.h configured for the ILI9488 driver with SMOOTH_FONT enabled, which is what makes the GFXFF proportional fonts (FreeSans9pt7b, FreeSansBold9pt7b) available without any extra #include.
Wire the display, SD module, RTC, and four buttons per the pinout above, format an SD card as FAT32, and drop some .txt books onto it (nested folders are supported). Flash the sketch from the Arduino IDE with the correct ESP32 board selected. On first boot with a fresh RTC, the device auto-syncs the clock to the sketch's build time if it detects the RTC lost power — worth doing once with an internet-synced computer nearby so the streak tracking starts from an accurate date.
Power on and the boot screen shows a live, Arch-style [ OK ] / [ FAIL ] log under a "PocketPages" header as each subsystem — display, RTC, SD card, NVS storage — comes online, so any wiring issue is visible immediately instead of a silent hang. Once boot finishes, it drops into the root file browser showing every .txt file and folder on the card, sorted alphabetically with folders grouped first.
All six settings persist in NVS flash and reload automatically on next boot. Changing any layout-affecting setting (font style, size, or line spacing) invalidates a book's cached page index, so it gets silently re-scanned and re-cached the next time that book is opened.