2

EPS8266 と nodeMCU を使用して時間を取得し、I2C 経由で RTC を設定したいと考えています。

これは私のスクリプトです:

-- 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」を実行して、それに続くスクリプトで「日付」を取得するにはどうすればよいですか?

Lua 5.1.4 を搭載した NodeMCU 0.9.6 ビルド 20150406 で ESP8266 を使用しています。 https://github.com/nodemcu/nodemcu-firmware/wiki/nodemcu_api_en#index

ESPlorer v2.0を使用してUSB経由でsriptをESP8266にロードします。conn.net... コマンドは NodeMCU ファームウェアの一部です (リンクを参照)。このスクリプトは、EPS8288 および NodeMCU ファームウェアでのみ実行できます。私の問題は次のとおりです。conn:net ルーチンを適切に終了し、次のプログラム部分にデータを返す方法が見つかりません。

4

2 に答える 2

3

コメンターが指摘しているように、ネットワーク コードは非同期で実行されます。つまり、conn:on呼び出しはすぐに返され、コールバックは後で呼び出されます。呼び出しはおそらく非同期ではconn:connectありませんが、それは役に立ちません。

conn:connect呼び出しが終了した直後にprint呼び出しが実行され、グローバル変数を出力しようとしますdate。Google からデータを取得するためのネットワーク レイテンシは 10 ミリ秒を超えるため、ほとんどの場合、これは印刷nilされます。これは、コードが印刷ステートメントを実行するのに十分な時間をすでに持っていることを意味します。ごくまれに、ネットワークの待ち時間が本当に運が良ければ、実際に正しい日付を取得することがあります (これは非常に驚くべきことですが)。

これを解決するには、ネットワーク リクエストの完了時に実行されるコードをconn:on、データを受信する に渡すコールバックに配置する必要があります。ただし、現在のコード構造では、これを適切な方法で行うのは少し困難です。

簡単な解決策は次のとおりです。

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

onReceiveCbhttpget コードを含める前に関数を追加したことに注意してください。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) 
于 2015-04-26T19:46:37.587 に答える
0

コールバック関数を使用した提案は機能しませんでした。コンパイル エラーが発生しました。今は別の方法で解決しました。conn:on("disconnection", function(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
于 2015-04-27T18:01:38.017 に答える