Web Bluetooth is not supported in this browser. Open in Chrome on desktop or Android.
Connection
Mic Check
The Web Speech API has no device selection option. It always uses the OS/browser
default input device. This panel lets you see every input device Chrome can access
and confirm one is actually live, but it cannot force the Voice Command Test below
to use a non-default device. To change what "default" means, set it in Chrome's
microphone site settings or in your OS sound settings.
Chrome on desktop (Windows / macOS) or Android only
Web Bluetooth is not supported in Firefox or Safari
iOS Chrome does not support Web Bluetooth due to Apple WebKit restrictions
Must be served over http:// or https://, not file://
Run locally: npx serve . or python -m http.server 8080
Windows Setup
Go to chrome://flags/#enable-experimental-web-platform-features and set to Enabled, then relaunch Chrome
Windows forces OS-level pairing before GATT access. Just Works pairing is configured in firmware so no PIN is required but a pair dialog will appear once
If the device appears in Windows Bluetooth settings as previously paired but connection fails, remove it from Windows Bluetooth settings and try again
Connection Dropping on Windows
ESP32 BLE drops the connection if GATT service discovery starts too quickly after connect on Windows Chrome
An 800ms delay is applied after GATT connect before service discovery to work around this
If the connection still drops, a retry is attempted automatically with a 1200ms delay
If connection consistently fails, try removing the device from Windows Bluetooth settings and reconnecting fresh
IMU Telemetry Characteristic
The IMU Telemetry characteristic is NOTIFY only. It has no readable value until a client subscribes
Click Subscribe Telemetry after connecting to start receiving data
If Subscribe fails, disconnect, reconnect, and try again
MTU
Default BLE MTU is 23 bytes (20 usable). JSON telemetry payload is ~120 bytes. If MTU shows 23 in the diagnostics panel, the payload is being fragmented across multiple BLE packets. The Angular companion app must request MTU >= 128 at connect time to receive each payload in a single packet.
MAC Address Discrepancy
Windows and Chrome may show a randomized BLE address that differs by one digit from the efuse MAC shown in the diagnostics panel. This is normal. The efuse MAC in the JSON payload is always the authoritative device identifier.
Stale Bond State (Windows) - Manual Fix
If the connection count in Serial Monitor is in the hundreds or thousands on first connect, Windows is holding stale BLE bond state from a previous session. This causes a rapid connect/disconnect loop that prevents service discovery from completing.
Manual fix: Open Windows Bluetooth settings, find the SnookerSense device, click Remove device, power cycle the ESP32, then reconnect. This clears the stale bond state on the Windows side.
Firmware fix: BLETransport clears all stored bonds from NVS on every boot via esp_ble_remove_bond_device() after BLEDevice::init(). Combined with ESP_LE_AUTH_NO_BOND in security config, no new bonds are stored so the loop should not recur after the first clean boot post-flash.
iOS Validation
Web Bluetooth does not work on iOS. Use the nRF Connect mobile app on iPhone to validate BLE connectivity until the native Angular/Capacitor app is built. The nRF Connect mobile app shows JSON values in ASCII format for custom characteristics.
Mic Device Selection Limitation
The Web Speech API (used by the Voice Command Test panel) has no parameter to bind recognition to a specific input device. It always uses the OS/browser default device at the moment recognition starts. The Mic Check panel uses a separate getUserMedia + AnalyserNode meter to show all available devices and confirm one is live, but it cannot redirect SpeechRecognition itself. To change which device is used, change the OS or Chrome default input device.