I’ve been building mini wardrivers for a while, and the WiFi Shuriken takes a different approach to coordinating multiple radios. It is a standalone wardriving platform with six ESP32-C5 scanners, an RP2350 controller, a GNSS receiver, and SD card logging. The goal was to separate scanning from the other work involved in collecting and logging observations, giving each part of the system a specific responsibility. With six radios collecting results, communication and logging needed to keep up as well.
For anyone unfamiliar with wardriving, the idea is to observe wireless devices and record metadata about them along with your location. For WiFi, this includes the SSID (network name), BSSID (MAC address), frequency band, channel, security settings, and signal strength. Combined with the location, date, and time, these observations can be used to map networks. WiGLE collects submissions from wardrivers, estimates network locations, and makes it possible to see trends over time. It’s also a good excuse to explore new areas and collect some Fake Internet Points.
The Shuriken takes inspiration from Wardriver.uk by Joseph Hewitt and WiFydra by Lozaning. I wanted to keep the scope focused on scanning and logging, with a clear separation between the controller and scanners. Operation is simple: apply power, and scanning and logging begin. The current design has no LCD or OLED display, web interface, automatic upload, or runtime configuration.
How it works
For the controller, I used a Seeed Studio XIAO RP2350. It has a dual-core ARM processor, which lets me split the work between the cores. Core 0 handles SD card logging and the location, time, and date from the GNSS receiver. Core 1 handles the scan channel scheduler and communication with the scanners. This gives scan scheduling and scanner communication a dedicated core while the other core handles location data and storage.
The GNSS receiver is a Quectel LC86L. It supports GPS, QZSS, BeiDou, GLONASS, and Galileo, with up to three constellations operating simultaneously. It also has a built-in real-time clock and battery-backed memory. I configured the UART connection for 115200 baud and the receiver for 5 Hz updates, with non-essential messages disabled to reduce the amount of data the controller needs to process.
Each scanner is a Seeed Studio XIAO ESP32-C5, with a single-core RISC-V processor and a WiFi radio that supports both 2.4 GHz and 5 GHz. The scanners handle the WiFi scan logic, including radio control, active or passive scanning, and scan duration. They accept commands from the controller and queue their results until the controller requests them.
One important part of the scheduling is that no single scanner is permanently responsible for a particular channel. The controller schedules channels across the scanners, so a scanner failure doesn’t leave its assigned channel out of the scan schedule entirely.
Getting the results back
Once the scanners have collected results, those results need to reach the controller without communication becoming a bottleneck. For this, I used a 20 MHz SPI bus. The raw transfer rate is 20 Mbps, or about 2.5 MB/sec. At 70% bus utilization, the protocol has capacity to transfer roughly 27,000 results per second. Given that during my testing, the highest 60 second WiFi count was 2048, we have plenty of capacity for even the densest environments.
The controller communicates directly with each scanner, using a shift register to select the individual scanner. Scanners only transfer data when prompted, so the controller controls when results are retrieved and new scans are requested. The protocol has a small set of operations: check the result count and status, transfer a record, or scan a channel.
The shift registers can be daisy-chained, allowing the addressing scheme to grow to 64 or more scanners. The current Shuriken uses six, but additional scanners can use the same controller/scanner arrangement.
With multiple radios scanning the same area, there will be overlap in the results. To reduce repeated observations being written to the SD card, deduplication happens at two levels. Each scanner filters duplicate AP results before reporting them, and the controller deduplicates results again before logging. The information used includes the SSID, BSSID, band and channel, and security settings.
On the controller, I use a hash table with FIFO eviction. Hashing reduces the memory footprint and makes lookups fast, while FIFO eviction removes the oldest entries when room is needed. Filtering duplicates before writing them helps keep the logging side moving as results arrive from multiple scanners.
RFHS at DC34
I covered the architecture and comparison results in my RFHS talk at DC34. For the test results and a more detailed walkthrough, you can watch the presentation and follow along with the accompanying slides.
What’s next?
Keeping the scanners separate from the controller leaves room for other types of radios in the future. HaLow and 6 GHz are possibilities, while the current ESP32-C5 scanners cover 2.4 GHz and 5 GHz. Optional phone or PC integration was still in development at the time of the presentation. Standalone scanning and logging remain the focus of the current design.
For anyone already using Wardriver.uk, I also have C5-Open-AT. It lets an ESP32-C5 replace the Realtek BW16 for 5 GHz scanning in an existing unit, providing an upgrade path for that hardware.
Much thanks to grim0us, M0nkeyDrag0n, MrBill, and pejacoby for their help and feedback during beta testing!
