11 Nov 2026
I live at the nexus of a bunch of public transit routes, so I built a little on-demand display:
It’s pretty basic: an Adafruit MagTag powered by a little LiPo battery, plus a pleasing—albeit un-necessary!—button picked up at Swapfest.1
When the Big Button™—or any of the on-board buttons—is pushed, the board wakes up, connects to WiFi, requests the next per-route departures from the MBTA’s API, and displays them. Every 30 seconds thereafter it refreshes those times; and after several minutes displays a “sleeping” screen and hibernates. If a button is re-pressed any time during the wake period, additional refreshes are added pre-hibernation.
The initial wake-up isn’t instantaneous, but that hasn’t been a problem: waiting 18 seconds for it to wake up is still better than pulling out a phone, spending that same 18 seconds searching for the same info and inevitably getting distracted into doing More Phone Things. It’s certainly enough time to put on shoes while waiting to find out if the next expected bus is on time (run!!) or a few minutes delayed (saunter!). Although sometimes the MBTA’s API returns upcoming departures without scheduled times, so the best we can see is “???” to show that something will depart some time.2
I chose an Adafruit MagTag for this project because I wanted to make something functional quickly and relatively cheaply, without faffing about with too many components: the MagTag has WiFi, display, and buttons all built in.3 The display is E-Ink so doesn’t draw power except when the screen is actively updating, which is great—with our current usage patterns of the transit display, we only need to recharge its LiPo battery once every few weeks.4 The recharge is trivially easy with a portable USB battery pack.
My code is here. To set up your own:
code.py script for your API’s response format.6
Thanks to Alex for photography and the MBTA for the API.
I attended the Recurse Center and all I got was this lousy blog footer