This example demonstrates how to scan for surrounding WiFi networks on the ESP32‑WROOM‑32E development board and display the results in a table format on the TFT LCD screen. The program lists the SSID, RSSI (signal strength), channel, and encryption type of each detected WiFi network, allowing users to quickly understand the wireless network environment. This example is suitable for WiFi network diagnostics, signal strength testing, and wireless network environment analysis.
Hardware prerequisite: The screen uses an ILI9341 SPI display in landscape mode (320×240).
Wifi_scan_test.ino filemy_lcd.setRotation(1))1 | MyHome_WiFi | -45dB | 6 | WPA2
2 | Office_5G | -58dB | 11 | WPA2
3 | Guest_Network | -72dB | 1 | OPEN
The TFT screen (landscape 320×240) displays WiFi scan results in a table:
| Column | Position | Description |
|---|---|---|
| Nr | x=10 | Network index (starting from 1) |
| SSID | x=32 | WiFi network name (max 30 characters) |
| RSSI | x=184 | Signal strength (dBm), closer to 0 means stronger signal |
| CH | x=238 | Channel number (1~13) |
| ENC_TYPE | x=267 | Encryption type (OPEN/WEP/WPA/WPA2/WPA3 etc.) |
Screen layout (top to bottom):
| Area | Y Coordinate | Description |
|---|---|---|
| Network count | y=3 | Shows number of networks found (e.g., "5 networks found") |
| Table header | y=15 | Shows column headers ("Nr |
| Data rows | y=30+ | Each row shows one WiFi network, 12px row spacing |
| Max rows | - | Up to 17 rows (extra networks are not displayed) |
⚠️ Key Notes:
WiFi.disconnect() is called before scanning to disconnect any existing WiFi connections, ensuring interference‑free scanningWIFI_STA (Station mode), which is required for scanningWiFi.scanDelete()This example code is based on the ESP32‑WROOM‑32E development board. The program implements WiFi network scanning, result display, and loop scanning, with the core function being WiFi.scanNetworks() to obtain the list of surrounding WiFi networks.
#include <TFT_eSPI.h>
#include "WiFi.h"
char wifi_name[40]; // Store WiFi name (SSID)
char wifi_rssi[6]; // Store WiFi signal strength (RSSI)
char wifi_enc[10]; // Store WiFi encryption type
TFT_eSPI my_lcd = TFT_eSPI();
TFT_eSPI.h: TFT screen driver library for graphics and textWiFi.h: ESP32 WiFi library providing network scanning, connection, etc.wifi_name[40]: Character array for WiFi SSID (max 40 chars)wifi_rssi[6]: Character array for RSSI string (e.g., "-45dB", max 6 chars)wifi_enc[10]: Character array for encryption type string (e.g., "WPA2", max 10 chars)my_lcd: TFT screen object for display operationsvoid setup()
{
my_lcd.begin();
my_lcd.setRotation(1);
WiFi.mode(WIFI_STA);
WiFi.disconnect();
delay(100);
}
my_lcd.begin(): Initializes TFT screen hardwaremy_lcd.setRotation(1): Sets screen to landscape mode (320×240) for table displayWiFi.mode(WIFI_STA): Sets WiFi to Station mode. Note: WiFi scanning requires STA modeWiFi.disconnect(): Disconnects any previous WiFi connections for clean scanningdelay(100): Brief delay for WiFi module to stabilise💡 Knowledge Point:
WiFi.mode(WIFI_STA)is a prerequisite for WiFi scanning. If set toWIFI_APorWIFI_OFFmode, scanning will not work.
The loop() function implements WiFi scanning, result display, and loop scanning.
my_lcd.fillScreen(TFT_WHITE);
my_lcd.setTextColor(TFT_RED);
my_lcd.setFreeFont(&FreeSans12pt7b);
my_lcd.drawString("WIFI Scan Start", 70, 114);
my_lcd.fillScreen(TFT_WHITE): Clears screen with white backgroundmy_lcd.setTextColor(TFT_RED): Sets text colour to redmy_lcd.setFreeFont(&FreeSans12pt7b): Sets large bold fontmy_lcd.drawString("WIFI Scan Start", 70, 114): Displays scan start prompt at centreint network_cnt = WiFi.scanNetworks();
WiFi.scanNetworks(): Core function – scans surrounding WiFi networksnetwork_cnt: Number of networks found💡 Knowledge Point:
WiFi.scanNetworks()returns an integer indicating the number of networks found. Returns 0 if none found, negative if error (e.g., -1 indicates scan failure).
my_lcd.setTextColor(TFT_BLUE);
my_lcd.fillRect(0, 110, my_lcd.width()-1, 40, TFT_WHITE);
my_lcd.drawString("WIFI Scan Done!", 70, 114);
delay(500);
my_lcd.fillRect(0, 110, my_lcd.width()-1, 40, TFT_WHITE): Erases previous text with white rectanglemy_lcd.drawString("WIFI Scan Done!", 70, 114): Displays scan complete prompt (blue)delay(500): Brief 0.5 second pause for user to see the promptmy_lcd.fillScreen(TFT_WHITE);
my_lcd.setTextColor(TFT_RED);
my_lcd.setTextFont(1);
my_lcd.fillScreen(TFT_WHITE): Clears screen for result displaymy_lcd.setTextColor(TFT_RED): Sets text colour to redmy_lcd.setTextFont(1): Uses default font (suitable for table data)if (network_cnt == 0)
{
my_lcd.drawString("no wifi networks found!", 5, 0);
}
else
{
my_lcd.drawNumber(network_cnt, 5, 3);
my_lcd.drawString("networks found", 21, 3);
// ... display table
}
network_cnt == 0: No WiFi networks found – displays "no wifi networks found!"network_cnt > 0: At least one network found
my_lcd.drawNumber(network_cnt, 5, 3): Displays network count as numbermy_lcd.drawString("networks found", 21, 3): Displays "networks found" textmy_lcd.setTextColor(TFT_BLUE);
my_lcd.drawString(" Nr | SSID | RSSI | CH | ENC_TYPE", 2, 15);
my_lcd.setTextColor(TFT_BLUE): Blue for table headermy_lcd.drawString(...): Displays table header row
int wifi_info_show = (network_cnt > 17 ? 17 : network_cnt);
for (int i = 0; i < wifi_info_show; ++i)
{
my_lcd.drawNumber(i + 1, 10, 30 + i * 12); // Display index
sprintf(wifi_name, "%-30s", WiFi.SSID(i).c_str()); // Get SSID
my_lcd.drawString(wifi_name, 32, 30 + i * 12);
sprintf(wifi_rssi, "%4ddB", WiFi.RSSI(i)); // Get RSSI
my_lcd.drawString(wifi_rssi, 184, 30 + i * 12);
my_lcd.drawNumber(WiFi.channel(i), 238, 30 + i * 12); // Get channel
// ... get encryption type
}
Key Function Reference:
| Function | Description |
|---|---|
WiFi.SSID(i) |
Gets the SSID of the i‑th network, returns String |
WiFi.RSSI(i) |
Gets the RSSI (dBm) of the i‑th network, returns int |
WiFi.channel(i) |
Gets the channel number of the i‑th network, returns int |
WiFi.encryptionType(i) |
Gets the encryption type of the i‑th network, returns wifi_auth_mode_t enum |
Maximum Display Calculation:
int wifi_info_show = (network_cnt > 17 ? 17 : network_cnt);
(240 - 30) / 12 ≈ 17switch (WiFi.encryptionType(i))
{
case WIFI_AUTH_OPEN:
sprintf(wifi_enc, "%s", "OPEN");
break;
case WIFI_AUTH_WEP:
sprintf(wifi_enc, "%s", "WEP");
break;
case WIFI_AUTH_WPA_PSK:
sprintf(wifi_enc, "%s", "WPA");
break;
case WIFI_AUTH_WPA2_PSK:
sprintf(wifi_enc, "%s", "WPA2");
break;
case WIFI_AUTH_WPA_WPA2_PSK:
sprintf(wifi_enc, "%s", "WPA+WPA2");
break;
case WIFI_AUTH_WPA2_ENTERPRISE:
sprintf(wifi_enc, "%s", "WPA2-EAP");
break;
case WIFI_AUTH_WPA3_PSK:
sprintf(wifi_enc, "%s", "WPA3");
break;
case WIFI_AUTH_WPA2_WPA3_PSK:
sprintf(wifi_enc, "%s", "WPA2+WPA3");
break;
case WIFI_AUTH_WAPI_PSK:
sprintf(wifi_enc, "%s", "WAPI");
break;
default:
sprintf(wifi_enc, "%s", "unknown");
}
my_lcd.drawString(wifi_enc, 267, 30 + i * 12);
Encryption Type Reference:
| Enum Value | Display Name | Description |
|---|---|---|
WIFI_AUTH_OPEN |
OPEN | Open network (no password) |
WIFI_AUTH_WEP |
WEP | WEP encryption (old, insecure) |
WIFI_AUTH_WPA_PSK |
WPA | WPA Personal |
WIFI_AUTH_WPA2_PSK |
WPA2 | WPA2 Personal (most common) |
WIFI_AUTH_WPA_WPA2_PSK |
WPA+WPA2 | Mixed mode |
WIFI_AUTH_WPA2_ENTERPRISE |
WPA2-EAP | WPA2 Enterprise (requires authentication server) |
WIFI_AUTH_WPA3_PSK |
WPA3 | WPA3 Personal (latest) |
WIFI_AUTH_WPA2_WPA3_PSK |
WPA2+WPA3 | WPA2/WPA3 mixed mode |
WIFI_AUTH_WAPI_PSK |
WAPI | Chinese wireless LAN security standard |
WiFi.scanDelete();
delay(5000);
my_lcd.fillScreen(TFT_WHITE);
WiFi.scanDelete(): Important – Deletes scan results and frees memory. Without this, each scan accumulates memory usage and may lead to insufficient memorydelay(5000): 5 second pause for user to view resultsmy_lcd.fillScreen(TFT_WHITE): Clears screen for next scan (loop)💡 Knowledge Point:
WiFi.scanDelete()must be paired withWiFi.scanNetworks(). After each scan, results are stored in memory; callingscanDelete()frees this memory. Forgetting to call it can cause memory leaks after repeated scans.
This example program implements complete WiFi network scanning and display:
WiFi.scanNetworks() to get list of surrounding WiFi networksWiFi.scanDelete() to free memoryKey functions:
WiFi.mode(WIFI_STA): Sets WiFi to station mode (required for scanning)WiFi.disconnect(): Disconnects existing connections for clean scanningWiFi.scanNetworks(): Performs network scan, returns network countWiFi.SSID(i): Gets the SSID of the i‑th networkWiFi.RSSI(i): Gets the RSSI of the i‑th networkWiFi.channel(i): Gets the channel number of the i‑th networkWiFi.encryptionType(i): Gets the encryption type of the i‑th networkWiFi.scanDelete(): Deletes scan results, frees memorymy_lcd.drawString(): Displays text on screenmy_lcd.drawNumber(): Displays numbers on screensprintf(): Formats stringsmy_lcd.setRotation(1); // 0:portrait, 1:landscape, 2:portrait flipped, 3:landscape flipped
If changing to portrait (0), table layout coordinates need adjustment.
my_lcd.setFreeFont(&FreeSans12pt7b); // Large font for scan prompts
my_lcd.setTextFont(1); // Small font for table data
Available fonts:
FreeSans9pt7b (9pt)FreeSans12pt7b (12pt)FreeSans18pt7b (18pt)FreeSans24pt7b (24pt)int wifi_info_show = (network_cnt > 20 ? 20 : network_cnt); // Display 20 networks
Ensure sufficient screen space when modifying (12px per row).
ESP32 WiFi scan timeout can be adjusted:
WiFi.scanNetworks(true); // Async scan mode
Or use WiFi.scanNetworks(true, true) for active scan.
delay(5000); // Change to other value (in milliseconds)
Display different colours based on RSSI:
int rssi = WiFi.RSSI(i);
if (rssi > -50) {
my_lcd.setTextColor(TFT_GREEN); // Strong signal
} else if (rssi > -70) {
my_lcd.setTextColor(TFT_YELLOW); // Medium signal
} else {
my_lcd.setTextColor(TFT_RED); // Weak signal
}
Add conditions to display only specific SSIDs:
String ssid = WiFi.SSID(i);
if (ssid.startsWith("MyHome")) {
// Only display networks starting with "MyHome"
}
Can also display BSSID (MAC address):
String bssid = WiFi.BSSIDstr(i);
// Display bssid on screen
No display or garbled screen
User_Setup.h is configured for ILI9341No scan results (no WiFi found)
WiFi.mode(WIFI_STA))Incomplete scan results or garbled text
sprintf buffer sizes are sufficientProgram hangs at scan step
WiFi.scanNetworks() is synchronous – program blocks during scanOut of memory errors
WiFi.scanDelete() is called correctlyscanDelete() after each scan to free memoryScreen text overlap
my_lcd.fillRect() to erase old text before writing newmy_lcd.fillScreen(TFT_WHITE) clears the entire screenCompilation error: cannot find FreeSans font
User_Setup.hmy_lcd.setTextFont(2))