- Rust 84.3%
- HTML 9.4%
- PowerShell 6.3%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
| .cargo | ||
| .idea | ||
| assets | ||
| docs | ||
| scripts | ||
| src | ||
| .gitignore | ||
| build.rs | ||
| Cargo.lock | ||
| Cargo.toml | ||
| espflash.toml | ||
| LICENSE-APACHE | ||
| LICENSE-MIT | ||
| partitions.csv | ||
| README.md | ||
| rust-toolchain.toml | ||
| sdkconfig.defaults | ||
DPT Table
Real-time public transit departure board firmware for ESP32 microcontrollers. Connects over WiFi to a relay server and displays live departure times and line information on a color LCD.
How it works
Transit data feed ──► relay server ──► board (ESP32, WiFi TCP)
The relay server connects to the transit operator's real-time feed and serves per-stop departure snapshots over TCP. The board polls the server every few seconds, parses the JSON response, and renders the display.
Each board has a unique device ID stored in flash. When the board connects to the server it identifies itself by that ID, and the server returns the stop and departure data configured for that device. You register your board and pick its stop via the web UI at dpt.raccoon.sk.
The departures screen
The board shows the stop name and a WiFi indicator in the header, then up to four upcoming departures — line badge, destination (scrolling if long), and the ETA.
A board can be configured to show one platform, several, or all of its stop. When more than one platform has departures, the board cycles through them: the header lists every platform's letter with the one currently on screen highlighted, and the body shows that platform's departures before moving on to the next. A board set to a single platform simply shows it without cycling.
See docs/departures-display.md for the full layout and cycling behaviour.
Platforms and branches
Each supported transit operator and hardware combination lives on its own branch. There is no runtime platform switching — pick the branch that matches your hardware and city, clone it, flash it.
See the Platforms wiki page for the full list of supported branches.
If you want to add support for your city or a different board, see Adding a platform below.
Getting started
Option A: flash a prebuilt image (no tools needed)
Open dpt.raccoon.sk/flash in Chrome or Edge, plug the board into your computer with a USB data cable, pick the firmware variant for your hardware, and click Connect & install. That's it — continue with connecting the board to WiFi below.
Reflashing an already-configured board keeps its saved WiFi credentials.
Prefer the command line? Each variant directory also serves a single merged
image; flash it with espflash:
curl -LO https://dpt.raccoon.sk/firmware/sk-dpb-esp32-c6-320-172/firmware-merged.bin
espflash write-bin 0x0 firmware-merged.bin
Option B: build from source
You need Rust with the ESP toolchain
(espup), ldproxy, and
espflash.
-
Clone the branch for your hardware (not
main) — any location works, nothing needs to be configured:git clone --branch sk-dpb-esp32-c6-320-172 https://github.com/your-org/dpt-table cd dpt-table -
Flash the board:
cargo c6This builds the firmware, flashes it, and opens the serial monitor. No WiFi credentials need to be compiled in — the board is configured over WiFi on first boot (see the next step).
On Windows the build output goes to
C:\dt— ESP-IDF's build breaks on long paths. SetCARGO_TARGET_DIRto override.
3. Connect the board to your WiFi. With no credentials stored, the board hosts its own setup access point. On your phone or laptop:
- Join the WiFi network
DPT-Setup-XXXXshown on the board's screen (passworddptsetup). - The config page opens automatically; if not, browse to
http://192.168.71.1. - Pick your home WiFi, enter its password and the server address
(
37.205.11.180:7878), and tap Save & connect. The board reboots and comes online.
Full details and the HTTP API are in docs/captive-portal.md.
- Register your board at dpt.raccoon.sk. The device ID is shown on the board's screen until it is configured. Enter it on the web UI, choose your stop, and pick which platforms to show — a single platform, several, or all of them. The board will start showing departures within a few seconds.
Pre-baking credentials (optional). For development you can skip the setup portal by creating a
.envfile in the project root:WIFI_SSID=YourNetwork WIFI_PASS=YourPassword SERVER_ADDR=37.205.11.180:7878 DEVICE_ID=0000000000000000The firmware persists these to flash on first boot and connects directly. Leave
DEVICE_IDas all zeros — the board generates a unique ID on first boot.
Server
The relay server bridges the transit operator's real-time feed to the boards. A public instance is available at:
- TCP:
37.205.11.180:7878 - Web UI: dpt.raccoon.sk
The public server is free to use. The source is not open at this time.
Releasing prebuilt images
scripts/release.ps1 builds a release image and publishes it for the web
flasher. On the variant branch:
scripts/release.ps1 -Deploy user@host:/var/lib/dpt-server/firmware
It produces dist/<branch>/ with the bootloader, partition table, app image,
a merged single image (firmware-merged.bin, flash at 0x0), and an ESP Web
Tools manifest.json, then uploads them over scp to the server's firmware
directory where they appear on dpt.raccoon.sk/flash.
Set DPT_FIRMWARE_DEPLOY to skip -Deploy; set GITEA_TOKEN to also archive
the merged image in the Gitea package registry.
Adding a platform
To add support for a new transit operator or hardware variant:
- Branch off an existing branch that is closest to your target (same hardware or same operator).
- Name your branch
<country>-<operator>-<hardware>-<display>— for examplecz-dpp-esp32-c6-320-172for Prague. - Adapt the data source (server-side), line colors, and display layout for your operator.
- Open a PR or post an issue to get your branch listed in the table above.
The intent is to keep each branch self-contained and independently flashable with no conditional compilation for platform differences.
License
MIT — see LICENSE.