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”,





沒有留言:

張貼留言