A tiny battery-friendly departure monitor for VRR (Verkehrsverbund Rhein-Ruhr) stops in Germany's Ruhr area. Runs on a Wemos D1 Mini (ESP8266) and a Waveshare 2.9" 3-color ePaper, and renders the next departures from any VRR stop.
Configuration is done through a captive portal — no recompiling to change stops, no secrets baked into firmware.
- Compact layout for the Waveshare 2.9" B (296×128, black/white/red)
- Live VRR openservice API with real-time delays
- Delayed departures highlighted in red
- Captive portal (WiFiManager) for WiFi + setup (stop city, stop name, device title, refresh interval)
- Wemos D1 Mini (ESP8266) — wemos.cc/en/latest/d1/d1_mini.html
- Waveshare 2.9" e-Paper Module (B) — 3-color (black/white/red), 296×128, SSD1680, GDEM029C90 panel — waveshare.com/2.9inch-e-paper-module-b.htm (ships with an 8-wire dupont cable — all the wiring you need)
- Optional 3D-printed case — Live E-Paper Transit Departure Board on MakerWorld fits the Wemos + 2.9" Waveshare B perfectly
| Wemos D1 Mini | GPIO | ePaper | Symbol |
|---|---|---|---|
| 3V3 | — | VCC | — |
| GND | — | GND | — |
| D7 | GPIO13 | DIN (MOSI) | HW SPI |
| D5 | GPIO14 | CLK (SCK) | HW SPI |
| D1 | GPIO5 | CS | EPD_CS |
| D3 | GPIO0 | DC | EPD_DC |
| D0 | GPIO16 | RST | EPD_RST |
| D2 | GPIO4 | BUSY | EPD_BUSY |
See wiring.html for a visual diagram. Measure VCC directly at the ePaper connector with everything plugged in; it should be ≥ 3.0 V. If it's lower, your dupont wires are lossy — solder direct.
Grab firmware.bin from the latest GitHub release. You have two options to write it to the ESP:
- Plug the Wemos into your computer via USB.
- Open esp.huhn.me in Chrome or Edge (WebSerial is required).
- Click Connect and pick the Wemos serial port.
- Drop
firmware.bininto the Flash slot at offset0x0000. - Click Program. Wait for "Done".
pip install esptool
esptool.py --chip esp8266 --port /dev/ttyUSB0 --baud 115200 \
write_flash 0x0 firmware.bin(Replace /dev/ttyUSB0 with COM3 or similar on Windows.)
After flashing, the Wemos reboots into the setup portal on first run.
- The ePaper shows a setup screen: connect to the
VRR-Display-SetupWiFi from your phone. - A captive portal opens (or browse to
192.168.4.1). - In the menu, open Setup, fill in stop city / stop name / device title / refresh and hit Save. Then open Configure WiFi, pick your network, enter the password and hit Save. The device connects and starts showing departures.
There are two ways to reach the configuration:
1. Over the network (easy path). Browse to http://<device-ip>/ (the IP is printed on the serial console at boot and shows up in your router's client list as ESP-…). It's the same portal page, just reached over your LAN.
The config page has no authentication — anyone on your LAN can change the stop. This is a home gadget; keep it on a trusted network.
2. Double-reset → captive portal (when the network path is unreachable — e.g. new WiFi). Press the RST button on the Wemos, and as soon as the display starts to update, press RST again within ~2 seconds. The device boots into the VRR-Display-Setup AP - just like First-time setup. Join it from your phone, and in the portal menu open Setup to edit stop / title / refresh without re-entering WiFi, or Configure WiFi to switch networks. A single reset just reboots the device normally — only two quick resets trigger the portal.
VRR's openservice API matches name_dm against what's in their own database. To find the exact name, open vrr.de, type your stop into the route planner, and use the name and city as they appear in the autocomplete suggestions. Usually the German stop name works directly (Hauptbahnhof, Rüttenscheider Stern, etc.).
| Library | Version | License |
|---|---|---|
| GxEPD2 | 1.6.8 | GPL-3.0 |
| Adafruit GFX Library | (transitive via GxEPD2) | BSD |
| ArduinoJson | 7.4.3 | MIT |
| WiFiManager (tzapu) | 2.0.17 | MIT |
| ESP8266 Arduino core | platform default | LGPL-2.1 |
MIT — see LICENSE. Note that when linked against GxEPD2 (GPL-3.0), the combined binary is effectively GPL-3.0.
