2015-04-26 187 views
2

我想要使用具有nodeMCU的EPS8266來通過I2C設置我的RTC。Lua腳本不會按順序執行

這是我sript:

-- file print.lua  
local file = assert(loadfile("httpget.lua"))  
file()     --get Date and Time from google  
print("Print follows:") --this should be executed after "file()"  
print(date) 

這是文件httpget.lua

-- file httpget.lua 
print('httpget.lua started') 
conn=net.createConnection(net.TCP, 0) 
-- show the retrieved web page 
conn:on("receive", function(conn, payload) 
        date = string.sub(payload,string.find(payload,"Date: ") 
        +6,string.find(payload,"Date: ")+35) 
        conn:close() 
        end) 

conn:on("connection", function(conn, payload) 
         print('\nConnected') 
         conn:send("HEAD/HTTP/1.1\r\n" 
         .."Host: google.com\r\n" 
         .."Accept: */*\r\n" 
         .."User-Agent: Mozilla/4.0 (compatible; esp8266 Lua;)" 
         .."\r\n\r\n") 
         end) 

-- when disconnected, let it be known 
conn:on("disconnection", function(conn, payload) 
         print("Disconnected\r\n"..date) 
         end)            
conn:connect(80,'google.com') 
conn = nil 

結果是:

> dofile("print.lua") 
httpget.lua started 
Print follows:    -- this should be at the end 
nil       -- date==nil because httpget.lua not executed 
> 
Connected 
Disconnected 
Sun, 26 Apr 2015 10:30:03 GMT 

如果我再次執行素文字(不復位)我從之前的執行中得到日期。 我能做些什麼來執行「httpget.lua」並在隨後的scipt中獲取「日期」?

我使用一個ESP8266與NodeMCU 0.9.6構建20150406由Lua 5.1.4驅動。 https://github.com/nodemcu/nodemcu-firmware/wiki/nodemcu_api_en#index

我使用ESPlorer v2.0通過USB向我的ESP8266加載sripts。 conn.net ...命令是NodeMCU固件的一部分(請參閱鏈接)。您只能使用EPS8288和NodeMCU固件運行腳本。我的問題是:我無法正確結束conn:net例程並將數據返回到下一個程序部分。

+0

連接調用可能是異步的,但我不知道你用的是什麼庫。 – ryanpattison

+0

另一方面,您已經定義了事件處理程序,並且print.lua不會等待連接成功,然後繼續到下一行。另外,我不知道lua是否會將日期的值傳遞給不同的範圍。 – Kyle

+0

我使用帶有由Lua 5.1.4支持的NodeMCU 0.9.6 build 20150406的ESP8266。我使用ESPloer加載腳本。 –

回答

3

正如評論者指出的那樣,網絡代碼將異步運行,即conn:on調用將立即返回並在稍後調用它們的回調。調用conn:connect可能不是異步的,但這沒有幫助。

直接在conn:connect調用完成後,您的print調用將運行,試圖打印全局變量date。大多數情況下,這會打印nil,因爲從Google獲取數據的網絡延遲時間將超過10毫秒,這意味着您的代碼已經有足夠的時間來執行打印語句。在極少數情況下,如果你真的對網絡延遲感到幸運,那麼你實際上可能會得到正確的日期(儘管如此,這將是非常令人驚訝的)。

要解決此問題,您需要將代碼傳遞到接收數據的conn:on回調中的網絡請求完成時執行。在你現在的代碼結構中,雖然這樣做有點困難。

一個簡單的辦法是做:

local function onReceiveCb(str) 
print("Print follows:") 
print(str) 
end 
local file = assert(loadfile("httpget.lua")) 
.... 

注意包括HTTPGET代碼之前我已經添加了onReceiveCb功能。在httpget中,您調用回調函數:

conn:on("receive", function(conn, payload) 
        date = string.sub(payload,string.find(payload,"Date: ") 
        +6,string.find(payload,"Date: ")+35) 
        conn:close() 
        onReceiveCb(date) -- Call the callback! 
        end) 
0

帶回調函數的提議不起作用。我有一個編譯器錯誤。我現在用其他方式解決了它。 在conn:on(「disconnect」,函數(conn,payload))中,我加載文件來設置我的RTC,這樣我就可以將數據傳遞給設置RTC的程序(參見我的輸出)

感謝您的幫助!

> dofile("httpget.lua"); 
httpget.lua started 
> 
Connected 
Disconnected 

---------------- 
Date: Mon, 27 Apr 2015 12:02:17 GMT -- printed in httpget.lua 
Date: Mon, 27 Apr 2015 12:02:17 GMT -- printed in set_date.lua 
Set RTC: 
23 2 19 2 39 4 21 -- Bytes 0-6 in decimal of the DS1307 (1h for Daylight Savings Time added) 
done 

- 這是工作的腳本:

print('httpget.lua started') 

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

-- show the retrieved web page 
conn:on("receive", function (conn, payload) 
        date = string.sub(payload,string.find(payload,"Date: ") 
        +0,string.find(payload,"Date: ")+35) 
        conn:close() 
        end) 

-- when connected, request page (send parameters to a script) 
conn:on("connection", function(conn, payload) 
         print('\nConnected') 
         conn:send("HEAD/HTTP/1.1\r\n" 
         .."Host: google.com\r\n" 
         .."Accept: */*\r\n" 
         .."User-Agent: Mozilla/4.0 (compatible; esp8266 Lua;)" 
         .."\r\n\r\n") 
         end) 

-- when disconnected, let it be known 
conn:on("disconnection", function(conn, payload) 
         print("Disconnected\r\n") 
         print("----------------") 
         print(date) 
         dofile("set_date.lua"); 
         end) 

conn:connect(80,'google.com') 
conn=nil 
+0

很好,你解決了!您可以將自己的答案標記爲正確的答案(因此顯示爲已答覆)。如果我的回答是有幫助的,請給它一個upvote。 – johlo