2016-05-13 37 views
1

我有一個使用兩個計時器的NodeMCU Lua應用程序。每個計時器都會調用一個函數,該函數會導致向本地服務器發出HTTP請求。NodeMCU計時器意外停止

經過幾次迭代後,其中一個定時器停止,另一個定時器繼續。計時器停止之前的迭代次數似乎是隨機的。我已經多次運行測試腳本,並且定時器停止的點也不相同。注意:它並不總是與暫停的計時器相同。

下面是一些測試代碼,可靠地說明此問題:

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請求的測試代碼,但是當應用程序運行幾個小時同樣的結果最終發生(即其中一個定時器停止運行)。減少HTTP請求之間的時間會使錯誤更早發生。

有沒有人遇到過這個問題?有沒有人有任何想法如何解決這個問題? (不能夠可靠地發送連續的HTTP請求是這個應用程序的一個阻礙)。

回答

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發送功能,繼續按預期運行。

我試過node.task.post()選項,測試腳本如下:

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回調的一個小時後,沒有被引用,那麼一定有碰撞。

0

我對NodeMCU瞭解不多,但根據參考手冊,當收到響應時會調用回調函數http.posthttp.get。因此定時器僅在收到響應時纔會重新啓動。有沒有延遲的機會,或者你永遠不會得到迴應?

一些第三方的東西已經響應後重新啓動定時器會增加一個可變延遲,因此不應該非常精確。我不希望它和某些測試代碼一樣準確。

對於調試,我建議您打印被調用的回調之間的實際延遲或post/get和response之間的延遲。

+0

您對回調函數的評論很有趣。我在Nodemcu中有一個情況,那裏有兩個http請求一個接一個地做,而對第二個請求的響應從未調用回調函數。在http調用之間插入一個1秒的延遲解決了這個問題。我想知道兩個獨立運行的定時器是否會產生類似的情況(兩個http請求靠近在一起)。我會做一些測試,看看是否會發生這樣的碰撞。 – Jonathan

+0

@Jonathan參見https://github.com/nodemcu/nodemcu-firmware/issues/1258 –