Community project

Bluetooth Navigation Display

Photo of Bluetooth Navigation Display

chess hehh

Published November 13, 2026

This project builds a Bluetooth navigation display using an ESP32 and a small OLED screen. The device connects to a Chronos smartwatch via Bluetooth to receive real-time navigation data, displaying turn-by-turn directions, distance to the next maneuver, and estimated arrival time on a 128x64 pixel screen.

The guide provides a wiring diagram showing how to connect the SH1106 OLED display to the ESP32, a complete parts list, and the firmware needed to establish the Bluetooth connection and render navigation information. Assembly takes just minutes—connect power, wire the I2C signal lines, and verify the display powers on correctly.

Wiring diagram

Wiring diagram for Bluetooth Navigation Display
Loading diagram…

Gather all the parts

QtyComponent
1

SH1106 OLED

1.3 inch 128x64 OLED display with I2C interface using the SH1106 controller

Assemble it in 3 steps

1. Connect screen power

Unplug USB. Connect OLED VCC to the board's 3V3 pin (power), and OLED GND to GND (common ground). Read the printed labels; pin order varies.

  • Do not connect VCC to 5V; keep the screen and signal wires at 3.3V.

2. Connect the two signal wires

Connect OLED SDA to GPIO41 (data), and OLED SCL to GPIO42 (clock). Use the pins marked 41 and 42, not header position numbers.

3. Check and power the circuit

Check for swapped power wires and loose connections, then power the ESP32-S3 with a USB data cable. This project assumes a four-pin 128x64 SH1106 OLED.

  • Use USB power; this project does not include a battery circuit.

Review all connections

1. Connections between "oled" and "ESP32"

FunctionoledESP32
powerVCC3V3
groundGNDGND
i2cSDAGPIO 41
i2cSCLGPIO 42

Deploy the firmware

#include <Arduino.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SH110X.h>
#include <ChronosESP32.h>
#include <atomic>

Adafruit_SH1106G oled(128, 64, &Wire, -1);
ChronosESP32 watch("Pocket Nav");
std::atomic<bool> connected{false};
bool screenOK = false;
String previous;
uint32_t lastPoll = 0;
void connectionCallback(bool state) { connected.store(state); }

void setup() {
  Serial.begin(115200);
  Wire.begin(41, 42);
  uint8_t address = 0;
  for (uint8_t a : {uint8_t(0x3C), uint8_t(0x3D)}) {
    Wire.beginTransmission(a);
    if (Wire.endTransmission() == 0) { address = a; break; }
  }
  if (address) screenOK = oled.begin(address, false);
  if (!screenOK) Serial.println("OLED not found: check VCC/GND, SDA 41, SCL 42");
  watch.setConnectionCallback(connectionCallback);
  watch.begin();
  Serial.println("Connect to Pocket Nav inside Chronos, not Android Bluetooth settings.");
}
void loop() {
  watch.loop();
  if (millis() - lastPoll < 200) { delay(5); return; }
  lastPoll = millis();
  bool linked = connected.load();
  Navigation nav = watch.getNavigation();
  bool active = linked && nav.active;
  String key = String(linked) + ":" + String(active);
  if (active) key += ":" + nav.distance + ":" + nav.directions + ":" + nav.title + ":" + nav.eta + ":" + String(nav.hasIcon) + ":" + String(nav.iconCRC);
  if (!screenOK || key == previous) return;
  previous = key;
  oled.clearDisplay();
  oled.setTextColor(SH110X_WHITE);
  oled.setTextSize(1);
  oled.setTextWrap(false);
  oled.setCursor(0, 0);
  if (!active) {
    oled.println("POCKET NAV");
    oled.setCursor(0, 18);
    oled.println(linked ? "Phone connected" : "Waiting for phone");
    oled.setCursor(0, 32);
    oled.println(linked ? "Start Google Maps" : "Open Chronos app");
    oled.setCursor(0, 44);
    oled.println(linked ? "navigation on phone" : "Pair: Pocket Nav");
  } else {
    oled.print(nav.distance.substring(0,21));
    if (nav.hasIcon) oled.drawBitmap(0, 16, nav.icon, 48, 48, SH110X_WHITE);
    String text = nav.directions.length() ? nav.directions : nav.title;
    for (int line=0; line<4; ++line) {
      oled.setCursor(52, 16 + line*10);
      oled.print(text.substring(line*12, (line+1)*12));
    }
    oled.setCursor(52,56);
    oled.print(nav.eta.substring(0,12));
  }
  oled.display();
}

Remix this project

Make it yours in one click

Open a full copy of this project in your own Schematik workspace, diagram, code, parts, and assembly steps included. Swap the sensor, add features, or redesign the whole thing with AI. The author's original stays untouched.

Open in Schematik