本文參考 NodeMCU 官網  API : http://nodemcu.readthedocs.org/en/dev/,將 DHT22 的感測資料透過 http 呼叫傳送給SQL server,為了支援浮點運算,須使用韌體版本為支援浮點數運算之nodemcu_float_0.9.6-dev_20150704.bin,與先前使用的整數版本不同請先自行更新韌體



1. DHT模組 API 測試


DHT 模組 API 可以自行判斷 DHT11 (整數)與其他  DHT (浮點數之結果


函數

功能

讀取以下型號之DHT感測器 DHT11, 21, 22, 33, 44

讀取DHT11感測器

讀取DHT11以外之感測器


回應結果dht.OK (0)dht.ERROR_CHECKSUM (1)dht.ERROR_TIMEOUT (2)


Lua程式測試範例


pin = 2

status, temp, humi, temp_dec, humi_dec = dht.read(pin)

if status == dht.OK then

    -- Integer firmware using this example

    print(string.format("DHT Temperature:%d.%03d;Humidity:%d.%03d\r\n",

          math.floor(temp),

          temp_dec,

          math.floor(humi),

          humi_dec

    ))


    -- Float firmware using this example

    print("DHT Temperature:"..temp..";".."Humidity:"..humi)


elseif status == dht.ERROR_CHECKSUM then

    print( "DHT Checksum error." )

elseif status == dht.ERROR_TIMEOUT then

    print( "DHT timed out." )

end


  

2. 將 DHT 感測資料上傳至 MySQL 伺服器


這部分有 init.luauser.luadht22_report.lua  三個模組。 init.lua 於開機時會自動執行程式碼如下


local timerID=0   -- LED閃滅用的 timer編號

local pinLED=4

local lighton=0

--

-- flashLED()

--

function flashLED()

    if (wifi.sta.getip()==nil) then

        gpio.write(pinLED,gpio.LOW)     

    else

        if (lighton==1) then

            gpio.write(pinLED,gpio.HIGH)           

            lighton = 0

        else

            gpio.write(pinLED,gpio.LOW)                

            lighton = 1

        end   


    end

end


--

-- checkWifi()

--

function checkWifi()

    local ip = wifi.sta.getip()


    if(ip==nil) then

        print("Connecting...")

    else

        tmr.stop(timerID)

        print("Connected to AP!")

        print(ip)

        tmr.alarm(timerID, 500, tmr.ALARM_AUTO, flashLED)

    end

end


--

-- main()

--


-- init LED status

gpio.mode(pinLED, gpio.OUTPUT) 

gpio.write(pinLED,gpio.LOW)     


-- connect Wifi

wifi.setmode(wifi.STATION)

wifi.sta.config("SSID","PASSWORD")   -- 這裡要替換成自己 AP 的 SSID 與密碼

wifi.sta.autoconnect(1) 

tmr.stop(timerID)   -- stop previous timer

tmr.unregister(timerID)

tmr.register(timerID, 2000, tmr.ALARM_AUTO,checkWifi)

if not tmr.start(timerID) then

    print("tmr.start("..timerID..") failed!")

end


-- start user file

dofile("user.lua")



user.lua負責啟動所有服務程式碼如下



dofile("dht22_report.lua");



dht22_report.lua 每隔 10 秒讀取  DHT 的感測值並用  POST 方式上傳至  MySQL 伺服器


--
--  DHT22_report

--

--  Note: this module needs the float version firmware :

--        nodemcu_float_0.9.6-dev_20150704.bin

--

local timerID=1    -- 讀取 DHT22用的計時器編號

local pinDHT=2

local sqlServer="XXX.XXX.XXX.XXX"   --這裡要替換成伺服器的 IP

local Location="NodeMCU"


--

-- sendDHT(temp, humi)

--

function postDHT(temp, humi)

    local conn = nil


    -- receive()

    function receive(conn, payloadout)

        if (string.find(payloadout, "Status: 200 OK") ~= nil) then

            print("Posted OK");

        end

    end


    --connection()

    function connection(conn, payloadout)  

        local params = "loc="..Location.."&temp="..temp.."&hum="..humi   --post paramaters

        -- Post       

        local httpString =  "POST /SensorReport.php HTTP/1.1\n"

                        ..  "Host: "..sqlServer.."\n"

                        ..  "Content-Type: application/x-www-form-urlencoded\n"

                        ..  "Content-Length: "..string.len(params).."\n\n"

                        ..  params

        print("***postDHT:\n"..httpString.."\n")

        conn:send(httpString)

    end


    --

disconnection()
    function disconnection(conn, payloadout)

        conn:close();

        collectgarbage();

    end

   

    -- create connection and register callback funciton

    conn = net.createConnection(net.TCP, 0)

    conn:on("receive", receive)

    conn:on("connection", connection)

    conn:on("disconnection", disconnection)

   

    -- connect to server

    conn:connect(80,sqlServer)

end


--

-- readDHT()

--

function readDHT()

    status, temp, humi, temp_dec, humi_dec = dht.read(pinDHT)

    if status == dht.OK then     

        local t = temp + temp_dec/1000

        local h = humi + humi_dec/1000       

        print(string.format("***DHT: Temperature : %.1f    Humidity : %.1f",t,h))  --debug

        if(wifi.sta.getip()==nil) then

            print("***DHT: Wifi is not connected")

        else

            postDHT(t,h)

        end

    elseif status == dht.ERROR_CHECKSUM then

        print( "***DHT: Checksum error." )

    elseif status == dht.ERROR_TIMEOUT then

        print( "***DHT: timed out." )

    end

end


--

-- main()

--

tmr.stop(timerID) -- stop previous timer

tmr.unregister(timerID)

tmr.register(timerID, 10000, tmr.ALARM_AUTO, readDHT)

if not tmr.start(timerID) then

     print("tmr.start("..timerID..") failed!")

end


--- start message

print("start DHT report service")




    

3. MySQL 伺服器的 http API



最後是  SensorReport.php,雖然是只用 POST 傳資料,但仍將 GET 放進來,網頁單獨測試時,可以直接在瀏覽器網址輸入測試資料 root 與 password 要替換成 mysql 的帳密

<?php

//The 'root' and 'password' is required to be setup according to your own mysql installation

$db = mysql_pconnect("localhost","root","password") or

   die('[{"Msg":"'.mysql_error().'"}]');

mysql_query("SET CHARACTER SET 'UTF8';");      

mysql_query('SET NAMES UTF8;');

mysql_query('SET CHARACTER_SET_CLIENT=UTF8;');

mysql_query('SET CHARACTER_SET_RESULTS=UTF8;');

mysql_select_db("HomeDB");

date_default_timezone_set('Asia/Taipei');

               

$loc="";

$temp=-999;

$hum=-999;


if (isset($_GET['loc'])) {

        $loc= $_GET['loc'];

}

if (isset($_GET['temp'])) {

        $temp = $_GET['temp'];

}

if (isset($_GET['hum'])) {

        $hum = $_GET['hum'];

}


if (isset($_POST['loc'])) {

        $loc = $_POST['loc'];

}

if (isset($_POST['temp'])) {

        $temp= $_POST['temp'];

}

if (isset($_POST['hum'])) {

        $hum= $_POST['hum'];

}


if ($loc=="") {  // invalid location

        die( '[{"Msg":"loc is null"}]'); //result code

}      


$query = 'INSERT INTO `HomeDB`.`sensor` '.

                 '(`Date`, `Time`, `Location`, `Temperature`, `Humidity`)'.

                 ' VALUES '.

                 '(CURDATE(), CURTIME(),"'.$loc. '","' .$temp. '","' .$hum.'");';


if(mysql_query($query)>0) {

        //create successfully

        print  '{"Msg":"OK"},';

} else {

        print  '{"Msg":"FAIL"},';

}

mysql_close();

?>





參考資料

[1]  “NodeMCU Documentation”, http://nodemcu.readthedocs.org/en/dev/



arrow
arrow
    文章標籤
    NodeMCU ESP8266
    全站熱搜
    創作者介紹
    創作者 ghostyguo 的頭像
    ghostyguo

    No More Codes

    ghostyguo 發表在 痞客邦 留言(0) 人氣()