1
votes

I have a problem with the following Lua code on an ESP8266...

function sendData(humidity,temperature)
    -- Setup MQTT client and events
    print("sendData() entered")
    print("Setting up mqtt.Client...")
    m = mqtt.Client(mqtt_client_id, 120, username, password)
    print("Attempting client connect...")
    m:connect(mqtt_broker_ip , mqtt_broker_port, 0, function(conn)
        print("Connected to MQTT")
        print("  IP: " .. mqtt_broker_ip)
        print("  Port: " .. mqtt_broker_port)
        print("  Client ID: " .. mqtt_client_id)
        print("  Username: " .. mqtt_username)

        payload = "Temp: " .. temperature .. " Hmdy: " .. humidity
        m:publish("pt/env",payload, 0, 0, function(conn)
            print("Going to deep sleep for " .. (DSLEEPTIME/1000) .. " seconds")
            node.dsleep(DSLEEPTIME*1000,4)             
        end)
    end)
end

The code is being successfully called with the following...

-- Connect to network
wifi.setmode(wifi.STATION)
wifi.setphymode(wifi_signal_mode)
wifi.sta.config(wifi_SSID, wifi_password) 
wifi.sta.connect()

print("Attempting to connect...")
ip = wifi.sta.getip()
if ip ~= nil then
    print("Got IP: " .. ip)
    print("About to call sendData()...")
    sendData(humidity, temperature)
    print("Returned from sendData()...")
end

Using ESPlorer I see the following...

Attempting to connect...
Attempting to connect...
Attempting to connect...
Attempting to connect...
Attempting to connect...
Attempting to connect...
Got IP: 192.168.0.39
About to call sendData()...
sendData() entered
Setting up mqtt.Client...
Attempting client connect...
Returned from sendData()...

So it basically enters sendData(...) and I see the output from the line...

print("Attempting client connect...")

...but I never see the logging in the m:connect(...) block such as...

print("Connected to MQTT")

...it seems it simply returns immediately.

The MQTT broker is a Raspberry Pi running Mosquitto and I've tested it with apps on my Android phone and tablet. I get successful publishing / subscription between phone and tablet in both directions.

I'm a Lua novice and only understand the basics of MQTT and I'm at a loss for what's wrong with the m:connect(...) block if anyone can help it would be appreciated.

UPDATE: PROBLEM SOLVED - Apologies for not getting back to this thread sooner. The problem was simply down to the version of Mosquitto I was running on my RPi (which complied to MQTT v3.1). The NodeMCU MQTT library supports MQTT v3.1.1 and is NOT backward compatible. In essence there wasn't very much wrong with my code although I did make some changes - it was simply down to MQTT versions being incompatible.

2
I guess your connection attempt fails so nothing happens. What do you expect to happen?Piglet
Did you solve it, case closed?Marcel Stör
@MarcelStör : I have added an update / comment to the end of my original question explaining the cause of the problem. Thanks for trying to help - I did modify my code based on your suggestions but I had to 'clean' my RPi to force a download of a more recent version of Mosquitto to get things working.Squonk
Ah, good to know. Don't you want to add it as an answer an self-accept it? No need to have this show up on the list of open NodeMCU questions IMHO.Marcel Stör
@MarcelStör : Sure. I'll add an answer when I've looked up what it was I did to fix the problem (I can't remember exactly at the moment) I'm currently struggling with a C++ / Arduino ESP8266 issue which I should have fixed soon. :)Squonk

2 Answers

1
votes

You didn't tell us what NodeMCU version you use. Warning: do NOT use any of the pre-built 0.9.x binaries available at https://github.com/nodemcu/nodemcu-firmware/releases. Build your own firmware as per http://nodemcu.readthedocs.io/en/dev/en/build/.

I always helps to strip a failing function and to make use of all available callback functions. I can confirm the following works on a nearly 2 months old firmware from the dev branch sending data to cloudmqtt.com:

function sendData(humidity, temperature)
    print("Setting up mqtt.Client...")
    m = mqtt.Client("SO-36667049", 120, "user", "password")
    print("Attempting client connect...")
    m:connect("m20.cloudmqtt.com", 12703, 0, 0,
        function(conn)
            print("Connected to MQTT")
            payload = "Temp: " .. temperature .. " Hmdy: " .. humidity
            m:publish("topic", payload, 0, 0, 
                function(client) 
                    print("Message sent") 
                end)
        end,
        function(client, reason)
            print("Connection failed, reason: " .. reason)
        end)
end

Differences:

  • m:connect defines secure y/n and autoreconnect y/n explicitly. It always confuses me if only a subset of all optional parameters is set. Is your 0 in m:connect interpreted as secure or as autoreconnect? I don't know Lua well enough to tell why I code it explicitly.
  • Make use of the extra callback for function for failed connection attempts. See http://nodemcu.readthedocs.org/en/dev/en/modules/mqtt/#connection-failure-callback-reason-codes for failure reason codes.
  • Do NOT use the same name for variables in callback functions as used in "parent" functions. Note how you use m:connect(..., function(conn) and then inside that function you use m:publish(..., function(conn) again. You don't interact with the conn object in your code, so no harm done. However, this may bite you in other projects.
0
votes

Your code is looking fine. If m:connect fails nothing will happen as you did not provide a callback function for failed connection attempts.

Also you don't check m:connect's return value for success.

Refer to http://nodemcu.readthedocs.org/en/dev/en/modules/mqtt/#mqttclientconnect

And check if your connection attempt fails.