Mark
Mark

Reputation: 523

NodeMCU ESP8266MOD Esplorer MQTT simple MQTT by foobarflies

I am a C# .net Xamarin developer who is now stuck porting an MQTT client to an ESP8266MOD wifi chip because the guy who was supposed to do it didn't.

Anyhow not knowing much of anything I have flashed a custom NodeMCU build from fightanic with file, gpio, http, i2c, mqtt, net, node, tmr, uart, wifi. I am following a simple MQTT project by foorbarflies.

I have uploaded the following files to a freshly flashed chip:

-- file : config.lua
local module = {}

module.SSID = {}  
module.SSID["xxxxx xxxxxxx"] = "xxxxxxxxxxxxxxxxx"

module.HOST = "mqtt.xxxxxxxxxxx.com"  
module.PORT = 1883  
module.ID = node.chipid()

module.ENDPOINT = "nodemcu/"  
return module  

-- file: setup.lua
local module = {}

local function wifi_wait_ip()  
  if wifi.sta.getip()== nil then
    print("IP unavailable, Waiting...")
  else
    tmr.stop(1)
    print("\n====================================")
    print("ESP8266 mode is: " .. wifi.getmode())
    print("MAC address is: " .. wifi.ap.getmac())
    print("IP is "..wifi.sta.getip())
    print("====================================")   
    app.start()
  end
end

local function wifi_start(list_aps)  
    if list_aps then
        for key,value in pairs(list_aps) do
            if config.SSID and config.SSID[key] then
                wifi.setmode(wifi.STATION);
                wifi.sta.config(key,config.SSID[key])
                wifi.sta.connect()
                print("Connecting to " .. key .. " ...")
                --config.SSID = nil  -- can save memory
                tmr.alarm(1, 2500, 1, wifi_wait_ip)
            end
        end
    else
        print("Error getting AP list")
    end
end

function module.start()  
  print("Configuring Wifi ...")
  wifi.setmode(wifi.STATION);
  wifi.sta.getap(wifi_start)
end

return module  


-- file : application.lua
local module = {}  
m = nil

-- Sends a simple ping to the broker
local function send_ping()  
    m:publish(config.ENDPOINT .. "ping","id=" .. config.ID,0,0)
end

-- Sends my id to the broker for registration
local function register_myself()  
    m:subscribe(config.ENDPOINT .. config.ID,0,function(conn)
        print("Successfully subscribed to data endpoint")
    end)
end

local function mqtt_start()  
    m = mqtt.Client(config.ID, 120)
    -- register message callback beforehand
    m:on("message", function(conn, topic, data) 
      if data ~= nil then
        print(topic .. ": " .. data)
        -- do something, we have received a message
      end
    end)
    -- Connect to broker
    m:connect(config.HOST, config.PORT, 0, 1, function(con) 
        register_myself()
        -- And then pings each 1000 milliseconds
        tmr.stop(6)
        tmr.alarm(6, 1000, 1, send_ping)
    end) 

end

function module.start()  
  mqtt_start()
end

return module  



-- file : test.lua
app = require("application")  
config = require("config")  
setup = require("setup")

setup.start()

I sent the command dofile("test.lua");

and I get .......

esplorer grab

It seems I should see some of the strings from application.lua like "ping" or "successfully subscribed" but I am getting nothing. It's like application.lua is not running.

Any help would be appreciated. Thanks in advance.

-- Mark

Update

I added a string directly before the connect object and it printed so it seems to be locking up on the connect object working on that now.

Upvotes: 0

Views: 558

Answers (1)

Marcel Stör
Marcel Stör

Reputation: 23535

It's really difficult to wade through that much code just to understand what it actually does. Over here we prefer minimal, complete, and verifiable examples.

It seems you understand the logic behind the code you copy-pasted, right? That tutorial is actually really nice - but it's from 07 Oct 2015. Since it's fairly old glitches and bugs are to be expected. A lot has changed in the NodeMCU firmware in the meantime.

The problem obviously must be in application.lua. To understand NodeMCU MQTT I suggest you take a look at the example in our documentation. It says:

m:connect("192.168.11.118", 1883, 0, function(client)
  print("connected")
  -- Calling subscribe/publish only makes sense once the connection
  -- was successfully established. You can do that either here in the
  -- 'connect' callback or you need to otherwise make sure the
  -- connection was established (e.g. tracking connection status or in
  -- m:on("connect", function)).

  -- publish a message with data = hello, QoS = 0, retain = 0
  client:publish("/topic", "hello", 0, 0, function(client) print("sent") end)

Your send_ping(), however, is invoked asynchronously from the timer (tmr.alarm(6, 1000, 1, send_ping)) and just silently assumes to be connected to the broker rather than connecting first and then publishing.

Upvotes: 0

Related Questions