2016年7月30日 星期六

使用 ESPlorer 撰寫 NodeMCU 程式

本文以 NodeMCU v2開發板,使用 ESPlorer 撰寫 Lua 程式。Lua是一種 script 語言,語法非常精簡,跨平台的手機程式 CoronaSDK 也使用它,lua 官網是 https://www.lua.org/。


1.下載 ESPlorer 


ESPlorer官網:http://esp8266.ru/esplorer/

電腦須先安裝JAVA7以上的執行環境,下載之後解開,直接執行ESPlorer.bat即可:



啟動後的畫面分左右兩半,左邊是程式編輯區,右邊是與ESP8266通訊的終端機,設定右上方的COM port之後,按下open按鈕就可以連線,連線後如果出現Can’t autodetect…. 錯誤訊息,先忽略不看。



畫面右方三個按鈕的作用是:
        
        Format :將ESP8266格式化,使用者程式會全部被刪除。
        FS Info:查看ESP8266的檔案狀況。
        Reload :重新載入使用者程式。 

右下方的Snippet,目前先使用Snippet0即可。


2. 程式編輯與執行


在畫面左方 Scripts 視窗輸入程式,然後按下下方的  Send to ESP  按鈕,即可送至 NodeMCU立即執行。Lua 語言也可以將程式模組化,然後呼叫模組來執行某些動作。

先來一行最簡單的程式:

print("Hello, world")

將上面的程式輸入到Scripts視窗,按下  Send to ESP    按鈕,就可以在右邊的終端機視窗看到如下圖的傳送過程與結果。


再來一個簡單的GPIO範例,讓ESP8266-12上面的LED燈閃爍100次:

pin = 4 -- gpio pin
gpio.mode( pin, gpio.OUTPUT )
for i=1,100 do
    gpio.write( pin, gpio.LOW )
    tmr.delay( 500000 ) -- delay 0.5 second
    gpio.write( pin, gpio.HIGH )
    tmr.delay( 500000 ) -- delay 0.5 second
end

NodeMCU的韌體預設在晶片開機的時候,會先自動呼叫 init.lua 這個檔案來執行。 如果要有開機後執行初始化設定的需求的時候,就把初始化動作寫好之後存指定檔名為 init.lua之後,再按下  Save to ESP  按鈕。以下程式,可以讓NodeMCU開機後,LED不斷的閃爍。

pin = 4 -- gpio pin
gpio.mode( pin, gpio.OUTPUT )
while 1 do
    gpio.write( pin, gpio.LOW )
    tmr.delay( 500000 ) -- delay 0.5 second
    gpio.write( pin, gpio.HIGH )
    tmr.delay( 500000 ) -- delay 0.5 second
end

按下  Save to ESP  按鈕,輸入檔案名稱為 init.lua:


按下右方  Reload  按鈕,會出現剛剛儲存的 init.lua 按鈕,按一下該按鈕就可輸入命令:

dofile("init.lua")

自動執行init.lua程式。


  

3. 類比輸入


NodeMCU 讀取類比輸入接腳A0:

for i=1,100 do
    print(adc.read(0))
    tmr.delay(1000000)
end

  

4. DHT22 感測器


DHT22 溫溼度感測器使用的並非標準通訊訊號,因此要撰寫專用的驅動程式。經測試,參考資料 [3] 提供的驅動程式可以正確抓到資料。欲讀取溫溼度感測值,須先建立一個  dht22_min.lua模組,放入  ESP8266-12  的使用程式區,然後在程式中將該模組  require  進來,就可以指定  DHT22  的  data  接腳,呼叫  read()  函數讀取感測值,即可取得溫溼度的資料。
進行本實驗時,因  NodeMCU  的電壓是  3.3V,而  DHT22 使用 3.3V 亦可驅動,因此請依照下表將  DHT22  與  NodeMCU  的接腳互相連接,切忌勿將  DHT22  連接至  5V  電壓,否則  data  腳輸入的電壓將會導致  NodeMCU  損壞。

DHT22接腳
NodeMCU接腳
VCC
3.3V
GND
GND
Data
D2

dht22_min.lua 程式碼如下:

--
-- dht22_min.lua
--
local moduleName=...
local M={}
_G[moduleName] = M

local o
local d

function a.read(e)
    local r
    local t
    o=0
    d=0
    r=0
    local i=gpio.read
    local l={}
   
    for e=1,40,1 do
        l[e]=0
    end
   
    local a=0
    gpio.mode(e,gpio.OUTPUT)
    gpio.write(e,gpio.HIGH)
    tmr.delay(100)
    gpio.write(e,gpio.LOW)
    tmr.delay(40)
    gpio.mode(e,gpio.INPUT)
   
    while(i(e)==0)do end
   
    local n=0
   
    while(i(e)==1 and n<500) do
        n=n+1
    end
   
    while(i(e)==0)do end
   
    n=0
   
    while(i(e)==1 and n<500)do
        n=n+1
    end
   
    for d=1,40,1 do
        while(i(e)==1 and a<10)do
            a=a+1
        end
        l[d]=a
        a=0
   
        while(i(e)==0)do end
    end
   
    for e=1,16,1 do
        if(l[e]>4)then
            o=o+2^(16-e)
        end
    end
   
    for e=1,16,1 do
        if (l[e+16]>4) then
            d=d+2^(16-e)
        end
    end
   
    for e=1,8,1 do
        if(l[e+32]>4)then
            r=r+2^(8-e)
        end
    end
   
    t=(bit.band(o,255)+bit.rshift(o,8)+bit.band(d,255)+bit.rshift(d,8))
    t=bit.band(t,255)   
    if d>32768 then
        d=-(d-32768)
    end
   
    if(t-r>=1)or(r-t>=1)then
        o=nil
    end
    gpio.mode(e,gpio.OUTPUT)
    gpio.write(e,gpio.HIGH)
end
   
function a.getTemperature()
    return d
end
   
function a.getHumidity()
    return o
end

return a

dht22_demo.lua 程式碼如下:

--
-- dht22_demo
--
DHT= require("dht22_min")
DHT.read(2)
temperature = DHT.getTemperature()
humidity = DHT.getHumidity()
if humidity == nil then
    print("Error reading from DHT22")
else
    print("Temperature: "..(temperature / 10).."."..(temperature % 10).." deg C")
    print("Humidity: "..(humidity / 10).."."..(humidity % 10).."%")
end




參考資料
[1]  “ESP8266無線模組燒錄 NodeMCU 韌體 ( Lua 語法支援 )”,
[2]  “Using NodeMCU Lua”,
[3]  “ESP8266 NodeMCU – DHT22 humidity sensor with MQTT and deep sleep”,





沒有留言:

張貼留言