带有NodeMCU的ESP8266上的MQTT-发布问题 [英] MQTT on ESP8266 with NodeMCU - problems with publishing

查看:215
本文介绍了带有NodeMCU的ESP8266上的MQTT-发布问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在基于NodeMCU构建基于ESP8266的电池供电的IoT设备. 我使用mqtt定期执行测量并发布结果. 我知道,要允许网络堆栈运行,我应该避免紧密的循环并依靠回调函数.因此,在我看来,我的测量代码的正确组织应该是:

I'm building a battery powered IoT device based on ESP8266 with NodeMCU. I use mqtt to periodically perform measurements and publish results. I know, that to allow network stack running, I should avoid tight loops and rely on callback functions. Therefore it seemed to me that the right organization of my measurement code should be:

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连接完成后,它将调用测量功能.

The init.lua ensures, that the node has connected to the WiFi AP (if not, it retries up to 20 times, and if no connection is established, it puts the node on sleep until the next measurement time). After WiFi connection is done, it calls the measurement function.

有趣的是,上面的代码不起作用.控制台中未显示任何错误,但mqtt代理未收到已发布的消息. 为了使其正常工作,我必须通过在回调函数中添加计时器来增加额外的空闲时间.

The interesting thing is, that the above code doesn't work. There are no errors displayed in the console, but the mqtt broker does not receive published messages. To make it working, i had to add additional idle time, by adding timers in the callback functions.

最终有效的代码如下:

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

以上方法有效,但是我不确定它是否最佳.为了节省电池电量,我想在测量完成并发布结果之后,将节点进入睡眠状态的时间减至最少.

The above works, but I'm not sure if it is optimal. To conserve the battery power I'd like to minimize the time before the node is put on sleep after the measurement is completed and results published.

是否有更好的方法将必要的调用链接到m:connect,m:publish,m:close以及最后的node.dsleep,以便在最短的时间内正确发布结果?

Is there any better way to chain the necessary calls to m:connect, m:publish, m:close and finally node.dsleep so, that the results are correctly published in the minimal time?

推荐答案

也许这是由较新的固件解决的.我正在解决一个我认为可能对此问题有所解释的问题,因此请尝试重现该问题.

Perhaps this was solved by more recent firmware. I am working through a problem that I thought might be somewhat explained by this issue, so tried to reproduce the problem as described.

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

My simplified test code is substantially similar; it calls dsleep() from the PUBACK callback of mqtt.Client.publish():

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代理.

and when run, does successfully publish to my MQTT broker.

我正在使用:

    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)

这篇关于带有NodeMCU的ESP8266上的MQTT-发布问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆