-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathesp32-gps-wifi-wigle.ino
235 lines (209 loc) · 7.06 KB
/
esp32-gps-wifi-wigle.ino
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
#include <TinyGPSPlus.h>
#include <HardwareSerial.h>
#include <WiFi.h>
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <SD.h>
#include <time.h>
#include <RTClib.h>
// RTC setup
RTC_Millis rtc;
// Pin definitions for GPS module
static const int RXPin = 16, TXPin = 17;
static const uint32_t GPSBaud = 9600; // GPS module baud rate
// OLED display setup
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
#define SD_CS_PIN 5 // Chip select pin for SD card
#define MIN_SATELLITES 4 // Minimum number of satellites for a valid GPS fix
#define PST_OFFSET -8 // PST is UTC-8
// Objects for GPS, serial communication, display, and SD card
TinyGPSPlus gps;
HardwareSerial gpsSerial(1);
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
File csvFile;
// Counters for WiFi scans and networks found
int scanCount = 0;
int networkCount = 0;
void setup() {
Serial.begin(115200); // Start serial communication for debugging
gpsSerial.begin(GPSBaud, SERIAL_8N1, RXPin, TXPin); // Start GPS serial communication
delay(5000); // Allow time for the system to stabilize
// Initialize OLED display
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println(F("SSD1306 allocation failed"));
for (;;); // Infinite loop if display initialization fails
}
display.display();
delay(2000);
display.clearDisplay();
// Initialize SD card
if (!SD.begin(SD_CS_PIN)) {
Serial.println("Card failed, or not present");
displayError("SD Card Error");
return;
}
// Initialize CSV file
if (!initializeCSV()) {
displayError("CSV Init Error");
return;
}
rtc.begin(DateTime(F(__DATE__), F(__TIME__))); // Initialize RTC with compile time
Serial.println(F("GPS and WiFi Scanner"));
}
void loop() {
// Read GPS data
while (gpsSerial.available() > 0) {
gps.encode(gpsSerial.read());
}
// Check if GPS data is valid
if (gps.location.isValid() && gps.hdop.isValid() && gps.date.isValid() && gps.time.isValid() && gps.satellites.value() >= MIN_SATELLITES) {
// Update RTC with GPS time
DateTime gpsTime(gps.date.year(), gps.date.month(), gps.date.day(), gps.time.hour(), gps.time.minute(), gps.time.second());
rtc.adjust(gpsTime);
// Display GPS data and scan for WiFi networks
displayGPSData();
scanWiFiNetworks();
displayGPSData();
delay(15000); // Wait 15 seconds before next scan
} else {
displaySearching();
}
}
// Display GPS data on the OLED screen
void displayGPSData() {
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 0);
display.print("Lat: ");
display.println(gps.location.lat(), 6);
display.print("Lng: ");
display.println(gps.location.lng(), 6);
display.print("Alt: ");
display.println(gps.altitude.meters());
display.print("Sat: ");
display.println(gps.satellites.value());
// Get the current time from RTC and display it
DateTime now = rtc.now();
char buffer[30];
snprintf(buffer, sizeof(buffer), "%04d-%02d-%02d %02d:%02d:%02d", now.year(), now.month(), now.day(), now.hour(), now.minute(), now.second());
display.print("Time: ");
display.println(buffer);
// Display the number of networks found and scan count
display.print("Nets: ");
display.println(networkCount);
display.print("Scans: ");
display.println(scanCount);
display.display();
}
// Display a message while searching for GPS signal
void displaySearching() {
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 0);
display.println("Searching for GPS...");
display.print("Satellites: ");
display.println(gps.satellites.value());
display.display();
}
// Display an error message on the OLED screen
void displayError(const char* error) {
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 0);
display.println(error);
display.display();
}
// Initialize a new CSV file for storing WiFi scan results
bool initializeCSV() {
DateTime now = rtc.now();
char filename[32];
snprintf(filename, sizeof(filename), "/wigle_%04d%02d%02d_%02d%02d%02d.csv", now.year(), now.month(), now.day(), now.hour(), now.minute(), now.second());
csvFile = SD.open(filename, FILE_WRITE);
if (csvFile) {
csvFile.println("BSSID,SSID,Capabilities,First timestamp seen,Channel,Frequency,RSSI,Latitude,Longitude,Altitude,Accuracy,RCOIs,MfgrId,Type");
csvFile.close();
return true;
}
return false;
}
// Scan for WiFi networks and store results in the CSV file
void scanWiFiNetworks() {
networkCount = WiFi.scanNetworks(); // Scan for WiFi networks
scanCount++; // Increment scan count
csvFile = SD.open("/wigle.csv", FILE_APPEND);
if (csvFile) {
for (int i = 0; i < networkCount; ++i) {
writeNetworkData(i);
}
csvFile.close();
} else {
displayError("CSV Write Error");
}
// Print networks to serial monitor
Serial.print("Scan #");
Serial.println(scanCount);
Serial.print("Networks found: ");
Serial.println(networkCount);
for (int i = 0; i < networkCount; ++i) {
Serial.print("Network #");
Serial.print(i + 1);
Serial.print(": ");
Serial.print(WiFi.SSID(i));
Serial.print(" (");
Serial.print(WiFi.RSSI(i));
Serial.println(" dBm)");
}
}
// Write network data to the CSV file
void writeNetworkData(int networkIndex) {
String bssid = WiFi.BSSIDstr(networkIndex);
String ssid = WiFi.SSID(networkIndex);
String capabilities = WiFi.encryptionType(networkIndex) == WIFI_AUTH_OPEN ? "Open" : "Secured";
String timestamp = getLocalTimestamp();
int channel = WiFi.channel(networkIndex);
int frequency = 2400 + (channel - 1) * 5; // Assuming 2.4GHz WiFi
int rssi = WiFi.RSSI(networkIndex);
String latitude = String(gps.location.lat(), 6);
String longitude = String(gps.location.lng(), 6);
String altitude = String(gps.altitude.meters());
String accuracy = String(gps.hdop.hdop());
String rcois = ""; // Placeholder if RCOIs is not available
String mfgrid = ""; // Placeholder if Manufacturer ID is not available
String type = "WiFi";
// Write network data to CSV file
csvFile.print("\"" + bssid + "\",");
csvFile.print("\"" + ssid + "\",");
csvFile.print("\"" + capabilities + "\",");
csvFile.print("\"" + timestamp + "\",");
csvFile.print(channel);
csvFile.print(",");
csvFile.print(frequency);
csvFile.print(",");
csvFile.print(rssi);
csvFile.print(",");
csvFile.print(latitude);
csvFile.print(",");
csvFile.print(longitude);
csvFile.print(",");
csvFile.print(altitude);
csvFile.print(",");
csvFile.print(accuracy);
csvFile.print(",");
csvFile.print("\"" + rcois + "\",");
csvFile.print("\"" + mfgrid + "\",");
csvFile.println("\"" + type + "\"");
}
// Get the current timestamp from the RTC
String getLocalTimestamp() {
DateTime now = rtc.now(); // Use RTC time for timestamp
char buffer[30];
snprintf(buffer, sizeof(buffer), "%04d-%02d-%02d %02d:%02d:%02d", now.year(), now.month(), now.day(), now.hour(), now.minute(), now.second());
return String(buffer);
}