Reputation: 523
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 .......
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
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
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