Build a DIY UWB Item Finder: DW3000 Ranging Tags and an ESP32 Readout
Bluetooth trackers like Tile and AirTag estimate distance from signal strength, which is a rough guess at best — RSSI bounces around with orientation, obstacles, and interference, so "how far away is it" is really "how far away is it, plus or minus several meters." Ultra-wideband (UWB) ranging works completely differently: it times how long a radio pulse takes to travel between two devices and calculates distance from the speed of light, the same principle behind Apple's U1/U2 chip in the iPhone and AirTag. Done right, UWB ranging is accurate to within 10-30 cm, works through walls better than IR, and doesn't care about the reflective/absorptive quirks that make RSSI-based distance estimation nearly useless indoors. This project builds a pair of open, hackable UWB ranging tags — one you keep, one you attach to whatever you don't want to lose — using the same class of radio chip Apple's ecosystem is built on.
How UWB Ranging Actually Works
Instead of measuring signal strength, a UWB radio measures time-of-flight: it sends an extremely short, wideband radio pulse and precisely times how long the round trip takes using a technique called Two-Way Ranging (TWR). Because radio waves travel at roughly 30 cm per nanosecond, the DW3000's sub-nanosecond timing resolution translates directly into centimeter-scale distance accuracy — a property RSSI-based Bluetooth and Wi-Fi ranging simply cannot match, because signal strength is affected by antenna orientation, multipath reflection, and obstacles in ways that don't map cleanly to distance.
Wiring the DW3000 to the ESP32
The DW3000 talks SPI, plus two GPIO lines for reset and the ready/interrupt signal:
DW3000 PinESP32 PinPurpose MOSIGPIO23SPI data out MISOGPIO19SPI data in SCKGPIO18SPI clock CSGPIO5SPI chip select IRQGPIO4Ranging-complete interrupt RSTGPIO2Hardware reset 3V3 / GND3V3 / GNDPower — do not run at 5V, the DW3000 is 3.3V onlyFirmware: Two-Way Ranging
Both boards run essentially the same firmware, distinguished by role (initiator vs. responder). Qorvo publishes an open DW3000 API and example TWR code; the Makerfabs and Decawave community forks of this API are the easiest starting point for Arduino/ESP-IDF rather than writing the double-sided TWR exchange from scratch. The exchange sequence: the initiator sends a poll message, the responder replies after a fixed processing delay, the initiator sends a final message embedding its own transmit/receive timestamps, and the responder computes distance from the round-trip time minus the known processing delay. Both timestamps are exchanged so clock drift between the two independent crystal oscillators cancels out — this is the entire reason TWR needs three messages instead of a naive one-way ping.
On the finder unit, poll for a new range measurement every 200-500 ms, apply a simple moving average over the last 5 readings to smooth jitter, and drive the OLED with a live distance readout plus a directional "getting warmer/colder" indicator based on the trend. Trigger the piezo buzzer's beep rate to increase as distance decreases — the same "hot and cold" pattern people already expect from metal detectors and other proximity tools.
Enclosure Design
Print the tag half as a slim, keyring-mountable case — the DW3000 module's ceramic antenna needs clearance from metal and dense plastic on at least one face, so keep that side of the print thin-walled (1-2 perimeters) rather than solid infill, and avoid mounting the tag directly against a metal keyring bow. The finder half needs room for the OLED, ESP32, and battery; a two-part case with heat-set inserts holds up to repeated battery swaps far better than the print's own PLA threads. Vent the buzzer with a small grille rather than fully enclosing it — a sealed cavity muffles the beep more than you'd expect.
Realistic Expectations
This project gets you into the 10-30 cm accuracy range under good conditions — line of sight or a single interior wall — which is genuinely useful for "which couch cushion" or "which room" hunting, not GPS-replacement precision. Multipath reflection off metal shelving, large appliances, or a cluttered garage will degrade accuracy, and range tops out around 30-60 meters line-of-sight depending on antenna and TX power settings. It won't out-range a Sub-GHz signal the way a Flipper Zero's Sub-GHz radio does, and it isn't a substitute for Apple's Find My network coverage — but as a from-scratch build teaching real time-of-flight ranging rather than an RSSI approximation, it's a solid electronics project with a genuinely different working principle than the Bluetooth and Wi-Fi ranging projects already common in the maker space.
Related Guides
- How to Program Addressable LED Strips: WS2812B Patterns, Effects, and Power Design
- I2C vs SPI vs UART: How to Choose and Use Serial Communication Protocols
- How to Use Sensors with Arduino and ESP32: Temperature, Distance, Load, Current, and Hall Effect
- How to Control Motors with Arduino and ESP32: Stepper, DC, and Servo Drivers
- How to Hack Wi-Fi and Bluetooth with the Flipper Zero and Wi-Fi Marauder
- ESP32: Setting Up for Arduino IDE
- Setting Up Marauder on the ESP32 Wi-Fi Dev Board for Flipper
- Setting Up Wi-Fi Dev Board with Flipper Zero