====== Wifi Analyzer Software ======
Aug 2026
\\
\\
{{ :micro-python.png?100 |}}
Back to [[pico_wifi_analyzer_-_phase_1|Pico Wifi Analyzer Phase 1]]
----
===== Introduction =====
\\
When you did the section where you connected up the LCD to the Pico, there was some simple test Python scripts to see that the LCD works. Also, you have tested your Wifi connection to see that you can talk to your router. Remember, the Pico only supports 2.4Ghz Wifi.
\\
\\
Here is the Python code you need to save to your Pico. To start, I would just copy this code in to Thonny and run it from there.
# ----------------------------------------------------
# Wifi Analyzer
# Scans Wifi SSIDs every 15 minutes to keep track of
# current Wifi status.
# Alan Walker & CoPilot
# 19/08/2026
# ----------------------------------------------------
from machine import Pin, I2C
import ssd1306
import time
import network
import socket
# ----------------------------------------------------
# OLED Setup
# ----------------------------------------------------
i2c = I2C(0, scl=Pin(5), sda=Pin(4), freq=200000)
lcd = ssd1306.SSD1306_I2C(128, 64, i2c)
# ----------------------------------------------------
# Manual Button (GP16)
# ----------------------------------------------------
button = Pin(16, Pin.IN, Pin.PULL_UP) # active-low
# ----------------------------------------------------
# Onboard LED (Pico 2 W)
# ----------------------------------------------------
led = Pin("LED", Pin.OUT)
# Global WiFi status (updated after each scan)
wifi_ok = True
# ----------------------------------------------------
# LED Controller (continuous blink if ANY SSID down)
# ----------------------------------------------------
def update_led():
global wifi_ok
if wifi_ok:
led.value(1) # solid ON
else:
# continuous blink (non-blocking)
led.value(1)
time.sleep(0.15)
led.value(0)
time.sleep(0.15)
# ----------------------------------------------------
# UI Renderer
# ----------------------------------------------------
def draw_ui(header="WiFi Analyzer", last="--:--",
linksys="------", draytek="------",
status="Idle", next_scan="--m"):
lcd.fill(0)
lcd.text(header, 0, 0)
lcd.text("Last: " + last, 0, 8)
lcd.text("Linksys: " + linksys, 0, 24)
lcd.text("Draytek: " + draytek, 0, 32)
lcd.text("Status: " + status, 0, 48)
lcd.text("Next: " + next_scan, 0, 56)
lcd.show()
# ----------------------------------------------------
# Scanning Animation
# ----------------------------------------------------
def animate_scanning():
frames = ["Scanning.", "Scanning..", "Scanning..."]
for frame in frames:
draw_ui(status=frame)
update_led()
time.sleep(0.3)
# ----------------------------------------------------
# WiFi Test Engine
# ----------------------------------------------------
def test_network(ssid, password):
print("Trying:", ssid)
wlan = network.WLAN(network.STA_IF)
wlan.active(False)
time.sleep(0.2)
wlan.active(True)
wlan.connect(ssid, password)
for _ in range(20):
if wlan.isconnected():
break
time.sleep(0.5)
if not wlan.isconnected():
return False
try:
socket.getaddrinfo("google.com", 80)
return True
except:
return False
# ----------------------------------------------------
# Test SSIDs
# ----------------------------------------------------
networks = [
("SSID1", "YOUR-SSID-PASSWORD"),
("SSID2", "YOUR-SSID-PASSWORD")
]
# ----------------------------------------------------
# Rolling History
# ----------------------------------------------------
history = {
"Linksys": [],
"Draytek": []
}
# ----------------------------------------------------
# Startup Scan
# ----------------------------------------------------
animate_scanning()
print("Starting WiFi scan...")
time.sleep(1)
results = []
for ssid, pw in networks:
ok = test_network(ssid, pw)
results.append(ok)
# Update global WiFi status
wifi_ok = all(results)
linksys_status = "1" if results[0] else "x"
draytek_status = "1" if results[1] else "x"
history["Linksys"].append(linksys_status)
history["Draytek"].append(draytek_status)
if len(history["Linksys"]) > 5:
history["Linksys"].pop(0)
if len(history["Draytek"]) > 5:
history["Draytek"].pop(0)
# ----------------------------------------------------
# Time Sync
# ----------------------------------------------------
if any(results):
try:
import ntptime
ntptime.settime()
now = time.localtime(time.time() + 3600)
except:
now = time.localtime()
else:
now = time.localtime()
network.WLAN(network.STA_IF).disconnect()
timestamp = "{:02d}:{:02d}".format(now[3], now[4])
linksys_hist = "".join(history["Linksys"])
draytek_hist = "".join(history["Draytek"])
draw_ui(
last=timestamp,
linksys=linksys_hist,
draytek=draytek_hist,
status="Done",
next_scan="15m"
)
# ----------------------------------------------------
# Auto-scan loop
# ----------------------------------------------------
next_scan_seconds = 900
scanning_in_progress = False
while True:
for _ in range(600): # 60 seconds
update_led() # LED continues blinking if needed
if not scanning_in_progress and not button.value():
scanning_in_progress = True
animate_scanning()
print("Manual scan starting...")
results = []
for ssid, pw in networks:
ok = test_network(ssid, pw)
results.append(ok)
wifi_ok = all(results)
linksys_status = "1" if results[0] else "x"
draytek_status = "1" if results[1] else "x"
history["Linksys"].append(linksys_status)
history["Draytek"].append(draytek_status)
if len(history["Linksys"]) > 5:
history["Linksys"].pop(0)
if len(history["Draytek"]) > 5:
history["Draytek"].pop(0)
if any(results):
try:
import ntptime
ntptime.settime()
now = time.localtime(time.time() + 3600)
except:
now = time.localtime()
else:
now = time.localtime()
network.WLAN(network.STA_IF).disconnect()
timestamp = "{:02d}:{:02d}".format(now[3], now[4])
linksys_hist = "".join(history["Linksys"])
draytek_hist = "".join(history["Draytek"])
draw_ui(
last=timestamp,
linksys=linksys_hist,
draytek=draytek_hist,
status="Done",
next_scan=f"{next_scan_seconds // 60}m"
)
scanning_in_progress = False
time.sleep(0.3)
time.sleep(0.1)
next_scan_seconds -= 60
update_led()
mins = next_scan_seconds // 60
draw_ui(
last=timestamp,
linksys=linksys_hist,
draytek=draytek_hist,
status="Done",
next_scan=f"{mins}m"
)
if next_scan_seconds <= 0:
scanning_in_progress = True
animate_scanning()
print("Auto-scan starting...")
results = []
for ssid, pw in networks:
ok = test_network(ssid, pw)
results.append(ok)
wifi_ok = all(results)
linksys_status = "1" if results[0] else "x"
draytek_status = "1" if results[1] else "x"
history["Linksys"].append(linksys_status)
history["Draytek"].append(draytek_status)
if len(history["Linksys"]) > 5:
history["Linksys"].pop(0)
if len(history["Draytek"]) > 5:
history["Draytek"].pop(0)
if any(results):
try:
import ntptime
ntptime.settime()
now = time.localtime(time.time() + 3600)
except:
now = time.localtime()
else:
now = time.localtime()
network.WLAN(network.STA_IF).disconnect()
timestamp = "{:02d}:{:02d}".format(now[3], now[4])
linksys_hist = "".join(history["Linksys"])
draytek_hist = "".join(history["Draytek"])
draw_ui(
last=timestamp,
linksys=linksys_hist,
draytek=draytek_hist,
status="Done",
next_scan="15m"
)
next_scan_seconds = 900
scanning_in_progress = False