| ESP32 教學 | MicroPython | Wifi Networking 無線上網 | 301 |

選擇 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 設備連上網,三個步驟即可:

  1. 建立一個網路物件(並指定 STA Mode)
  2. 啟動 wifi 功能
  3. 設定連上基地台的 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 networking

如果 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. SSIDb'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。

https://jimirobot.com.tw/image/esp32/301/ps_boot1.jpg

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

  1. 謝謝您的教學 😀

    1. 感謝支持!! 希望內容對您有幫助~ 如有遇到問題也歡迎留言或寫信給我互相交流一下 ~

發佈留言

Close Menu