Wi-Fi連上了,
為何資料還是送不到?
ESP32 顯示 WL_CONNECTED,只代表它已經加入無線基地台,不代表資料已抵達 Django。真正的連線,要連續通過「Wi-Fi → IP → Gateway → DNS → TCP/TLS → HTTP → 應用程式」七道關卡。
一、先破解最常見的誤會
「連上 Wi-Fi」是第一關成功;只要後面任何一層失敗,Django 儀表板仍然看不到資料。
診斷原則:不要一看到「資料沒上傳」就立刻改程式。由下往上逐層驗證,先找到第一個失敗點。
二、Wi-Fi連線只證明了什麼?
已經證明
SSID、密碼與無線訊號大致可用;ESP32 已與基地台完成關聯。
還沒證明
是否取得正確 IP、Subnet、Gateway、DNS,網路是否能通往外部。
更沒證明
Django 網址、Port、憑證、API 路徑、權杖、JSON 格式與資料庫都正確。
先把 ESP32 的網路身分印出來
#include <WiFi.h>
void printNetworkInfo() {
Serial.println("=== NETWORK INFO ===");
Serial.print("SSID: "); Serial.println(WiFi.SSID());
Serial.print("IP: "); Serial.println(WiFi.localIP());
Serial.print("Subnet: "); Serial.println(WiFi.subnetMask());
Serial.print("Gateway: "); Serial.println(WiFi.gatewayIP());
Serial.print("DNS: "); Serial.println(WiFi.dnsIP());
Serial.print("RSSI: "); Serial.println(WiFi.RSSI());
}
若 IP 是 0.0.0.0,表示尚未完成網路配置;若是 169.254.x.x,通常代表 DHCP 沒有成功提供位址。RSSI 約 -30 dBm 很強、-67 dBm 尚可,低於 -75 dBm 時傳輸容易不穩。
三、從區域網路到 Django:封包實際走哪裡?
| 關卡 | 封包需要知道 | 常見失敗 |
|---|---|---|
| Wi-Fi | SSID、密碼、訊號 | 密碼錯、2.4/5 GHz 不相容、訊號弱 |
| IP/Subnet | 本機 IP 與同網段判斷 | DHCP 失敗、固定 IP 衝突、Subnet 設錯 |
| Gateway/NAT | 跨網段的下一跳 | Gateway 錯、訪客網路隔離、路由器無外網 |
| DNS | 網域名稱對應的 IP | DNS 未配置、解析失敗、網址拼錯 |
| TCP/TLS | 目標 Port 與安全連線 | Port 關閉、防火牆阻擋、時間或憑證錯誤 |
| HTTP | Method、URL、Header、Body | POST/GET 用錯、路徑錯、JSON 或 Content-Type 錯 |
| Django | 路由、驗證、資料模型 | 404、403、CSRF、500、欄位驗證失敗 |
四、七層診斷法:先找第一個失敗點
① 無線層
狀態WiFi.status() == WL_CONNECTED
訊號觀察 RSSI 是否持續過低或大幅波動。
② IP 配置層
確認 IP、Subnet、Gateway、DNS 不是空值;檢查固定 IP 是否與其他設備重複。
③ 本地網路層
用同一 Wi-Fi 的電腦或手機測試 Router 與區網伺服器。若訪客 Wi-Fi 開啟 Client Isolation,設備彼此可能不能連線。
④ DNS 層
先用 IP 測,再用網域測。IP 可通、網域不通,問題多半在 DNS;不要把 https:// 一起當作主機名稱解析。
⑤ TCP/TLS 層
確認 Port:HTTP 常用 80,HTTPS 常用 443。HTTPS 還要檢查 ESP32 時間、CA 憑證與 TLS 相容性。
⑥ HTTP 層
序列埠必須印出完整 URL、HTTP 回應碼與回應內容。只有「send failed」不足以定位問題。
⑦ Django 應用層
同步查看伺服器 log。請求有進來但回 4xx/5xx,代表網路大致已通,問題已經移到 API 或程式端。
⑧ 儀表板與資料庫
API 回 200/201 仍未顯示時,檢查資料是否真正寫入、查詢條件、時區、快取與前端刷新。
五、HTTP回應碼就是伺服器留下的線索
| 回應 | 代表意義 | 優先檢查 |
|---|---|---|
200 OK/201 Created | 請求成功或資料已建立 | 若畫面仍沒資料,檢查資料庫與前端查詢 |
301/302 | 網址被重新導向 | HTTP→HTTPS、尾端斜線、網域設定 |
400 Bad Request | 請求內容無法解析 | JSON、必填欄位、資料型別 |
401/403 | 身分驗證或權限失敗 | API Key、Token、CSRF、權限 |
404 Not Found | 找不到 API 路徑 | Django urls.py、版本路徑、尾斜線 |
405 Method Not Allowed | HTTP 方法不被接受 | 伺服器要 POST,裝置卻送 GET |
415 Unsupported Media Type | 資料格式宣告不符 | Content-Type: application/json |
500/502/503 | 應用程式或伺服器端異常 | Django log、反向代理、服務狀態 |
-1 或連線逾時 | 常是 HTTP 之前就失敗 | DNS、TCP、TLS、Port、防火牆 |
六、ESP32上傳時,至少留下這些診斷資訊
#include <HTTPClient.h>
void postEvent(const String& json) {
const char* url = "https://example.org/api/events/";
HTTPClient http;
Serial.print("POST URL: "); Serial.println(url);
Serial.print("WiFi RSSI: "); Serial.println(WiFi.RSSI());
if (!http.begin(url)) {
Serial.println("HTTP begin failed");
return;
}
http.addHeader("Content-Type", "application/json");
int code = http.POST(json);
Serial.print("HTTP code: "); Serial.println(code);
if (code > 0) {
Serial.print("Response: "); Serial.println(http.getString());
} else {
Serial.print("Transport error: ");
Serial.println(http.errorToString(code));
}
http.end();
}
上例用 example.org 作教材占位網址。實際部署 HTTPS 時,應依函式庫版本正確設定 CA 憑證與系統時間;不要為了省事而長期停用憑證驗證。
event_uuid,失敗時先保存,恢復連線後再重送;伺服器依 UUID 去除重複資料。七、最有效率的交叉測試
| 測試結果 | 可推論的範圍 |
|---|---|
| 手機使用同一 Wi-Fi 也打不開 API | 先查 Router、DNS、伺服器或 API,不急著改 ESP32 |
| 手機可用,ESP32 不行 | 查 ESP32 的 DNS、TLS、時間、憑證、記憶體與程式 |
| 用 IP 可連,用網域不行 | DNS 解析問題 |
| HTTP 可用,HTTPS 不行 | TLS、CA 憑證、系統時間或 SNI |
| API 收得到,但回 400/403/404 | 網路已走到應用層,查 Header、Token、路徑與資料格式 |
| API 回 201,但儀表板沒顯示 | 查資料庫、查詢條件、時區與前端刷新 |
八、場域版故障排除順序
- 記錄現象:時間、裝置 ID、IP、RSSI、目標網址、HTTP code。
- 確認影響範圍:一台裝置、同一基地台,還是所有場域都失敗?
- 由下往上測:Wi-Fi → DHCP → Gateway → DNS → TCP/TLS → HTTP → Django。
- 做單一變因測試:不要同時換 Wi-Fi、改網址又重寫程式。
- 恢復後驗證:即時資料與離線佇列是否都完成補送,是否產生重複事件。
好系統不只是「正常時會動」:還要在斷網時保留資料、恢復時自動重送、出錯時留下足以診斷的證據。
九、學生實作:同一問題,三種學習層次
No-AI|人工診斷
抄錄 ESP32 的 IP、Subnet、Gateway、DNS、RSSI與 HTTP code;依七層表判斷第一個失敗點,畫出封包停在哪裡。
AI Pair|協作除錯
把「去識別化後」的序列埠紀錄與 Django log 交給 AI,要求它提出三個假設、每個假設的驗證方法,以及不可直接下結論的原因。
Challenge AI|場域韌性
設計斷網佇列、指數退避重試、event_uuid 去重與狀態儀表板;實測關閉 Wi-Fi 5 分鐘後能否完整補送。
十、學習檢核
| 我能做到 | 完成證據 |
|---|---|
| 說明 Wi-Fi connected 與資料送達的差異 | 能指出封包必須通過的七個關卡 |
| 讀懂 ESP32 的網路配置 | 能解釋 IP、Subnet、Gateway、DNS與RSSI |
| 利用 HTTP code 定位問題 | 能區分傳輸錯誤、用戶端錯誤與伺服器錯誤 |
| 完成可重現的故障報告 | 包含時間、環境、步驟、log、假設、測試與結果 |
| 設計斷線不漏資料的 IoT 裝置 | 具備佇列、重試、去重與恢復驗證 |
沒有留言:
張貼留言