Hello NodeRED community. I hope everyone is doing well. I am new to MQTT, but it seems very useful! I am having some trouble with it, but let me explain my situation first.
I have a RaspberryPi running DietPi, since this OS makes it so easy to get SSH, NodeRED, and Mosquitto up and running. I have an Arduino-type microcontroller that sends sensor data to the Mosquitto MQTT broker. I am using the help of an Arduino community library for MQTT on my microcontroller. The project requires me to send sensor data once per 15 minutes. I am able to send sensor data once to the MQTT subscribe node in NodeRED and then that's it, NodeRED never receives an MQTT message again, unless I restart my microcontroller or restart the NodeRED flow. After debugging with serial messages, I can confidently say that the flow/logic of my microcontroller's code is not the problem. I suspect I have not setup MQTT correctly, even though everything says it's connected without error messages. Your advice is greatly appreciated! Thank you.
Are you sure your arduino isn’t the culprit? Try installing an MQTT tracking program on another pc or your phone to see what is getting published
Is it possible to easily alter your code so it sends , say every 30 seconds or so ? That way when you follow @zenofmud 's suggestion you'll have more data to look at.
MQTT explorer is the tool to examine what your mosquito broker is receiving from your arduino
Thank you, everyone, for getting back to me so quickly! Before getting into MQTT Explorer (which is a cool program, thanks @crymplecy), I tried following @gerry's advice, and it resulted in some interesting behavior. It was easy enough for me to change the microcontroller's code to send the sensor data every 30 seconds, or rather, twice a minute. In this case, I was able to receive two MQTT messages before they stopped. This made me wonder if the issue has anything to do with the "Keep Alive" property in the MQTT broker connection properties, whose default is "60." To test my hypothesis, I changed the microcontroller's code again, but this time to send the sensor data every 15 seconds, or rather, four times a minute. What I expected was to receive four MQTT messages before they stopped. However, what happened in this case, was the uninterrupted receiving of MQTT messages every 15 seconds (for a couple of hours before I stopped it myself)! While not critical for this post, it is worth mentioning that the sensor data and its format is correct in every received MQTT message.
So, I'm not entirely sure how to interpret these results, but this at least leads me to think that my MQTT broker node in NodeRED is not configured correctly. Let me share with you the default properties it currently has.
MQTT Broker node > Properties > Connection:
Protocol: MQTT V3.1.1
Client ID: "Leave blank for auto generated"
Keep Alive: 60
iSession: "Use clean session" is checked
MQTT subscribe node > Properties:
Action: Subscribe to a single topic
Topic: "The name of the microcontroller"
Output: auto-detect (but it's always a string)
Name: "The name of the microcontroller"
Have you changed the default broker configuration in any way? And when you say you received the data are you referring to seeing it in mqtt explorer or in a arduino or what?
Hello @gerry! I hope you had a good weekend. I have not done anything to Mosquitto - the MQTT broker. I simply installed it from the DietPi OS applications menu (reference). As for your second question, forgive me if I wasn't clear. I am trying to send sensor data from the Arduino to NodeRED (through Mosquitto). So, when I say I have received data, I mean that I have received the data in NodeRED (debug messages).
Any chance of you using MQTT explorer to give another view on what may be happening?
It's not difficult to set up the Arduino code so that it subscribes to an mqtt topic as well as publishing the sensor data.
That way node-red can actively request sensor data as well as monitor any failure to respond.
But in fact I now have switched from Arduino firmware to Tasmota because although it's a bit strange to start with, everything in tasmota works around Mqtt.
Hello @cymplecy. I gave MQTT Explorer a try, and it experiences the same behavior. When the Arduino code is set to send sensor data every 15 minutes, MQTT Explorer receive one message, and then never again (same in NodeRED).
So what that means is that your broker is considering the connection to have died sometime between 15 secs (as that works) and 15 minutes.
The best approach (if possible) is for your Arduino to set the keepalive time to something like 30 minutes.
Check with the documentation for the library that you are using if that is possible to do
Hello @cymplecy. Thank you for your advice. Unfortunately, this MQTT community library that I'm using doesn't have much documentation (at least on its github page). So, I went looking for any mention of "keepalive" in the header files and found a function called "client.loop()". I put this function in the main arduino loop and that seems to keep the microcontroller connected to Mosquitto! I am now receiving the sensor data every 15 minutes! I am going to let it run all day before confirming that this is the solution. So, what I've learned is that it's not enough to simply connected to the MQTT broker, but you must also maintain a connection with it.
Client.loop tells the arduino to check for messages which in turn does generate traffic. There are two wifi commands you may want to to look at as well. Wifi.autoreconnect(true) and wifi.persistant(true). Working from memory so check spelling.
You did not mention which MQTT Library you used.
There are many to choose from.
I suggest to start with 'pubsubclient'
I would never touch an Arduino library which does not have documentation and examples. The examples are the key. Usually I start with an unchanged example (if possible) and once I have this running, add the example code to my own code.
If you run ESP32 or ESP8266 chips, then you most probably run a TCP/IP and WiFi stack. The basic network handling is done in the background.
But when you add network applications like MQTT, OTA or NTP, then these protocols need to act on incoming data packets, or send packets to keep a connection alive. This is done with a call in the loop() section of the code. You'll see this in the examples.
On a side note: if you use long delay() statements, then you break the network stacks. Use timers instead. There are simple ones like 'every'.
Hope this helps somewhat.
Hello, everyone! My microcontroller has indeed been able to upload its sensor data to NodeRED reliably every 15 minutes for over a day. I think it's safe to say that the "client.loop()" function in the main Arduino loop is the solution! Thank you, @gerry, for explaining what it is.
I originally had thought that there was a problem with NodeRED, as opposed to Arduino code, hence why I posted my issue in the NodeRED forum. I apologize for any inconvenience. I truly thank you, everyone, for your patience, time, advice, and for being an active community.