選擇 ESP32 核心為主控制器其中一個重要原因就是內建了 wifi networking 的功能,無須連接外部的網路硬體來進行,在物聯網應用尤為重要,這篇就來瞭解如何使用 micropython 語法,將 ESP32 透過家中的無線基地台上網,並設定開機就自動連線。
1. wifi networking 類別
– wifi 連線程序
要測試 ESP32 的 wifi 功能正常與否,最直覺的方式就是將 ESP32 模組(本文採用 ai-thinker 的 ESP32S 為例)連接 USB 線到電腦,並使用 REPL 模式來進行互動,即可瞭解目前的網路環境。( REPL模式不熟悉的朋友,可以參考這篇 https://jimirobot.tw/esp32-micropython-tutorial-micropython-repl-104/ )
wifi 的操作與設定放在 network 這個類別內,要將手邊的 ESP32 設備連上網,三個步驟即可:
- 建立一個網路物件(並指定 STA Mode)
- 啟動 wifi 功能
- 設定連上基地台的 ssid 與密碼進行連接
簡單的程式範例如下:
import network wifi= network.WLAN(network.STA_IF) wifi.active(True) wifi.connect('wifi_ssid','password')
在第2行的 wifi,就是我們所建立的網路物件,network.WLAN 內的設定,可以填入兩種參數:network.STA_IF 與 network.AP_IF,分別代表所謂的基站與無線基地台模式,這邊使用「STA Mode」基站模式,來加入附近的無線基地台網路。
第3行為啟動 wifi 功能,這邊如果填入 False,就是關關 wifi 功能。
第4行為進行連線動作,connect 的第1個參數填入無線基地台的名稱,第2個參數為設定密碼。
下面是實際操作 REPL 模式的情況:
如果 wifi 都設定OK,ESP32 將顯示取得的 ip 位址與其他網路設定值。
– 網路操作常用方法
如果遇到連線問題時,可以參考下面的方法進行測試修改:(下面提到的 wifi 為建立的物件名,可自行定義)
I. ifconfig()
這個方法可以用來讀取或設定目前裝置 tcp/ip 的相關參數,例如要是想確認目前的網路狀態,可以直接在 REPL 模式下打入 wifi.ifconfig()
,便會顯示目前的 TCP/IP 的設定。想要手動設定網路參數,在 ifconfig() 內打入對應的 ip 位址即可,如 wifi.ifconfig(('192.168.43.10', '255.255.255.0', '192.168.43.1', '192.168.43.1'))
,刮號內參數依序對應 本機IP/子網路遮罩/Gateway/DNS,所以如果不想用預設的DHCP,也就是從無線基地台獲得分配的IP,就可以用這個方法直接指定靜態IP,ifconifg 這個方法還蠻好用的,各位朋友可以將它記住。
小提醒:當指定靜態ip 到 ifconfig() 時,ifconfig() 這個方法只接受 tuple 型態的資料,所以相關 ip 的資料要多加一個刮號,不然就會無法指定喔!!
II. scan()
這個方法就是在當裝置在STA模式下,掃描附近的無線基地台,下面來實際操作看看:
如上圖所示,建立好 wifi 的 STA 模式物件後,直接打入 wifi.scan()
, 螢幕便會 show 出附近的無線基地台相關資訊,每個AP一共會提供6個參數「ssid, bssid, channel, RSSI, authmode, hidden」,我們使用其中一個 (b'Starbucks Wi-Fi', b'\xdc\xae\xeb\x81r\xa8', 6, -52, 0, False)
依序來進行說明:
1. SSID: b'Starbucks Wi-Fi'
,『Starbucks Wi-Fi』這個就是無線基地台的 ssid 名稱,有注意到名稱的前面有個小寫 b 嗎?這個就是指這個名稱是用 python 的『bytes』位元組型態所儲存的。
2. MAC位址:b'\xdc\xae\xeb\x81r\xa8'
,這個就是標示這個無線基地台的MAC實體位址,在世界上每個可以連上網的硬體都會一個獨特的的MAC位址,我們在電腦上常見到的實際位址通常會顯示為16進位,如『00:18:47:1E:42:56』類似這樣的數字。
在 micropython 中的表示法,其實只是把用這個數字用剛剛提到的 bytes 型態儲存起來( \x 是表示為16進位),將掃到 starbucks 的基地台 mac 位址進行拆解的話,就會變成『\xdc:\xae:\xeb:\x81:r:\xa8』,\x後面的數字很好理解,就是16進位的數字,那為什麼有個『r』,這個是因為如果這個數字是介於0-127之間的話,就會直接用 ascii 碼的符號去代替(有興趣的朋友可以去參考ascii碼的wiki ),所以此處的實體位址用電腦上的顯示方法就是『 DC:AE:EB:81:72:A8』,各位朋友會不會覺得每次要看時都要換算一下很麻煩? micropython 也有內建一個轉換模組 ubinascii(源自另一套嵌入式pathon語法的cpython),將 bin 二進位資料轉換成 ascii 顯示,使用方法如下:
(步驟:將 wifi.scan() 的資料存下,Starbucks Wi-Fi 為傳回來的第3筆 ap 資料,mac 實體位址為每個 ap 的第 2 個資訊 )
import ubinascii ap_data=wifi.scan() mac_bin=ap_data[2][1] mac_ascii= ubinascii.hexlify(mac_bin,':') #用:號隔開
REPL 下操作就很清楚了:
3. 頻道 channel: 這是指 wifi 基地台的 channel,切換到合適的頻道可以有效避免訊號的干擾。
4. 訊號品質 rssi: Received Signal Strength Indication,這就是表示 wifi 訊號的強弱指標,單位是 dBm,通常為負值,越接近零表示訊號強度越好,這個值每次掃描都會稍有浮動,像第一次 starbucks Wi-Fi 強度為-52dBm,第2次就是-49dBm。
5. 認證模式 authmode: 無線網路的安全性需要透過認證 Authentication 來實施,在 micropython 的 wifi 連接,提供5種參數設定:0->none; 1->WEP; 2->WPA-PSK; 3->WPA2-PSK; 4->WPA/WPA2-PSK。這邊掃描到的 Wifi AP 認證設定用 0。(有覺得有點危險嗎? 😆 )
6. 隱藏: 這邊是指該 ssid 是否隱藏,False 表示無隱藏。
III. status()
status 這個方法可以確認參數與回覆網路的狀態,如果不帶入任何引數,則會回傳一個數值表示網路狀態,常見數值意義如下:
- 1000:閒置中
- 1001: 連線中
- 1001:已取得IP狀態
也可以帶入想知道的參數值,如:wifi.status('rssi')
,REPL 會回覆目前連上AP 的訊號強度。
2. 開機自動上網
在了解 micropython REPL 模式下如何上網後,接著就是設定讓 ESP32 在上電後可以直接連上網路,方法就是將上面的操作程序寫在 boot.py 或 main.py 內執行,不過實務上在說,我們通常把開機連網動作會寫在 boot 程序內,控制動作寫在 main.py。
我們先檢視一下原本放在 ESP32 內部的 boot.py 內容,這邊可以透過之前文章介紹過的 ThonnyIDE 或自己熟悉的工具,JIMI哥 常用的是 mpfshell lite 這套,操作過程如下:
Step1: 透過 serial 傳輸連結 ESP32,並檢視硬體的檔案列表是否有 boot.py。
Step2: 檢視 boot.py 內容。
在預設的 boot.py 內容,可以看到其實程序都是被註解掉,所以只要編寫的連網動作寫成程序直接加入其中即可。
– 完整程式碼
在實際連網過程中,有時會有找不到基地台或帳號密碼錯誤導致無法連上 Wifi,因此程式碼加上簡單的 Timeout 機制,也就是在一定時間內,無法連上網時,即顯示錯誤訊息,完整 boot.py 程式碼如下:
import esp,network,utime esp.osdebug(None) #import webrepl #webrepl.start() wifi= network.WLAN(network.STA_IF) wifi.active(True) try: wifi.connect('androidjj','jimixxxxtw') print('start to connect wifi') for i in range(10): print('try to connect wifi in {}s'.format(i)) utime.sleep(1) if wifi.isconnected(): break if wifi.isconnected(): print('WiFi connection OK!') print('Network Config=',wifi.ifconfig()) else: print('WiFi connection Error') except Exception as e: print(e)
– 程式說明
import esp,network,utime esp.osdebug(None) #import webrepl #webrepl.start() wifi= network.WLAN(network.STA_IF) wifi.active(True)
程式一開始先 import 三個模組分別是 esp、 network、 utime。esp.osdebug()
這個方法為顯示系統內部的相關除錯訊息,開啟這個功能(將 None 改為0 ),在初期測試網路時透過 UART0 的介面傳出系統訊息(也就是 REPL 畫面),方便我們快速瞭解相關的錯誤原因,待測試完成後,JIMI哥 就會建議這個功能關閉,減少訊息干擾。第 5-6 行程式建立起 WLAN 物件與 STA 模式後,啟動 wifi 功能。
try: wifi.connect('androidjj','jimixxxxtw') print('start to connect wifi') for i in range(10): print('try to connect wifi in {}s'.format(i)) utime.sleep(1) if wifi.isconnected(): break
第8行:wifi.connect()
內填入欲連上線基地台 ssid 與密碼,開始進行連線。
第9-14行:這邊利用 for 迴圈設計一個簡單的 timeout 機制,時間限制為10s,utime.sleep(s)
內填入單位為秒,所以 utime.sleep(1)
就是 delay 1秒,10次迴圈就是10秒,如在時間限制內連上基地台,執行 break 跳出等待迴圈。
if wifi.isconnected(): print('WiFi connection OK!') print('Network Config=',wifi.ifconfig()) else: print('WiFi connection Error') except Exception as e: print(e)
跳出等待迴圈後,wifi.isconnected()
回傳是否已連上網,如果已連上 wifi,系統顯示目前的網路 ip 相關資訊,如果連線失敗,顯示 wifi connect Error!。第21行:如有任何 Exception 發生,列印錯誤訊息。
3. 小結
本篇主要介紹 ESP32 的 wifi 如何連網操作,如果想要啟動自動上網功能,也可以在預設的 boot.py 檔編輯想要執行的程序,micropython 在 ESP32上還有一個優勢就是內建 file system,在某些產品上,就可以將這上網的資訊透過檔案或鍵盤輸入存取,達成更為彈性的應用,後續 JIMI 哥會在整理這部分的資料與各位朋友分享。
今天的內容就到這邊,如果各位有遇到什麼問題,也歡迎在下面留言或寫信與我討論囉~
↓↓↓↓↓↓賣場連結↓↓↓↓↓↓
歡迎大家有需要的話,可以多多支持一下我們的蝦皮賣場喔! 😀
吉米家官方店-創客機器人材料專賣 https://shopee.tw/jimirobot.tw
Follow JIMI哥 Twitter : https://twitter.com/jimirobot <–得到最新文章通知
This Post Has 2 Comments
Jun
11 3 月 2021謝謝您的教學 😀
jimi
12 3 月 2021感謝支持!! 希望內容對您有幫助~ 如有遇到問題也歡迎留言或寫信給我互相交流一下 ~