2015-04-26 273 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