2015-04-26 6 views
2

Я хочу получить время, используя EPS8266 с nodeMCU, чтобы установить мой RTC через I2C.Сценарий 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 

Если я снова выполнить scipt (без перезагрузки) Я получаю дату от исполнения раньше. Что я могу сделать, чтобы выполнить «httpget.lua» и получить «дату» в следующем порядке?

Я использую ESP8266 с NodeMCU 0.9.6 build 20150406 от Lua 5.1.4. https://github.com/nodemcu/nodemcu-firmware/wiki/nodemcu_api_en#index

Я загружаю сценарии через USB с помощью ESPlorer v2.0 на свой ESP8266. Команды conn.net ... являются частью прошивки NodeMCU (см. Ссылку). Вы можете запускать сценарий только с помощью прошивки EPS8288 и NodeMCU. Моя проблема заключается в следующем: я не нахожу никакого способа закончить корректную подпрограмму conn: net и возвращать данные в следующую часть программы.

+0

на соединение вызова, вероятно, асинхронный, но я не знаю, что библиотека вы используете. – ryanpattison

+0

С выключенной стороны вы определили обработчики событий, и print.lua не дожидается успешного соединения, прежде чем он перейдет к следующей строке. Кроме того, я не знаю, будет ли lua передавать значение даты в разные области. – Kyle

+0

Я использую ESP8266 с NodeMCU 0.9.6 build 20150406, работающим от Lua 5.1.4. Я загружаю скрипты с ESPloer. –

ответ

3

Как отмечают комментаторы, сетевой код будет выполняться асинхронно, то есть вызовы conn:on будут немедленно возвращены, а их обратные вызовы будут вызваны позже. Вызов conn:connect, вероятно, не асинхронный, но это не помогает.

Непосредственно после завершения вызова conn:connect вызовы будут выполнены, пытаясь распечатать глобальную переменную date. В большинстве случаев это будет печатать nil, так как время ожидания сети для извлечения данных из Google будет в> 10 миллисекунд, что означает, что у вашего кода уже было достаточно времени для выполнения операторов печати. В некоторых редких случаях вы можете получить правильную дату, если вам действительно повезло с латентностью сети (это было бы очень удивительно).

Для этого необходимо поместить код, который будет выполняться, по завершении сетевого запроса в обратном вызове, который вы передадите на conn:on, который получает данные. В вашей нынешней структуре кода это немного сложно сделать в приятной манере.

Простое решение сделать:

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

Обратите внимание, что я добавил onReceiveCb функцию перед включением кода HttpGet. В 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

Предложение с функцией обратного вызова не работает. У меня ошибка компилятора. Я решил это сейчас по-другому. В режиме разъединения (функция «разъединение», функция (соединение, полезная нагрузка), я загружаю файл для установки своего 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 

--This это рабочий сценарий:

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

Отлично, что вы решили! Вы можете пометить свой собственный ответ как правильный (поэтому он отображается как ответ). И если бы мой ответ был полезен, пожалуйста, дайте ему преимущество. – johlo

 Смежные вопросы

  • Нет связанных вопросов^_^