NodeMCU與WiFi

和Arduino最不一樣的地方在於,NodeMCU本身就內建Wi-Fi晶片,因此可以直接驅動使用,而在MicroPython中也有內建的指令可以讓你的NodeMCU秒變連網裝置,現在就讓我們來看看吧!

在Wi-Fi的網路環境中主要有兩種設備,分別是作為存取節點的Access Point(AP),也就是一般我們常說的基地台,以及像是我們的手機或是筆電在上網時所扮演的角色Station(STA)。如果你是AP,就可以當做是基地台共其它的設備連接,提供網路資訊,如果是STA 的話,則是用來連接到別人取得資訊或把AP當做是上網的管道的裝置。

簡單地說,AP可以被別人連入,而STA則是用來連別人的,別人不能連上STA。NodeMCU的板子支援上述兩種角色讓我們自己選擇使用。

把NodeMCU當做是基地台AP

通常如果沒有特別設定的話,NodeMCU在MicroPython的韌體安裝完畢之後,在連接上電源啟動之後,就是以AP的模式運作,也就是它會被動地等待其它裝置的連線,而且它會每隔一段時間就在Wi-Fi信號上發佈它的識別名稱(Service Set IDentifier,SSID),預設的SSID是以MicroPython字串作為啟始,透過手機的Wi-Fi搜尋就可以看到,如下所示:

此時如果你的電腦或是筆電等等裝置就可以選用那個MicroPython-b4525d的基地台,直接連線就可以了。預設的密碼是micropythoN。連接之後會取得一個192.168.4.2的IP位址,而基地台的IP則是192.168.4.1。

但是,因為它提供的功能並不能直接從瀏覽器中操作使用,而是要透過WebREPL進行連線操作,因為還去去GitHub中下載支援的網頁(https://github.com/micropython/webrepl),有興趣的同學就自己練習看看吧。

把NodeMCU當做是連線裝置STA

由於把NodeMCU當成基地台的方式就沒有辦法上連上網際網路了,所以在實用上,大家還是比較常把NodeMCU當做是連線裝置STA來使用。

要把NodeMCU當做是STA,需要先匯入network模組,然後透過此模組啟用STA模式,請執行以下的程式:

import network
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
wlan.scan()
wlan.ifconfig()
wlan.connect('YourSSID', 'YourPassword')
wlan.ifconfig()

在你輸入了正確的SSID和密碼之後,就可以看到如下所示的網路位址資訊了:

>>> wlan.ifconfig()
('192.168.43.150', '255.255.255.0', '192.168.43.1', '192.168.43.1')

有了這個位址,也代表你的NodeMCU已經能夠透過基地台連線到網際網路上的所有服務了,其它的部份就看你的Python程式設計功力囉。

除了ifconfig()可以查詢目前的網路連線狀態之外,如果單純只是想知道目前的連線是否正常,也可以使用以下的函數來查詢:

>>> wlan.status()
5

使用status()方法函數有幾個可能的傳回值,分述如下:

  • 0:沒有連線或是沒有啟用

  • 1:連線中

  • 2:因密碼錯誤而無法連線

  • 3:因找不到基地台而無法連線

  • 4:因其它錯誤而無法連線

  • 5:已連線,並已取得IP位址

校正NodeMCU的時間

在連線上網之後的第一件事就是要校正NodeMCU的時間。因為NodeMCU本身並沒有RTC模組,因此它不能夠記住時間,也就是每一次只要通電的時候才會開始計時,當電源切斷下次再通電時,所設定的時間又會全部還原,因此,我們需要透過網路NTP服務來校正NodeMCU的時鐘。

MicroPython支援的時間函數模組最基本的是time,使用time.time ()可以取得從NodeMCU接上電源之後到目前為止經過的秒數,如下:

>>> import time
>>> time.time()
5
>>> import network
>>> wlan = network.WLAN(network.STA_IF)
>>> wlan.active(True)
>>> wlan.connect('Z3Skynet', '********')
>>> wlan.ifconfig()
('192.168.43.150', '255.255.255.0', '192.168.43.1', '192.168.43.1')
>>> import time
>>> time.time()
74
>>> now = time.time()
>>> time.localtime(now)
(2000, 1, 1, 0, 1, 18, 5, 1)

在上面的操作過程中,我們使用time.time()得到的是74秒,接著可以利用time.localtime(now)這個函數把目前的秒數換成人們可以解讀的內容,從2000年開始起算,(2000, 1, 1, 0, 1, 18, 5, 1)分別就代表了2000年1月1日0時1分18秒星期五以及是今年的第1天。

當然我們可以透過程式的方式去手動地設定目前的正確時間,不過,既然已經連上網路了,為何不用網路上的時間來直接設定呢?!MicroPython其實提供了可以直接由網路來校正NodeMCU時的函數模組ntptime,其中的settime()函數即可自動連上網路設定本地時間。使用方法如下:

>>> from ntptime import settime
>>> settime()
(2018, 11, 12, 7, 51, 0, 0, 316)
>>> time.localtime()
(2018, 11, 12, 7, 51, 4, 0, 316)

只要設定過一次settime(),就可以即時把本地時間設定為最正確的時刻了。不過,有一點要注意的是,它是格林威治時間,台灣的區域時間(中原標準時間)還要再加上8小時才行,為了設定為本地的時間,可以使用以下的技巧:

>>> utc = time.mktime(time.localtime())
>>> time.localtime(utc+28800)
(2018, 11, 12, 15, 54, 17, 0, 316)

其中第一行使用mktime()函數把目前的本地時間轉換成秒數放到utc變數中,之後把utc加上28800(8小時的秒數),再透過localtime()函數把它設定回本地時間即可。最後,每次使用time.localtime()就可以查詢到目前的正確時間了。以下方法可以把每一個單項內容(年月日、時分秒)分別取出:

>>> time.localtime()
(2018, 11, 12, 7, 56, 41, 0, 316)
>>> year, month, day, hour, minute, second, week, days = time.localtime()
>>> year
2018
>>> month
11
>>> day
12

有了正確的時間資料,在記錄我們的感測資訊時就更有感覺了。

這些程式碼都可以寫在boot.py中,讓NodeMCU一開機的時候就會自動地執行這些連線以及時間的校正喔。