在上一篇中,我們成功在 OLED 螢幕上顯示了本地的溫濕度數據,讓 ESP32 具備了獨立運作的「視覺」。不過,這依然只能算是一個「單機設備」。要成為真正意義上的「物聯網(IoT)」節點,裝置必須能夠上網,且數據必須伴隨精確的時間標記。
今天,我們要來解鎖 ESP32 最強大的天賦——無線聯網 (Wi-Fi)!我們將實作如何讓 ESP32 在開機時自動連上當地的無線網路,並透過 NTP (網路時間協定) 向世界級的標準時間伺服器「對時」。這樣一來,我們採集到的每一筆數據,都能打上精準的「時間戳記 (Timestamp)」,這是日後大數據分析與異常追溯必備的基礎!
1. 觀念解析:什麼是 NTP 網路時間協定?
ESP32 內部雖然有定時器,但它沒有像電腦或手機那樣有「水銀電池(RTC 模組)」來保存時間。每次只要斷電重開,它的時間就會歸零(回到 2000 年 1 月 1 日)。這在大數據採集中是非常致命的,因為我們無法得知「這筆異常高溫是在何時發生的」。
為了解決這個問題,只要讓 ESP32 聯網,就能使用 NTP (Network Time Protocol)。這是一種用來在網路中同步電腦時間的協定。透過向公開的 NTP 伺服器發送請求,我們的 ESP32 就能獲取誤差在幾毫秒內的 UTC 標準時間,並轉換為台灣當地的標準時間(UTC+8)!
▲ ESP32 Wi-Fi 自動連線與 NTP 時間同步示意圖
2. 實作一:讓 ESP32 連上 Wi-Fi
import network
import time
def connect_wifi(ssid, password):
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
if wlan.isconnected():
print("已經處於連線狀態:", wlan.ifconfig())
return True
print(f"正在連線到 Wi-Fi: {ssid}...")
wlan.connect(ssid, password)
timeout = 10
# 注意:這裡使用 > 代表大於符號
while not wlan.isconnected() and timeout > 0:
print(".", end="")
time.sleep(1)
timeout -= 1
if wlan.isconnected():
print("\n連線成功!獲得 IP 配置:")
print(wlan.ifconfig())
return True
else:
print("\n連線失敗,請檢查帳號密碼或網路訊號!")
return False
connect_wifi("Your_WiFi_SSID", "Your_WiFi_Password")
3. 實作二:NTP 網路時間校準與台灣時區轉換
import ntptime
import time
print("嘗試向 NTP 伺服器對時中...")
try:
ntptime.settime()
print("對時成功!")
except Exception as e:
print("對時失敗,請確認是否已聯網。錯誤原因:", e)
def get_taiwan_time():
taiwan_seconds = time.time() + (8 * 3600)
local_t = time.localtime(taiwan_seconds)
formatted_time = "{:04d}-{:02d}-{:02d} {:02d}:{:02d}:{:02d}".format(
local_t[0], local_t[1], local_t[2], local_t[3], local_t[4], local_t[5]
)
return formatted_time
for _ in range(5):
print("台灣時間:", get_taiwan_time())
time.sleep(1)
4. 進階實作:聯網、對時與環境採集(整合 main.py)
from machine import Pin, I2C
import ssd1306
import dht
import time
import network
import ntptime
i2c = I2C(0, scl=Pin(22), sda=Pin(21))
oled = ssd1306.SSD1306_I2C(128, 64, i2c)
sensor = dht.DHT11(Pin(4))
SSID = "Your_WiFi_SSID"
PASSWORD = "Your_WiFi_Password"
oled.fill(0)
oled.text("Connecting...", 10, 20)
oled.show()
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
wlan.connect(SSID, PASSWORD)
timeout = 10
while not wlan.isconnected() and timeout > 0:
time.sleep(1)
timeout -= 1
if wlan.isconnected():
oled.fill(0)
oled.text("Connected!", 10, 20)
oled.text(wlan.ifconfig()[0], 10, 40)
oled.show()
time.sleep(2)
try:
ntptime.settime()
except:
pass
else:
oled.fill(0)
oled.text("WiFi Failed", 10, 20)
oled.show()
time.sleep(2)
def get_tw_time():
t_sec = time.time() + (8 * 3600)
t = time.localtime(t_sec)
return "{:02d}:{:02d}:{:02d}".format(t[3], t[4], t[5])
while True:
try:
sensor.measure()
temp = sensor.temperature()
humi = sensor.humidity()
oled.fill(0)
oled.text("ESP32 IoT Node", 5, 0)
oled.text("----------------", 0, 10)
oled.text(f"Time: {get_tw_time()}", 0, 25)
oled.text(f"Temp: {temp} C", 0, 40)
oled.text(f"Humi: {humi} %", 0, 52)
oled.show()
except Exception as e:
oled.fill(0)
oled.text("Error!", 10, 25)
oled.show()
time.sleep(2)

沒有留言:
張貼留言