我正在使用 NodeMCU 构建基于 ESP8266 的电池供电物联网设备。我使用 mqtt 定期执行测量并发布结果。我知道,要允许网络堆栈运行,我应该避免紧密循环并依赖回调函数。因此,在我看来,我的测量代码的正确组织应该是:
interval=60000000
function sleep_till_next_sample()
node.dsleep(interval)
end
function close_after_sending()
m:close()
sleep_till_next_sample()
end
function publish_meas()
m:publish("/test",result,1,0,close_after_sending)
print("published:"..result)
end
function measurement()
-- The omitted part of the function accesses
-- the hardware and places results
-- in the "result" variable
m = mqtt.Client("clientid", 120, "user", "password")
m:connect("172.19.1.254",1883,0, publish_meas)
end
init.lua 确保节点已连接到 WiFi AP(如果没有,它最多重试 20 次,如果没有建立连接,它会使节点进入睡眠状态,直到下一次测量时间)。WiFi连接完成后,调用测量函数。
有趣的是,上面的代码不起作用。控制台中没有显示错误,但是 mqtt 代理没有收到已发布的消息。为了使其正常工作,我必须通过在回调函数中添加计时器来添加额外的空闲时间。
最终工作的代码如下所示:
interval=60000000
function sleep_till_next_sample()
node.dsleep(interval)
end
function close_after_sending()
m:close()
tmr.alarm(1,500,0,function() sleep_till_next_sample() end)
end
function publish_meas()
m:publish("/test",result,1,0,function() tmr.alarm(1,500,0,close_after_sending) end)
print("published:"..result)
end
function measurement()
-- The omitted part of the function accesses
-- the hardware and places results
-- in the "result" variable
m = mqtt.Client("clientid", 120, "user", "password")
m:connect("172.19.1.254",1883,0, function() tmr.alarm(1,500,0, publish_meas) end)
end
以上工作,但我不确定它是否是最佳的。为了节省电池电量,我希望在测量完成并公布结果后,尽量减少节点进入睡眠状态的时间。
有没有更好的方法来链接对 m:connect、m:publish、m:close 和最后的 node.dsleep 的必要调用,以便在最短的时间内正确发布结果?