使用NodeMCU上的ESP8266进行MQTT - 发布问题

我正在基于ESP8266和NodeMCU构建一个电池供电的IoT设备。

我使用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,以便在最短时间内正确地发布结果?

点赞
用户4331874
用户4331874

也许这个问题已经在更近期的固件中解决了。我正在解决一个问题,我认为这个问题可能有一定的解释,因此我尝试按照描述的方式重现问题。

我简化的测试代码基本相似;它从mqtt.Client.publish()的PUBACK回调函数中调用dsleep():

m = mqtt.Client("clientid", 120, "8266test", "password")

m:lwt("/lwt", "offline", 0, 0)

function main(client)
    print("connected - at top of main")

m:publish("someval",12345,1,0, function(client)
    rtctime.dsleep(SLEEP_USEC)
    end)
end

m:on("connect", main)
m:on("offline", function(client) is_connected = false print ("offline") end)

m:connect(MQQT_SVR, 1883, 0, mainloop,
                         function(client, reason) print("failed reason: "..reason) end)

当运行时,它成功发布到我的MQTT代理。

我使用的是:

    NodeMCU custom build by frightanic.com
            branch: master
            commit: 81ec3665cb5fe68eb8596612485cc206b65659c9
            SSL: false
            modules: dht,file,gpio,http,mdns,mqtt,net,node,rtctime,sntp,tmr,uart,wifi
     build  built on: 2017-01-01 20:51
     powered by Lua 5.1.4 on SDK 1.5.4.1(39cb9a32)
2017-01-07 13:45:43