A small nav pod that shows turn-by-turn directions, weather, a compass, and trip stats for your bike. Your iPhone does the work and the display just draws. Here is how it works and how to build one.
Go Marker is a small round display for your bike. It shows turn-by-turn directions from your iPhone: the next turn, how far away it is, the street name, and a map with your route on it. Swipe and you get weather, trip stats, a compass with your elevation, and a clock.
The display is dumb on purpose. Your phone does the routing, the GPS, the map data, and the weather, then sends the results over Bluetooth. The display only draws them. That keeps the hardware down to one inexpensive board and a USB cable.
The Go Marker iPhone app is not part of the download. I am preparing it for the App Store. This guide builds the display: the firmware, the screens, and the desktop simulator. The Bluetooth messages between the phone and the display are written down in proto/nav_protocol.h, in case you want to write your own app.
Two devices share the job and talk over Bluetooth.
Your iPhone works everything out:
The display only shows it. It takes what the phone sends and draws it on the screen. It has no GPS and no internet of its own, so it needs the phone to work.
About once a second the phone sends a small status message: position, speed, heading, the next turn, its distance, the street name, and time left. Less often it sends the next few miles of route, the streets, parks, and water around you, and the weather. Every message is a small fixed-size packet. They are all defined in one header file, proto/nav_protocol.h, which the display firmware and the simulator share, and which any phone app has to follow.
The code is in three folders:
firmware/ is the ESP-IDF project for the board.ui/ and proto/ are the screen drawing code (written with LVGL 9) and the packet definitions. The board and the simulator both build them.sim/ is a desktop simulator that draws the same screens on your computer, so you can try the interface before you touch any hardware.The hardware is in the parts list below. For software:
cmake and sdl2 if you want the simulator.I built and tested all of this on a Mac with ESP-IDF 5.3.2.
Do these once, before step 1. Each one heads off a confusing error later.
brew. The installer also sets up Apple’s command line tools if you don’t have them, and those include the git command the steps use.NOTE: If you have trouble with the instructions, just have Claude do it for you.
The command-line steps are typed into Terminal. Terminal is the command-line app that comes with your Mac. To open it, press Command-Space, type Terminal, and press Return. Every dark box below with commands in it is meant for Terminal: type or paste one line, press Return, and wait for it to finish before the next line.
Download the Go Marker source code (zip). Unzip it by double-clicking the file. You get a folder called go-marker. The commands below assume it is in your Downloads folder. If you put it somewhere else, use that path in the cd line at the top of each box. It is released under the Apache License 2.0, and the readme in the zip has a one-page summary of these steps.
The simulator shows the real screens riding a made-up route. In Terminal:
cd ~/Downloads/go-marker
brew install cmake sdl2
git clone --depth 1 --branch v9.4.0 https://github.com/lvgl/lvgl.git lvgl
cd sim
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build -j8
./build/nav_sim
Drag left or right in the window to swipe between pages. Close the window when you are done; Terminal then gives you its prompt back.
First, install ESP-IDF 5.3.2, the toolkit that builds the display’s software. You only do this once. In Terminal:
brew install python@3.11 cmake ninja dfu-util
export PATH="/opt/homebrew/opt/python@3.11/libexec/bin:$PATH"
mkdir -p ~/esp
cd ~/esp
git clone -b v5.3.2 --recursive https://github.com/espressif/esp-idf.git
cd esp-idf
./install.sh esp32s3
export PATH line makes Terminal use Python 3.11. ESP-IDF needs it. The Python that comes with macOS (3.9) gave me trouble.git clone line downloads over a gigabyte, so it takes a while. install.sh then downloads the ESP32 compiler./opt/homebrew to /usr/local.Then build the software and put it on the display. Do this in every new Terminal window, starting with the first two lines. Plug the display into your Mac with the USB-C cable first:
export PATH="/opt/homebrew/opt/python@3.11/libexec/bin:$PATH"
source ~/esp/esp-idf/export.sh
cd ~/Downloads/go-marker/firmware
idf.py set-target esp32s3
idf.py build
ls /dev/cu.usbmodem*
The ls line prints the display’s port name, something like /dev/cu.usbmodem101. Use that name in the last line, in place of /dev/cu.usbmodemXXXX:
idf.py -p /dev/cu.usbmodemXXXX flash
set-target is needed the first time only.build downloads LVGL (the screen library), so it needs internet, and it takes a few minutes.python3 main/voices/make_voices.py in the same firmware folder, then run the idf.py build and flash lines again. Without them the display just stays quiet.The phone app is not in the download yet, and I am preparing it for the App Store. Until it is out, the display shows its splash screen and waits for a phone. You can still see all of its screens in the simulator from step 2.
The display runs on 5 V over USB-C. Feed it from a 12 V to 5 V USB adapter on switched power, so it comes on with the ignition.
I run it without a battery. The board has a battery connector and I left it empty. A lithium cell in a closed case sitting in the sun is a bad idea, and the trip stats are already safe without one.
The display firmware, the screens, the simulator, and the Bluetooth packet definitions are released under the Apache License 2.0. The phone app is not part of that release. You can use the released code, change it, and share it, and the license has the usual “as is, no warranty” terms. The No Marker name and logo are not part of the license, so use your own splash picture. The readme lists the other people’s code and data it relies on.
This is a hobby project, not a safety device. Do not let it take your attention off the road. Set your route before you ride. Check the directions against the road and the signs yourself, and ride within your abilities and the law.
The version number of your download is in the file VERSION in the top folder.
1.2, October 12, 2026
--vintage, --vintage-day, --vintage-auto, --tripper, --tripper-night, --tripper-auto, --standard-day, and --standard-night.1.1, October 3, 2026
--free option that shows the view you get with no route running.1.0, October 2, 2026