acid-drop- Hacking the planet from a LilyGo T-Deck using custom firmware |
git clone git://git.acid.vegas/acid-drop.git |
Log | Files | Refs | Archive | README | LICENSE |
PicoWiFiAnalyzerUTF8.ino (10433B)
1 /* 2 * Pico W WiFi Analyzer 3 * Require Raspberry Pi Pico W board support. 4 */ 5 6 #define SCAN_INTERVAL 3000 7 // #define SCAN_COUNT_SLEEP 3 8 9 /******************************************************************************* 10 * Start of Arduino_GFX setting 11 * 12 * Arduino_GFX try to find the settings depends on selected board in Arduino IDE 13 * Or you can define the display dev kit not in the board list 14 * Defalult pin list for non display dev kit: 15 * Arduino Nano, Micro and more: CS: 9, DC: 8, RST: 7, BL: 6, SCK: 13, MOSI: 11, MISO: 12 16 * ESP32 various dev board : CS: 5, DC: 27, RST: 33, BL: 22, SCK: 18, MOSI: 23, MISO: nil 17 * ESP32-C3 various dev board : CS: 7, DC: 2, RST: 1, BL: 3, SCK: 4, MOSI: 6, MISO: nil 18 * ESP32-S2 various dev board : CS: 34, DC: 38, RST: 33, BL: 21, SCK: 36, MOSI: 35, MISO: nil 19 * ESP32-S3 various dev board : CS: 40, DC: 41, RST: 42, BL: 48, SCK: 36, MOSI: 35, MISO: nil 20 * ESP8266 various dev board : CS: 15, DC: 4, RST: 2, BL: 5, SCK: 14, MOSI: 13, MISO: 12 21 * Raspberry Pi Pico dev board : CS: 17, DC: 27, RST: 26, BL: 28, SCK: 18, MOSI: 19, MISO: 16 22 * RTL8720 BW16 old patch core : CS: 18, DC: 17, RST: 2, BL: 23, SCK: 19, MOSI: 21, MISO: 20 23 * RTL8720_BW16 Official core : CS: 9, DC: 8, RST: 6, BL: 3, SCK: 10, MOSI: 12, MISO: 11 24 * RTL8722 dev board : CS: 18, DC: 17, RST: 22, BL: 23, SCK: 13, MOSI: 11, MISO: 12 25 * RTL8722_mini dev board : CS: 12, DC: 14, RST: 15, BL: 13, SCK: 11, MOSI: 9, MISO: 10 26 * Seeeduino XIAO dev board : CS: 3, DC: 2, RST: 1, BL: 0, SCK: 8, MOSI: 10, MISO: 9 27 * Teensy 4.1 dev board : CS: 39, DC: 41, RST: 40, BL: 22, SCK: 13, MOSI: 11, MISO: 12 28 ******************************************************************************/ 29 #include <U8g2lib.h> 30 #include <Arduino_GFX_Library.h> 31 32 #define GFX_BL DF_GFX_BL // default backlight pin, you may replace DF_GFX_BL to actual backlight pin 33 34 /* More dev device declaration: https://github.com/moononournation/Arduino_GFX/wiki/Dev-Device-Declaration */ 35 #if defined(DISPLAY_DEV_KIT) 36 Arduino_GFX *gfx = create_default_Arduino_GFX(); 37 #else /* !defined(DISPLAY_DEV_KIT) */ 38 39 /* More data bus class: https://github.com/moononournation/Arduino_GFX/wiki/Data-Bus-Class */ 40 Arduino_DataBus *bus = create_default_Arduino_DataBus(); 41 42 /* More display class: https://github.com/moononournation/Arduino_GFX/wiki/Display-Class */ 43 Arduino_GFX *gfx = new Arduino_ILI9341(bus, DF_GFX_RST, 3 /* rotation */, false /* IPS */); 44 45 #endif /* !defined(DISPLAY_DEV_KIT) */ 46 /******************************************************************************* 47 * End of Arduino_GFX setting 48 ******************************************************************************/ 49 50 #include "WiFi.h" 51 #define log_i(format, ...) Serial.printf(format, ##__VA_ARGS__) 52 53 int16_t w, h, text_size, banner_height, graph_baseline, graph_height, channel_width, signal_width; 54 55 // RSSI RANGE 56 #define RSSI_CEILING -40 57 #define RSSI_FLOOR -100 58 59 // Channel color mapping from channel 1 to 14 60 uint16_t channel_color[] = { 61 RED, ORANGE, YELLOW, GREEN, CYAN, BLUE, MAGENTA, 62 RED, ORANGE, YELLOW, GREEN, CYAN, BLUE, MAGENTA}; 63 64 uint8_t scan_count = 0; 65 66 void setup() 67 { 68 Serial.begin(115200); 69 // Serial.setDebugOutput(true); 70 // while(!Serial); 71 Serial.println("Pico WiFi Analyzer UTF8"); 72 73 #ifdef GFX_EXTRA_PRE_INIT 74 GFX_EXTRA_PRE_INIT(); 75 #endif 76 77 // Set WiFi to station mode and disconnect from an AP if it was previously connected 78 WiFi.mode(WIFI_STA); 79 WiFi.disconnect(); 80 delay(100); 81 82 #ifdef GFX_BL 83 pinMode(GFX_BL, OUTPUT); 84 digitalWrite(GFX_BL, HIGH); 85 #endif 86 87 // init LCD 88 gfx->begin(); 89 gfx->setUTF8Print(true); // enable UTF8 support for the Arduino print() function 90 gfx->setFont(u8g2_font_unifont_t_cjk); 91 92 w = gfx->width(); 93 h = gfx->height(); 94 text_size = (w < 224) ? 1 : 2; 95 banner_height = text_size * 16; 96 graph_baseline = h - (2 * 16); // minus 2 text lines 97 graph_height = graph_baseline - banner_height - (2 * 16); // minus 2 text lines 98 channel_width = w / 17; 99 signal_width = channel_width * 2; 100 101 // init banner 102 gfx->setTextSize(text_size); 103 gfx->fillScreen(BLACK); 104 gfx->setTextColor(MAGENTA); 105 gfx->setCursor(0, 28); 106 gfx->print("Pico W"); 107 gfx->setTextColor(WHITE); 108 gfx->print(" WiFi分析儀"); 109 } 110 111 bool matchBssidPrefix(uint8_t *a, uint8_t *b) 112 { 113 for (uint8_t i = 0; i < 5; i++) 114 { // only compare first 5 bytes 115 if (a[i] != b[i]) 116 { 117 return false; 118 } 119 } 120 return true; 121 } 122 123 void loop() 124 { 125 uint8_t ap_count_list[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; 126 int32_t noise_list[] = {RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR}; 127 int32_t peak_list[] = {RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR}; 128 int16_t peak_id_list[] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}; 129 int32_t channel; 130 int16_t idx; 131 int32_t rssi; 132 uint8_t bssidA[6]; 133 uint8_t bssidB[6]; 134 String ssid; 135 uint16_t color; 136 int16_t height, offset, text_width; 137 138 // WiFi.scanNetworks will return the number of networks found 139 int n = WiFi.scanNetworks(); 140 141 // clear old graph 142 gfx->fillRect(0, banner_height, w, h - banner_height, BLACK); 143 gfx->setTextSize(1); 144 145 if (n == 0) 146 { 147 gfx->setTextColor(WHITE); 148 gfx->setCursor(0, banner_height + 14); 149 gfx->println("找不到WiFi"); 150 } 151 else 152 { 153 for (int i = 0; i < n; i++) 154 { 155 channel = WiFi.channel(i); 156 idx = channel - 1; 157 rssi = WiFi.RSSI(i); 158 WiFi.BSSID(i, bssidA); 159 160 // channel peak stat 161 if (peak_list[idx] < rssi) 162 { 163 peak_list[idx] = rssi; 164 peak_id_list[idx] = i; 165 } 166 167 // check signal come from same AP 168 bool duplicate_SSID = false; 169 for (int j = 0; j < i; j++) 170 { 171 if ((WiFi.channel(j) == channel) && matchBssidPrefix(WiFi.BSSID(j, bssidB), bssidA)) 172 { 173 duplicate_SSID = true; 174 break; 175 } 176 } 177 178 if (!duplicate_SSID) 179 { 180 ap_count_list[idx]++; 181 182 // noise stat 183 int32_t noise = rssi - RSSI_FLOOR; 184 noise *= noise; 185 if (channel > 4) 186 { 187 noise_list[idx - 4] += noise; 188 } 189 if (channel > 3) 190 { 191 noise_list[idx - 3] += noise; 192 } 193 if (channel > 2) 194 { 195 noise_list[idx - 2] += noise; 196 } 197 if (channel > 1) 198 { 199 noise_list[idx - 1] += noise; 200 } 201 noise_list[idx] += noise; 202 if (channel < 14) 203 { 204 noise_list[idx + 1] += noise; 205 } 206 if (channel < 13) 207 { 208 noise_list[idx + 2] += noise; 209 } 210 if (channel < 12) 211 { 212 noise_list[idx + 3] += noise; 213 } 214 if (channel < 11) 215 { 216 noise_list[idx + 4] += noise; 217 } 218 } 219 } 220 221 // plot found WiFi info 222 for (int i = 0; i < n; i++) 223 { 224 channel = WiFi.channel(i); 225 idx = channel - 1; 226 rssi = WiFi.RSSI(i); 227 color = channel_color[idx]; 228 height = constrain(map(rssi, RSSI_FLOOR, RSSI_CEILING, 1, graph_height), 1, graph_height); 229 offset = (channel + 1) * channel_width; 230 231 // trim rssi with RSSI_FLOOR 232 if (rssi < RSSI_FLOOR) 233 { 234 rssi = RSSI_FLOOR; 235 } 236 237 // plot chart 238 // gfx->drawLine(offset, graph_baseline - height, offset - signal_width, graph_baseline + 1, color); 239 // gfx->drawLine(offset, graph_baseline - height, offset + signal_width, graph_baseline + 1, color); 240 gfx->startWrite(); 241 gfx->drawEllipseHelper(offset, graph_baseline + 1, signal_width, height, 0b0011, color); 242 gfx->endWrite(); 243 244 if (i == peak_id_list[idx]) 245 { 246 // Print SSID, signal strengh and if not encrypted 247 String ssid = WiFi.SSID(i); 248 if (ssid.length() == 0) 249 { 250 WiFi.BSSID(i, bssidA); 251 // bssidA to ssid 252 char mac[18] = {0}; 253 sprintf(mac, "%02X:%02X:%02X:%02X:%02X:%02X", bssidA[0], bssidA[1], bssidA[2], bssidA[3], bssidA[4], bssidA[5]); 254 ssid = String(mac); 255 } 256 text_width = (ssid.length() + 6) * 8; 257 if (text_width > w) 258 { 259 offset = 0; 260 } 261 else 262 { 263 offset -= signal_width; 264 if ((offset + text_width) > w) 265 { 266 offset = w - text_width; 267 } 268 } 269 gfx->setTextColor(color); 270 gfx->setCursor(offset, graph_baseline - height - 2); 271 gfx->print(ssid); 272 gfx->print('('); 273 gfx->print(rssi); 274 gfx->print(')'); 275 if (WiFi.encryptionType(i) == ENC_TYPE_NONE) 276 { 277 gfx->print('*'); 278 } 279 } 280 } 281 } 282 283 // print WiFi stat 284 gfx->setTextColor(WHITE); 285 gfx->setCursor(0, banner_height + 14); 286 gfx->print("找到"); 287 gfx->print(n); 288 gfx->print("個WiFi,訊噪比較好:"); 289 bool listed_first_channel = false; 290 int32_t min_noise = noise_list[0]; // init with channel 1 value 291 for (channel = 2; channel <= 11; channel++) // channels 12-14 may not available 292 { 293 idx = channel - 1; 294 log_i("min_noise: %d, noise_list[%d]: %d", min_noise, idx, noise_list[idx]); 295 if (noise_list[idx] < min_noise) 296 { 297 min_noise = noise_list[idx]; 298 } 299 } 300 301 for (channel = 1; channel <= 11; channel++) // channels 12-14 may not available 302 { 303 idx = channel - 1; 304 // check channel with min noise 305 if (noise_list[idx] == min_noise) 306 { 307 if (!listed_first_channel) 308 { 309 listed_first_channel = true; 310 } 311 else 312 { 313 gfx->print(", "); 314 } 315 gfx->print(channel); 316 } 317 } 318 319 // draw graph base axle 320 gfx->drawFastHLine(0, graph_baseline, 320, WHITE); 321 for (channel = 1; channel <= 14; channel++) 322 { 323 idx = channel - 1; 324 offset = (channel + 1) * channel_width; 325 gfx->setTextColor(channel_color[idx]); 326 gfx->setCursor(offset - ((channel < 10) ? 4 : 8), graph_baseline + 14); 327 gfx->print(channel); 328 if (ap_count_list[idx] > 0) 329 { 330 gfx->setCursor(offset - ((ap_count_list[idx] < 10) ? 12 : 16), graph_baseline + 16 + 14); 331 gfx->print('{'); 332 gfx->print(ap_count_list[idx]); 333 gfx->print('}'); 334 } 335 } 336 337 // Wait a bit before scanning again 338 delay(SCAN_INTERVAL); 339 }