Getting Started

Everything from unboxing to live departures โ€” step by step.

Before You Start

Make sure you have everything on the Build Guide parts list. There are two decisions: which controller board you're using (below), which decides the firmware you flash; and which panels you attach, which is a setting you pick afterwards on the Hardware tab rather than a different build.

MatrixPortal S3 Generic ESP32-S3
Wiring Plug & play Manual GPIO wiring
Level shifters Built-in Optional but recommended
Difficulty Easy Medium
Cost ~$65โ€“90 ~$51โ€“85
Level shifters (generic ESP32-S3 only): The ESP32-S3 outputs 3.3V logic, but HUB75 panels expect 5V. Most panels work anyway, but it's out of spec โ€” some batches won't. The MatrixPortal S3 has 74AHCT245 level shifters built in. For generic ESP32-S3, adding two 74AHCT245 chips (~$2โ€“6) guarantees reliable operation with any panel.

Step 1: Assemble the Hardware

MatrixPortal S3

  1. Plug the MatrixPortal S3 into the first panel's HUB75 input connector
  2. Connect a HUB75 ribbon cable from Panel 1 OUT โ†’ Panel 2 IN to daisy-chain the second panel
  3. Connect 5V power via USB-C (2A minimum, 3A recommended) to the MatrixPortal โ€” it passes power to both panels via the screw terminals

Generic ESP32-S3

  1. Wire the ESP32-S3 GPIO pins to the first panel's HUB75 input โ€” full pin mapping in the Wiring Guide
  2. Connect a HUB75 ribbon cable from Panel 1 OUT โ†’ Panel 2 IN
  3. Connect a 5V power supply (2A+) directly to the panels via screw terminals
  4. Power the ESP32-S3 via USB or from the same 5V supply โ€” ensure common GND between ESP32 and panels
โš ๏ธ Panel chain order: Looking at the back of the panels, the controller board goes on the left. Chain runs left โ†’ right (OUT โ†’ IN). Getting this backwards causes a split or mirrored image.

Step 2: Flash the Firmware

Option A: Browser flasher (recommended)

The easiest way to flash a fresh board โ€” no command line, no tools to install. Plug the board into your computer over USB and use the browser flasher: pick your variant and click Install. It writes the bootloader, partition table, and firmware in one step.

Works in Chrome, Edge, or Opera on desktop (it uses the Web Serial API).

Option B: Build from source

If you want to modify the firmware or use a different board configuration:

git clone https://github.com/xbach/spojboard-firmware.git
cd spojboard-firmware
pio run -t upload

Requires PlatformIO CLI. The default environment matches the MatrixPortal S3 โ€” check platformio.ini for other board targets. PlatformIO flashes the bootloader, partitions, and app together over USB.

About the .bin files on GitHub Releases: those are application images for over-the-air updates (the web interface's "Check for Updates" and GitHub OTA), not for first-time USB flashing. A blank board needs the bootloader and partition table too โ€” which the browser flasher and pio run -t upload both handle for you.

Step 3: First Boot & WiFi Setup

After flashing, the display shows WiFi credentials:

WiFi Setup Mode
SSID: SpojBoard-XXXX
Pass: xxxxxxxx
Go to: 192.168.4.1
  1. Connect your phone or laptop to the SpojBoard-XXXX network
  2. A captive portal opens automatically (or go to 192.168.4.1)
  3. Enter your home WiFi credentials and save
  4. The device reboots and connects to your WiFi
If the device can't connect (wrong password, network issue), it automatically falls back to AP mode with a new random password shown on the display. Just reconnect and try again.

Step 4: Configure via Web Interface

Find the device IP on your router's DHCP list (or check the serial monitor), then open http://<device-ip>/ in a browser.

Connection tab

  • Select your city: Prague, Berlin, or MQTT (Custom)

Transit Data tab

  • Prague: Enter your Golemio API key and stop ID(s)
  • Berlin: No API key needed โ€” just enter stop ID(s)
  • MQTT: Configure broker address, request/response topics โ€” see MQTT Guide

Need your stop ID? Use the Station Search tool to find it by name.

Display tab

  • Brightness (default 90, range 0โ€“255)
  • Number of departure rows
  • Display mode: Vanilla / Platform / Dual ETA / Dual ETA + Platform
  • Custom line colors

Hardware tab

This is where you describe the panels you actually attached. If you built anything other than the default two 64ร—32 panels, come here first โ€” the display will look wrong until the arrangement matches your hardware.

  • Panel arrangement โ€” 2ร— 64ร—32 chained (128ร—32), 4ร— 64ร—32 in a 2ร—2 grid (128ร—64), or 2ร— 64ร—64 chained / one 128ร—64 module (128ร—64)
  • RGB channel order โ€” the fix when colours come out wrong. Use the test pattern button: it draws three bars labelled R, G and B, so a swap takes seconds to spot
  • Panel driver chip โ€” try another if the panel stays blank or ghosts
  • Custom pin map โ€” only if you wired to different GPIOs
  • Restore built-in wiring โ€” reboots back to the factory pin map

Changing the arrangement or the wiring reboots the device. Both this tab and the System tab are also available in setup (AP) mode, so a panel left dark by a bad setting is always recoverable without a USB cable.

Optional tab

  • Weather display (Open-Meteo, no API key required)
  • Rest mode (scheduled off periods)

System tab

  • Configuration Backup โ€” download every setting as a JSON file, and restore one. Worth doing once the board works, and again before a firmware update
  • Firmware updates, device info, reboot and factory reset
The backup file contains your WiFi password and API keys in plain text โ€” that is what makes it a complete backup. Keep it private, and never attach it to a bug report.

Hit Save on each tab โ€” the interface saves one tab at a time, so a save on one tab does not carry the others. The device applies settings and starts pulling live departures.

Step 5: Test & Tune

  • Demo mode โ€” available in the web interface before API setup; lets you preview the display with sample departure data
  • Brightness โ€” lower is easier on the eyes indoors; default 90 is a good starting point
  • Dual ETA โ€” enable to see the next two departures per line, useful for high-frequency routes
  • Trip filtering โ€” default 3 min minimum hides departures you can't catch; adjust to taste
  • Scrolling โ€” enable for very long destination names (off by default)

Next Steps