Building an ESP32 Tactical RF Radar: Wi-Fi Sniffing, BLE Tracker Detection & Real-Time Web UI
Have you ever wondered what invisible radio signals are floating around you right now? From smartphones scanning for known Wi-Fi networks to Apple AirTags quietly broadcasting BLE ping frames, our ambient environment is buzzing with RF data.
In this project, I built a standalone Tactical RF Reconnaissance Radar using a single $4 ESP32 board. It turns the ESP32 into a wireless sniffer, processes multiple signal protocols simultaneously, and serves a dark-themed HTML5 visual radar dashboard directly over its own Wi-Fi Access Point.
๐ ๏ธ The 4 Core Features
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ ESP32 RF RADAR ENGINE โ
โโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโ
โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โผ โผ โผ
โโโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโ
โ 1. Wi-Fi APs โ โ 2. Client Probes โ โ 3. BLE Trackers โ
โ (SSID, Auth, Ch) โ โ(Promiscuous Sniffโ โ(AirTags, Tiles) โ
โโโโโโโโโโฌโโโโโโโโโโ โโโโโโโโโโฌโโโโโโโโโโ โโโโโโโโโโฌโโโโโโโโโโ
โ โ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ 4. Embedded WebSockets โ
โ HTML5 Radar UI โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโ
1. Active Wi-Fi Access Point Spectrum Scanning
The device scans nearby 2.4 GHz Wi-Fi Access Points, capturing their SSID, BSSID (MAC address), channel, signal strength (RSSI), and encryption standard (WPA2, WPA3, Open).
To convert raw RSSI into estimated physical distance in meters, the firmware applies the Log-Distance Path Loss Model:
Where A is reference RSSI at 1 meter (-59 dBm) and n is the path loss exponent (~3.0 for indoor environments).
2. Wi-Fi Client Probe Request Sniffing (Promiscuous Mode)
Even when smartphones aren't connected to a Wi-Fi network, they continuously broadcast 802.11 Probe Requests searching for previously saved networks.
By putting the ESP32 Wi-Fi chip into Promiscuous Mode, the system hooks directly into raw hardware interrupts (esp_wifi_set_promiscuous_rx_cb) to intercept these management frames in real timeโallowing us to detect nearby phones and laptops.
3. BLE & Anti-Stalking Tracker Parsing
The ESP32 runs an active Bluetooth Low Energy (BLE) scan to detect ambient BLE beacons. By parsing the Manufacturer Data vendor IDs in raw BLE advertisement payloads, the code identifies target tracker signatures:
-
Apple AirTag / Find My Network:
0x004C -
Tile Trackers:
0x0059 -
Samsung Galaxy SmartTags:
0x0075 -
Google Find My Device Network:
0x00E0/0xFE2C
When a tracker is detected, it is flagged as a high-priority threat vector on the dashboard.
4. Embedded WebSockets & HTML5 Radar Dashboard
The ESP32 hosts its own Wi-Fi Access Point (ESP32-Radar) and web server on Port 80. When connected, it serves a single-page HTML5 Canvas application.
Instead of heavy HTTP polling, the ESP32 pushes live JSON target payloads every 3 seconds over a persistent WebSocket connection (Port 81), animating target blips across a glowing green radar sweep line in real time.
๐ป Key Code Highlights
Setting Up Promiscuous Frame Filtering
To intercept phone probe requests without dropping packet throughput, we inspect raw IEEE 802.11 management headers:
// Wi-Fi Promiscuous Callback (Interprets raw IEEE 802.11 frames)
void wifiSnifferCallback(void* buf, wifi_promiscuous_pkt_type_t type) {
if (type != WIFI_PKT_MGMT) return;
const wifi_promiscuous_pkt_t* pkt = (wifi_promiscuous_pkt_t*)buf;
const wifi_mgmt_hdr_t* mgmt = (wifi_mgmt_hdr_t*)pkt->payload;
uint16_t fc = mgmt->frame_ctrl;
uint8_t frameType = (fc >> 2) & 0x03;
uint8_t frameSubtype = (fc >> 4) & 0x0F;
// Intercept Subtype 4: Management Probe Requests from Smart Devices
if (frameType == 0 && frameSubtype == 4) {
uint8_t* srcMac = (uint8_t*)mgmt->addr2;
int rssi = pkt->rx_ctrl.rssi;
// Store captured client MAC & RSSI metrics...
}
}
Parsing Vendor Signatures for AirTags
String mData = device.getManufacturerData();
bool isTracker = false;
if (mData.length() >= 2) {
uint16_t vendorId = ((uint8_t)mData[1] << 8) | (uint8_t)mData[0];
if (vendorId == 0x004C) {
trackerMeta = "Apple AirTag / FindMy";
isTracker = true;
} else if (vendorId == 0x0059) {
trackerMeta = "Tile Tracker";
isTracker = true;
}
}
๐งฐ Hardware & Requirements
- Board: Any ESP32 Dev Module (ESP-WROOM-32, ESP32-S3, etc.)
- Framework: Arduino Core for ESP32
- Libraries:
-
ArduinoJson(JSON serialization) -
WebSocketsServer(Real-time browser streaming) -
BLEDevice(Native ESP32 BLE stack)
๐ How to Run It
- Flash the sketch onto your ESP32 board using Arduino IDE.
- Open your phone or laptop Wi-Fi settings and connect to
ESP32-Radar(Password:12345678). - Open your web browser and navigate to
[http://192.168.4.1](http://192.168.4.1). - Watch the radar sweep render nearby Wi-Fi APs, active smartphones, and BLE trackers!
๐ฎ What's Next?
The next evolution for this project is shifting from a local web dashboard to a distributed telemetry node:
- Implementing FreeRTOS Dual-Core queues to keep packet capture non-blocking.
- Streaming live telemetry over MQTT to a central time-series database (TimescaleDB / InfluxDB).
- Multi-node triangulation to pinpoint exact (x,y) indoor device coordinates.
What features would you add to an ambient RF scanner? Let me know in the comments below!


Top comments (0)