Je travaille sur un projet perso assez fun (et très concret) : monter un Raspberry Pi Zero 2 W sur un drone pour scanner les réseaux Wi‑Fi visibles pendant le vol, enregistrer toutes les données en local, puis analyser à la maison sur une interface web avec carte.
L’idée n’est pas de “pirater” quoi que ce soit : l’objectif est de cartographier la couverture Wi‑Fi sur une zone donnée (ex. site / entreprise / terrain), avec une vue claire : où je capte bien, où le signal devient faible, et comment se répartissent les points d’accès.




Le concept : “Wi‑Fi + GPS + base de données”
Pendant le vol, on collecte deux types d’informations :
- Wi‑Fi : SSID, BSSID (MAC), puissance du signal (RSSI), canal, chiffrement…
- GPS : latitude, longitude, altitude, timestamp
À chaque “tick” (ex. toutes les 10 secondes), on fait un scan Wi‑Fi et on associe les résultats à la dernière position GPS valide.
Ensuite, toutes les mesures sont stockées dans une base locale (SQLite). À la maison, on lance une interface web qui permet de :
- voir les réseaux sur une carte,
- afficher une vue “couverture” (heatmap) en fonction du RSSI,
- supprimer des réseaux non pertinents,
- afficher des infos avancées (debug GPS/collecte).
Matériel utilisé
Raspberry Pi
- Raspberry Pi Zero 2 W (léger, compact, suffisant pour du scan + SQLite + Flask)
GPS
- Un module GPS UART (type NEO‑6M / NEO‑M8N)
- Connexion via GPIO (UART)
Câblage (principe) :
- VCC → 5V
- GND → GND
- TX GPS → RX Pi (GPIO15)
- RX GPS → TX Pi (GPIO14)
Collecte : comment ça marche
Scan Wi‑Fi
Sur Linux, le scan se fait avec :
iw dev wlan0 scan
On parse ensuite la sortie pour extraire :
- BSS / BSSID
- SSID
- signal: -xx dBm
- channel
- encryption (WPA2/WPA3/open…)
Lecture GPS
Le GPS arrive en trames NMEA sur /dev/serial0 (UART).
On lit typiquement des phrases GGA / RMC qu’on parse pour obtenir lat/lon/alt.
Modèle de stockage (SQLite)
Deux tables principales :
access_pointsbssid,ssid,encryption,channelfirst_seen,last_seen- une colonne
vendor(constructeur, voir plus bas)
- une colonne
measurementsap_id(clé vers l’AP)timestamp,lat,lon,altrssi
L’intérêt : access_points = “référentiel” des réseaux, measurements = toutes les mesures dans l’espace/temps.
Interface Web : carte, liste, debug
Côté serveur :
- Flask (API JSON + page HTML)
Côté client :
- Leaflet + fond OpenStreetMap
- Une vue “Points”
- Une vue “Couverture” (heatmap)
Vue “Points”
- Un marqueur par réseau (regroupé par SSID, donc un seul item même si plusieurs bornes/ BSSID)
- Couleur selon le RSSI (vert/jaune/rouge)
- Popup détaillée : SSID, BSSID, chiffrement, canal, RSSI, timestamp, nombre de bornes, constructeur
Vue “Couverture”
- Une heatmap construite à partir de toutes les mesures
- En gros : plus le RSSI est fort, plus c’est “chaud” (zone de bonne couverture)
Liste des réseaux
À gauche, une liste de tous les réseaux détectés.
Au clic, ça recentre la carte sur le marqueur.
Debug
Un panneau debug aide à vérifier rapidement :
- fix GPS, nombre de satellites, lat/lon
- “dernier scan”, erreurs éventuelles
- compteurs en base
Bonus : identifier le constructeur via l’adresse MAC (OUI)
Chaque BSSID est une adresse MAC. Les 3 premiers octets (OUI) indiquent souvent le constructeur.
Exemple :
8C:F8:13:…→ constructeur X
J’ai ajouté une base offline de préfixes IEEE (fichier oui.txt officiel), parsée en oui_vendors.csv, puis importée dans une table SQLite vendors.
Ensuite, à chaque nouvel AP vu :
- on extrait
AA:BB:CC - on fait la correspondance OUI → constructeur
- on stocke
vendordansaccess_points
Résultat : sur l’interface, on peut voir qui fabrique quoi (utile quand on veut distinguer box opérateur, matériel pro, etc.).
Démarrage automatique au boot (systemd)
Pour éviter de lancer à la main :
wifi-collector.servicedémarre la collecte au bootwifi-web.servicedémarre l’interface web au boot
Comme ça :
- J’allume le Pi
- Il collecte automatiquement
- Je me connecte au web pour visualiser
Ce que j’ai appris (et les “pièges”)
- Le GPS : dehors, ciel dégagé, le premier fix peut prendre plusieurs minutes.
- Scanner Wi‑Fi et être connecté en Wi‑Fi : possible, mais parfois un peu instable si on scanne trop souvent.
- SQLite + reset en live : supprimer la base pendant que des services la lisent/écrivent peut provoquer des erreurs I/O (donc on évite de “reset DB” en plein flux en prod).
Prochaines améliorations possibles
- Filtrer par SSID / chiffrement / canal
- Export CSV/JSON des données
- Mode “sessions de vol” (une session = un vol)
- Meilleure estimation de “portée” (modèle radio plus avancé, pas seulement heatmap)
- Matériel Wi‑Fi dédié (dongle) pour limiter les micro‑coupures si besoin
Conclusion
Ce projet donne une manière très visuelle de répondre à une question simple :
“Où est-ce que ça capte bien, et où est-ce que ça commence à décrocher ?”
Avec un Pi Zero, un GPS UART, une base SQLite et une interface web légère, on obtient une cartographie utile, réutilisable, et facilement extensible.