NodeMCU 计时器意外停止
NodeMCU timer stops unexpectedly
我有一个使用两个计时器的 NodeMCU Lua 应用程序。每个计时器调用一个函数,该函数导致向本地服务器发出 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)
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 请求,但是当应用程序 运行s 几个小时后最终会出现相同的结果(即其中一个计时器停止 运行宁)。减少 HTTP 请求之间的时间会使错误发生得更快。
有人遇到过这个问题吗?有没有人对如何解决此问题有任何想法? (无法可靠地发送连续的 HTTP 请求是此应用程序的障碍)。
我对 NodeMCU 了解不多,但根据参考手册,收到响应时会调用 http.post
和 http.get
回调函数。因此,计时器仅在收到响应时才重新启动。有没有可能有延迟,或者您可能永远得不到回应?
在某些第三方响应后重新启动计时器会增加可变延迟,因此不应该非常精确。我不希望它像某些测试代码那样准确。
对于调试,我建议您打印调用回调之间的实际延迟或 post/get 和响应之间的延迟。
解决方案是设置标志,以便在任何给定时间只有一个 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 回调,所以一定是发生了冲突。
我有一个使用两个计时器的 NodeMCU Lua 应用程序。每个计时器调用一个函数,该函数导致向本地服务器发出 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)
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 请求,但是当应用程序 运行s 几个小时后最终会出现相同的结果(即其中一个计时器停止 运行宁)。减少 HTTP 请求之间的时间会使错误发生得更快。
有人遇到过这个问题吗?有没有人对如何解决此问题有任何想法? (无法可靠地发送连续的 HTTP 请求是此应用程序的障碍)。
我对 NodeMCU 了解不多,但根据参考手册,收到响应时会调用 http.post
和 http.get
回调函数。因此,计时器仅在收到响应时才重新启动。有没有可能有延迟,或者您可能永远得不到回应?
在某些第三方响应后重新启动计时器会增加可变延迟,因此不应该非常精确。我不希望它像某些测试代码那样准确。
对于调试,我建议您打印调用回调之间的实际延迟或 post/get 和响应之间的延迟。
解决方案是设置标志,以便在任何给定时间只有一个 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 回调,所以一定是发生了冲突。