NavCube is a pocket-to-dashboard navigation companion for motorcycles: an Android phone reads Google Maps navigation notifications, sends compact guidance updates over Bluetooth, and a Raspberry Pi Zero 2 W renders the next maneuver on a sunlight-readable E Ink display.
NavCube is now working end to end:
- Android notification access captures Google Maps navigation updates.
- The Android app parses notification text into the shared
NavUpdateV0protocol. - Bluetooth RFCOMM carries JSON-lines packets from the phone to the Pi.
- The Pi service validates, throttles, and renders updates on the Waveshare 2.13 inch E Ink HAT.
- UDP replay remains available for bench testing and fixture-driven development.
- The Pi can run as a systemd service with a pairing helper, volatile logging, and optional Android-triggered shutdown.
The rider-facing display stays intentionally minimal:
- Large maneuver arrow
- Remaining distance in meters or kilometers
- Current time and Google Maps arrival time
- Phone battery gauge
- Bluetooth connection state
The E Ink refresh policy favors readability and panel health over animation. The Pi only redraws when guidance meaningfully changes, a footer value changes, or the frame reaches its max staleness window.
Google Maps notification
|
v
Android NotificationListenerService
|
v
Google Maps notification parser
|
v
NavUpdateV0 JSON line
|
v
Bluetooth RFCOMM
|
v
Raspberry Pi display service
|
v
Waveshare E Ink display
android-app/- Android companion app, notification listener, parser integration, and Bluetooth transportraspberry-pi/- Pi runtime, systemd units, Bluetooth pairing agent, display drivers, and fresh-install toolingshared/- Protocol schemas and examples shared by Android and Pitools/- Bench simulators and replay helpersdocs/- Hardware, deployment, and parser notes
For a newly flashed Raspberry Pi OS image, copy the bootstrap bundle to the Pi and run the installer:
scp navcube-fresh-pi-bootstrap.tar.gz <user>@<pi-host>:/tmp/
ssh <user>@<pi-host>
mkdir -p ~/navcube-bootstrap
tar -xzf /tmp/navcube-fresh-pi-bootstrap.tar.gz -C ~/navcube-bootstrap
cd ~/navcube-bootstrap
sudo bash fresh-pi-install.shThe installer copies NavCube to /opt/navcube, installs runtime dependencies, enables the display service, starts the Bluetooth pairing agent, and configures the Pi for the Waveshare driver by default.
See raspberry-pi/FRESH_PI_SETUP.md for the full setup flow.
- Build and install the Android app from
android-app/. - Pair the phone with the Raspberry Pi Bluetooth device named
NavCube. - Open NavCube and grant Bluetooth permission.
- Enable NavCube in Android notification access settings.
- Start Google Maps navigation.
The app sends parsed updates to the paired Pi automatically. The in-app test packet is still useful for checking Bluetooth before starting a real route.
The Pi service can run without Bluetooth by using the UDP transport and the console driver:
cd raspberry-pi/display-service
NAVCUBE_TRANSPORT=udp NAVCUBE_DRIVER=console PYTHONPATH=. python3 scripts/run_service.pyReplay a fixture from another terminal:
python3 tools/simulator/replay_fixture.py raspberry-pi/display-service/tests/fixtures/city_route.json --host 127.0.0.1Motorcycle use assumes ignition-hot power, so sudden Pi power loss is treated as normal. The deployment docs cover volatile journald, read-only/overlay filesystem mode, Bluetooth-first operation, and bring-up order:
docs/motorcycle-deployment.mddocs/hardware-bringup-checklist.mddocs/hardware-arrival-todo.md
The active runtime protocol is v0. It is intentionally small, stateless, and last-write-wins. See shared/protocol/v0/README.md and the JSON schema in shared/protocol/v0/navigation-update.schema.json.
NavCube is released under the MIT License. See LICENSE.
