首页 文章

带有NodeMCU的ESP8266上的MQTT - 发布问题

提问于
浏览
0

我正在使用带有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次,如果没有 Build 连接,则将节点置于休眠状态直到下一个测量时间) . 完成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,以便在最短的时间内正确发布结果?

1 回答

  • 1

    也许这是通过更新的固件解决的 . 我正在解决一个我认为可能在某种程度上解释过这个问题的问题,因此试图按照描述重现问题 .

    我的简化测试代码基本相似;它从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)
    

相关问题