2016-05-13 6 views
1

2つのタイマーを使用するNodeMCU LUAアプリケーションがあります。各タイマーは、ローカルサーバーにHTTP要求を行う機能を呼び出します。NodeMCUタイマーが予期せず停止する

数回繰り返した後、タイマーの1つが停止し、もう1つのタイマーが続行されます。タイマーが停止する前の反復回数はランダムであるようです。私は何度もテストスクリプトを実行しましたが、タイマーが停止するポイントは決して同じではありません。注:必ずしも同じタイマが停止するとは限りません。ここで

は確実にこの問題を示し、いくつかのテストコードです:

ctr1=0 
ctr2=0 

local function doCmdChk() 
    ctr1 = ctr1 + 1 
    http.get("http://192.168.2.38/ICmd.py?i=" .. ctr1 , nil, 
    function(rspCode, payload) 
     tmr.start(1) 
    end) 
end 

local function sendData() 
    ctr2 = ctr2 + 1 
    local msgBdy = '{"s":"' .. ctr2 .. '","i":"test23", "d":"heap='..node.heap()..'"}' 

    http.post("http://192.168.2.38/DeviceScan.py", "Content-Type: text/json\r\n", msgBdy, 
    function(rspCode, payload) 
     tmr.start(2) 
    end) 
end 

--mainline start: 
tmr.alarm(1, 3000, tmr.ALARM_SEMI, doCmdChk) 
tmr.alarm(2, 5000, tmr.ALARM_SEMI, sendData) 

私のアプリケーションは早くテストコードとしてHTTPリクエストをオフに発生しませんが、アプリケーションは数時間、同じ結果を実行したとき最終的に発生します(つまり、タイマーの1つが動作を停止します)。 HTTP要求間の時間を短縮すると、エラーがより早く発生します。

誰でもこの問題が発生しましたか?誰もこの問題のトラブルシューティング方法に関するアイデアはありますか? (継続的なHTTP要求を確実に送信することができないことは、このアプリケーションのためのショーストッパーです)。

答えて

1

解決策は、特定の時点で1つのhttp要求だけが未解決であるようにフラグを設定することです。ここでは、フラグを含み、以前のテストスクリプトは次のとおりです。

ctr1=0 
ctr2=0 
sendFlag=true 

local function doCmdChk() 
    if sendFlag then 
     sendFlag=false   
     ctr1 = ctr1 + 1 
     http.get("http://192.168.2.38/ICmd.py?i=" .. ctr1 , nil, 
     function(rspCode, payload) 
      sendFlag=true 
      tmr.start(1) 
     end) 
    else 
     tmr.alarm(3, 1000, tmr.ALARM_SINGLE, doCmdChk) 
    end 
end 

local function sendData() 
    if sendFlag then 
     sendFlag=false   
     ctr2 = ctr2 + 1 
     local msgBdy = '{"s":"' .. ctr2 .. '","i":"test23", "d":"heap='..node.heap()..'"}' 

     http.post("http://192.168.2.38/DeviceScan.py", "Content-Type: text/json\r\n", msgBdy, 
     function(rspCode, payload) 
      sendFlag=true 
      tmr.start(2) 
     end) 
    else 
     tmr.alarm(3, 1000, tmr.ALARM_SINGLE, sendData) 
    end 
end 

--mainline start: 
tmr.alarm(1, 3000, tmr.ALARM_SEMI, doCmdChk) 
tmr.alarm(2, 5000, tmr.ALARM_SEMI, sendData) 

は、私は数時間のために、このスクリプトを実行し、両方のHTTPの機能が期待どおりに動作し続けて送ります。

ctr1=0 
ctr2=0 

local function doCmdChk() 
     ctr1 = ctr1 + 1 
     http.get("http://192.168.2.38/ICmd.py?i=" .. ctr1 , nil, 
     function(rspCode, payload) 
      sendFlag=true 
      tmr.start(1) 
     end) 
end 

local function sendData() 
     ctr2 = ctr2 + 1 
     local msgBdy = '{"s":"' .. ctr2 .. '","i":"test23", "d":"heap='..node.heap()..'"}' 

     http.post("http://192.168.2.38/DeviceScan.py", "Content-Type: text/json\r\n", msgBdy, 
     function(rspCode, payload) 
      sendFlag=true 
      tmr.start(2) 
     end) 
end 

--mainline start: 
tmr.alarm(1, 3000, tmr.ALARM_SEMI, function() node.task.post(node.task.MEDIUM_PRIORITY, doCmdChk) end) 
tmr.alarm(2, 5000, tmr.ALARM_SEMI, function() node.task.post(node.task.HIGH_PRIORITY, sendData) end) 

しかし、HTTPコールバックのいずれかを実行しているの数時間後に

が呼び出されていなかったので、そこにされている必要があります:次のように私はnode.task.post()のオプション、テストスクリプトを試してみました

衝突。

0

NodeMCUについてよく分かりませんが、参照マニュアルによれば、応答を受け取ったときにhttp.posthttp.getコールバック関数が呼び出されます。したがって、タイマーは、応答が受信されたときにのみ再開されます。何かチャンスが遅れている、あるいは決して応答を得られないかもしれませんか?

サードパーティのものが応答した後にタイマーを再起動すると、可変遅延が追加されるため、あまり正確ではありません。私はそれがいくつかのテストコードほど正確であるとは思っていません。

デバッグのために、呼び出されたコールバック間の実際の遅延や、ポスト/ゲットとレスポンスの間の遅延を表示することをお勧めします。

+0

あなたのコメントは面白いです。 Nodemcuには、2つのhttp要求が1つずつ次々と送信されるケースがありました.2番目の要求に対する応答では、コールバック関数が呼び出されませんでした。 http呼び出しの間に1秒の遅延を挿入すると、この問題が解決しました。私は、2つのタイマーが独立して動作していて、2つのhttpリクエストが近くにあるような状況を作り出すのだろうかと思います。私は、このような衝突が発生しているかどうかを確認するためにいくつかのテストを行います。 – Jonathan

+0

@Jonathan https://github.com/nodemcu/nodemcu-firmware/issues/1258を参照してください。 –

関連する問題