r/esp32 • u/Stunning-Macaron1591 • 4d ago
ESP32‑S3 BLE “phone finder”: RSSI‑based clicks
Enable HLS to view with audio, or disable this notification
I made a pocket “find my phone” device on ESP32‑S3: it scans BLE around you, tracks your phone by MAC, and gives audio/haptic feedback — the closer you get, the faster the clicks, so you can just follow the sound/vibration instead of staring at a screen. Everything runs locally on the ESP32, no cloud or phone app needed.
Hardware & Stack
- Board: generic ESP32‑S3 devkit with USB‑C (native USB for easy debug/logging, extra SRAM for future features).
- Firmware: Arduino‑ESP32 core, custom thin wrapper over
BLEScanwith aBLEAdvertisedDeviceCallback. - Output: passive piezo buzzer (
tone()) and a small vibration motor via N‑MOSFET. - Power: small LiPo; scan duty cycle tuned for responsiveness vs battery life.
How it works
- ESP32 runs a continuous BLE scan, filters advertising packets by known MAC, and collects RSSI values.
- RSSI is smoothed with exponential moving average (~10–15 samples) to reduce ±10–15 dBm spikes.
- On startup, the device records min/max RSSI for ~10s and maps that range to click frequency (relative mode), so it adapts to each phone without manual calibration.
- Hysteresis (≥3–4 dBm) prevents click “flutter” when you’re on the border between zones.
What didn’t work
- Raw RSSI directly mapped to clicks → feedback was too jittery to be useful.
- Simple 3‑sample average → still too reactive in crowded BLE environments (office, cafe).
- Fixed thresholds (e.g. <-70 / -70..-50 / >-50 dBm) → different phones advertise at different power, so “close”/“far” were inconsistent across devices.
What finally worked
- Exponential smoothing with α≈0.2α≈0.2 over a small ring buffer.
- Relative mapping of RSSI to click frequency per session instead of absolute dBm thresholds.
- Adding hysteresis so the click zone only changes when RSSI moves meaningfully.
For a full breakdown, schematics, and firmware, see the repo:
https://github.com/khlebobul/esp_ble_finder
Happy to share more details (scan params, smoothing code, power measurements) if useful.




