"Wardriving with an ESP32 and a GT-U7: lawful mapping of your own coverage"
Wardriving is the practice of driving (or walking, or cycling) around with a radio receiver and a GPS, recording the WiFi networks that announce themselves in the area. It is a passive activity: you log the fact that a network exists, its BSSID, RSSI, channel and security posture, plus where you were when you heard it. You do not join the network, you do not send data to it, and you do not decrypt anything. The WiFi chips on an ESP32 advertise themselves by default to anyone in range — that beacon is public information, and listening to it is how your phone decides which network to display.
Why do it? Two practical reasons. First, mapping your own coverage: if you run LoRa nodes, mesh APs, or client devices across a property, a wardrive tells you where the signal actually lands versus where the vendor datasheet says it should. Second, network hygiene: your home router's SSID broadcast pattern, channel crowding in your suburb, and how far your signal bleeds beyond your fence are all easier to see on a map than in a config page.
The hardware stack
The rig is two devices and a power source. The ESP32 side is covered by the StealthDeck Lite — a compact ESP32-based deck that runs scanning firmware, handles WiFi promiscuous mode and passive scan cycles, and stores logs. The GPS side is a GT-U7 / NEO-6M GPS wardriving module, which speaks standard NMEA over UART and stamps the fix quality, position and time onto your log entries.
GT-U7 vs NEO-6M
These are the two modules you'll see most often in wardriving projects, and they're close cousins:
- NEO-6M (u-blox 6 generation) is the long-established reference. 50 channels, GPS only, a cold start around 27 seconds under open sky, and a hot start near 1 second. Well-documented, well-supported by every Arduino and ESP32 GPS library.
- GT-U7 is a u-blox 6-compatible clone that runs the same NMEA protocol at the same default baud rate, usually at a lower price. In practice you configure and parse it exactly like a NEO-6M; some units ship with a 9600 baud default and some with 38400, so check your first output rather than assuming.
Both want a clear sky view. Ceramic patch antennas have poor sensitivity indoors or in a car with heavy tint — get the module's antenna near a windscreen, or on a magnet mount on the roof, and you'll see fix time drop from minutes to tens of seconds. A fix with no satellites is a log with no geography.
Wiring
Four wires: VCC (3.3 V — the GT-U7 tolerates 3.3–5 V on most boards but check your specific unit), GND, TX to an ESP32 RX pin, RX to an ESP32 TX pin. Put the GPS module at least 15 cm away from the ESP32 antenna if you can; the ESP32's 2.4 GHz bursts can saturate the GPS front end on the 1575 MHz band edge when both are tightly bundled.
The software pipeline
1. NMEA parsing
The GPS streams sentences like $GPGGA and $GPRMC at 1 Hz. Each contains latitude, longitude, altitude, number of satellites, and a validity flag. On ESP32, libraries such as TinyGPSPlus parse these cleanly. Only accept a position when the validity flag is A and the satellite count is above 4 — logging with a stale or degraded fix gives you coordinates that are metres to hundreds of metres wrong.
2. WiFi scanning
Two approaches on the ESP32:
- Active scan (
esp_wifi_scan_start) sends probe requests and collects beacons. It's what the ESP-IDF exposes directly, is fast, and returns SSID/BSSID/RSSI/channel/auth per AP. - Passive promiscuous mode (
esp_wifi_set_promiscuous) sniffs frames without transmitting. Slower per channel, but it emits nothing — which matters if you want the survey to be purely observational.
The ESP-IDF documentation for esp_wifi scanning covers both modes and the scan time trade-offs in detail.
3. Logging format
Write one CSV row per (AP observation, GPS fix): timestamp, latitude, longitude, BSSID, SSID, RSSI, channel, auth mode. Deduplicate on BSSID within a rolling window so you log a network once per fix rather than once per packet. At the end of a session, convert to KML for viewing in Google Earth, or straight to WiGLE's CSV format.
4. Uploading to WiGLE
WiGLE is the public wardriving database most hobbyists contribute to — it accepts CSV uploads of WiFi observations with GPS stamps, plots them on a map, and tracks coverage statistics. It only stores what you observed: BSSID, SSID, signal, location. Nothing about the network's contents, no client data, no keys. You can keep logs local if you prefer; uploading is a choice, not a requirement of the activity.
The Australian legal line
Australia's law here distinguishes listening from accessing, and that distinction is the whole game.
The Telecommunications (Interception and Access) Act 1979 (Cth) makes it an offence to intercept a communication passing over a telecommunications system without the knowledge of the parties — the legislation is published on the Federal Register of Legislation. That provision is aimed at the content of communications, not at the fact that a wireless network exists. A WiFi beacon broadcast at 1–10 dBm across a public street is not a communication between two parties that you have intercepted; it is an advertisement. Hearing it and logging its metadata is passive observation.
Where you cross into offence territory is joining or interfering:
- Connecting to a network — even briefly, even without authentication — without authorisation, and accessing data through it, engages the Commonwealth computer offences in Part 10.7 of the Criminal Code (unauthorised access to, modification of, and impairment of data held in a computer) — these are the provisions the CDPP prosecutes under for cybercrime.
- Deliberately transmitting to disrupt, jam, or interfere with a network's operation is a separate problem under telecommunications interference provisions and ACMA's spectrum rules. ACMA regulates the radio spectrum in Australia and takes a dim view of unlicensed transmissions outside permitted bands and powers.
We covered this distinction in our earlier piece on WiFi testing law in Australia: passive scanning of public beacons sits on the lawful side; active association, authentication attempts against networks you don't own, or any effort to decrypt captured traffic sits firmly on the unlawful side. State and territory surveillance device legislation adds another layer if you're logging in ways that could capture identifying information about people rather than infrastructure — keep your logs about access points, not about individuals.
One caveat we'll concede: the law is a moving target and we're not lawyers. This article describes the generally understood position, not legal advice. If you're doing anything beyond hobbyist mapping — penetration testing for a client, research publication — get specific advice.
Practical session notes
- Cold start: power the GT-U7 on and let it sit under open sky for 2–5 minutes before you start driving. If it's been off for weeks (battery-backed RAM empty), the first fix can take a couple of minutes; a hot start after a recent session is under a minute.
- Baud rate: match the ESP32 serial config to the module. If you see garbage characters, drop to 9600. Most GT-U7 units default to 9600.
- Logging cadence: a 1 Hz fix and a scan cycle every 2–3 seconds produces a log of a few MB per hour. An SD card or an ESP32 with SPIFFS/LittleFS handles this without trouble.
- Position noise: RSSI measurements vary by several dB between passes, so don't chase single-observation anomalies. A drive that crosses the same street twice gives you a far better coverage picture than one clean pass.
- Legal hygiene: never auto-join. Set the ESP32 to station mode with association disabled, or use promiscuous mode outright. Your log should contain zero connections.
The rig costs about the same as a takeaway dinner, takes an afternoon to build, and produces data that's immediately useful — where your mesh nodes actually reach, how crowded your channels are, and whether your router's signal respects your fence line.