MQTT on ESP8266 with NodeMCU - problems with publishing

0 votes

Objective: Building a battery powered IoT device based on ESP8266 with NodeMCU. 

Methodology :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 as below)

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

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.

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.

The finally working code looks like below:

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

PS: 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.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?

Any help would be much appreciated. Thanks in advance.

Aug 13, 2018 in IoT (Internet of Things) by Matt
• 2,260 points

edited Aug 16, 2018 by Matt 343 views

1 answer to this question.

0 votes

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.

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)

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

I am using:

    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)
answered Aug 13, 2018 by anonymous2
• 4,260 points

Related Questions In IoT (Internet of Things)

0 votes
1 answer
0 votes
1 answer

What is the best way to retrofit existing alarm PIR with esp8266/etc?

Here is an explanation that best fits ...READ MORE

answered Sep 4, 2018 in IoT (Internet of Things) by anonymous2
• 4,260 points
68 views
0 votes
1 answer

MQTT pubish is slow to send with ESP8266 & NodeMCU

I think you're almost correct and on ...READ MORE

answered Aug 1, 2018 in IoT (Internet of Things) by nirvana
• 3,060 points
749 views
0 votes
1 answer

How to send a data from arduino uno to a webpage through esp8266 wifi module?

You are missing a few \r\n and the length ...READ MORE

answered Aug 9, 2018 in IoT (Internet of Things) by anonymous2
• 4,260 points
1,535 views
0 votes
1 answer

Using ESP8266 for controlling through Arduino

Please explain better your problem. In Arduino-Esp8266 String ...READ MORE

answered Sep 11, 2018 in IoT (Internet of Things) by anonymous2
• 4,260 points
70 views
0 votes
1 answer

NodeMCU HTTP : How to use HTTPS post request?

Your firmware might not have SSL/TLS enabled. ...READ MORE

answered Feb 11 in IoT (Internet of Things) by Shubham
• 13,310 points
413 views
0 votes
1 answer
0 votes
1 answer

Publishing commands to device in IBM IoT using MQTT in Java

If you are publishing from an application, ...READ MORE

answered Jul 27, 2018 in IoT (Internet of Things) by anonymous2
• 4,260 points
458 views