Skip to content

T-RGB Bike Computer

A bike computer built on the LilyGO T-RGB: a round 480×480 touch display, ESP32-S3 with BLE and WiFi, SD card, and a LiPo charger on board. Its main job is navigation on the handlebar: turn-by-turn instructions from OsmAnd, or along your own GPX route, sent by the Android app TrailBridge over BLE. On a GPX route it also shows the climb ahead. Besides that it reads standard BLE bike sensors and logs every ride to SD card.

Navigation screen

Navigation: the next turn

Main screen

Main screen with the next maneuver at the top

Climb screen

Climb on a GPX route

Screenshots from the device, taken during a simulated ride from Villach to Bovec. The texts on the display are German.

OsmAnd Your own GPX route
Who computes the route OsmAnd on the phone you, beforehand (e.g. with BRouter, Komoot or a recorded track)
Turn instructions from OsmAnd, with street names and lanes from the GPX file, or derived from the geometry of the track
Elevation profile and climbs no yes, if the file has elevation data
Needs OsmAnd and TrailBridge TrailBridge only

In both cases the phone stays in the pocket: TrailBridge sends the next maneuver to the bike computer, which shows it in a pill on the main screen and switches to the full navigation screen shortly before the turn. How to set it up: TrailBridge.

Features

Navigation from the phone, through the Android app TrailBridge over BLE (protocol). Two sources: - OsmAnd: TrailBridge passes on OsmAnd's turn-by-turn navigation -- maneuver, distance, street name, the maneuver after next, lane guidance, roundabout exits - Your own GPX route: TrailBridge navigates along a GPX file itself, without OsmAnd. Turn hints come from the file or from the geometry of the track. With elevation data in the file the bike computer also gets the profile of the road ahead - The navigation screen opens by itself before a maneuver and closes after it: large turn arrow, distance ring, street name, next maneuver, lanes. In between, the main screen shows the next maneuver and its distance in a small pill - Tools/gpxenrich turns a plain GPX track into a route with turn hints (from BRouter)

Climbs on a GPX route: the climb screen shows the elevation profile ahead, coloured by gradient, with category, altitude and distance to the summit. It opens by itself at the foot of a rated climb (doc/CLIMB.md).

Route overview on a GPX route: one swipe to the left on the navigation screen opens the list of what is still ahead -- destination with arrival time, the waypoints of the file with name, distance and arrival time, and the climbs (which of how many, distance to the foot, height gain, length, gradient) (doc/ROUTE.md).

Main screen: speed (number and outer ring), cadence, heart rate with zone band, temperature, altitude, gradient, distance (ride / trip / tour / total), ride time or clock, driving state, status icons for WiFi, GPS fix and battery.

Rides and statistics - One button starts a ride, pauses it ("cruise") and ends it; stops and breaks are detected from the speed - Distance, time, average and maximum speed and average cadence per ride, trip, tour and in total; averages with or without stops, breaks and cruise time (doc/design/ride-state-machine.md)

Sensors - BLE: cycling speed & cadence (CSC), heart rate, battery level of each sensor; sensors are paired once and locked to their address - The phone's GPS position (through TrailBridge) for the ride log, and its time for the clock when there is no WiFi - BME280: barometric altitude and gradient, temperature (height calibration) - BMI160 IMU sensor to record the road quality - Forumslader hub-dynamo charger via my BLE gateway (build variant -FL)

Settings on the device: WiFi (on/off, hotspot, network setup with the display keyboard, doc/WIFI.md), BLE devices (connection, battery level, forget a sensor), height calibration, IMU calibration, restart and power off.

Logging - Binary ride log on SD card in dated folders: ride data every 5 s incl. GPS position and ride states - Debug log and raw Forumslader log (replayable on the device) - Python tools to convert logs to CSV and GPX, and a service that fetches the sessions when the bike computer shows up in the WiFi, archives them, exports GPX, syncs to Nextcloud and uploads to Komoot - Log upload from the bike computer to a Nextcloud folder (WebDAV, HTTPS) whenever it is online, for a bike that is not parked in reach of the home WiFi; set up on the web page /push, the service collects the files from there just like pulled ones - Session report: all key figures of a ride (climbs, heart-rate zones, TRIMP, estimated power, road quality, sensor dropouts and other technical findings) as a web page, Markdown or JSON; optionally also in words, written by a local LLM (Ollama) on the home server, with a check of every number it uses - Training analysis in the log service, in the Rim & Ridge design: fitness, fatigue and form over time, weeks by heart-rate zone, target events with countdown, training phase and the course's climbs, best times on recurring climbs - Test sessions (sensor simulator, TrailBridge GPX test ride) are recognised, marked and kept out of the ride list, training, Nextcloud and Komoot; idle sessions (switched on, no ride) are archived and can be deleted on the bike computer from the service - Bikes with weight and aerodynamics, assigned to the bike computers by date (several bike computers in one network: TRGB-BC, TRGB-FL); rides recorded elsewhere imported as GPX, also as earlier editions of a goal - Planned and regular routes as GPX in the log service: checked for what TrailBridge's navigation makes of them (turn hints, heights, gaps, waypoints), with distance, elevation profile and climbs, named waypoints on a map and in the profile (with distance from the start and to the destination); one route can be offered to TrailBridge, which fetches it by itself

Web interface (when on WiFi) - Download, replay and delete log files; live log with adjustable log levels - Ride statistics with a chart, odometer and wheel calibration - Manage BLE sensors; debug pages for sensors, accelerometer, climbs and crashes - WiFi: saved networks and their priority, hotspot settings (doc/WIFI.md) - Firmware and filesystem update over the air

Serial console with line editing, history and Tab completion (doc/DEBUG.md).

For development: a simulator build with fake sensors (doc/SIMULATOR.md), screenshots and touch input over HTTP (Tools/uishot.py), host tests for the pure algorithms (test/, Tools/tests/).

Hardware

  • LilyGO T-RGB (the two builds differ in the touch controller variant, TRGB_ROUND / TRGB_OVAL, and in Forumslader support)
  • Optional: BME280 and BMI160 on the I²C bus
  • LiPo battery
  • 3D-printed case and handlebar mounts -- a parametric model for the Canyon CP0007 gravel cockpit is in cad/, a first draft for the Forumslader build (oval display, ESP32 gateway, sits on stem and drop bar) in cad/fl/

T-RGB Bike Computer on the handlebar (older UI)

Build

PlatformIO, Arduino framework (pioarduino platform):

pio run -e trgb-esp32-s3 -t upload        # default: BLE + I²C sensors
pio run -e trgb-esp32-s3-FL -t upload     # Forumslader variant
pio run -e trgb-esp32-s3 -t uploadfs      # web interface files (data/site)

trgb-esp32-s3-ota and trgb-esp32-s3-FL-ota are the same builds, uploaded over WiFi to the device's /update endpoint. Target is TRGB-BC.local; if mDNS doesn't resolve, pass the IP: pio run -e trgb-esp32-s3-ota -t upload --upload-port 192.168.x.y. trgb-esp32-s3-sim is the simulator build.

The build applies small patches to two libraries (apply_patches.py), which needs the patch tool.

Where to go next

Source code: github.com/euphi/TRGB-BikeComputer. Contributions are welcome, see the roadmap for where help is wanted.

Licences and attributions