Sketch of a test MQTT client recovers most errors and uses software WDT for rest

This sketch publishes a message to a MQTT broker on port 1883, no SSL. I've spent many months off and on to get a MQTT client that doesn't hang forever and so far this seems to manage either to retry with success some errors and when it hangs the software watch dog timer triggers and the MKR1500 restarts. It powers on the modem, publishes a message, powers off the modem, and enters deepSleep. Not exactly what I'd like to have but think for my target application will work. This test program has been extracted from the application that monitors liquid level in storage tanks and publishes a message four times a day with the sensor readings. In between it wakes up and checks for alert conditions such as level is dropping, if so publish an alert thus if all is well the modem will only be powered on for a short period four times a day.

The sketch may not be a solution to others but hopefully will help someone and maybe be enhanced. My thanks go out to the folks on this forum who have shared their discoveries and solutions.

Component Levels
MKRNB Library level 1.4.0
Ardiono MQTT Client level 0.1.5
SARA firmware level L0.0.00.00.05.11,A.02.16

Link to Sketch

There are several modifications to the MKRNB 1.4.0 library with the diffs:

--- MKRNB-1.4.0/src/Modem.cpp 2020-12-03 05:33:05.000000000 -0600
+++ Arduino/libraries/MKRNB/src/Modem.cpp 2020-12-03 20:24:11.036373999 -0600
@@ -166,7 +166,7 @@
{
send("AT+CFUN=15");

  • return (waitForResponse(1000) == 1);
  • return (waitForResponse(180000) == 1); // MODIFIED reset can take some time
    }

size_t ModemClass::write(uint8_t c)
diff -u MKRNB-1.4.0/src/NBClient.cpp Arduino/libraries/MKRNB/src/NBClient.cpp
--- MKRNB-1.4.0/src/NBClient.cpp 2020-12-03 05:33:05.000000000 -0600
+++ Arduino/libraries/MKRNB/src/NBClient.cpp 2020-12-03 20:22:30.216056959 -0600
@@ -317,8 +317,9 @@
MODEM.send(command);
if (_writeSync) {
String response;

  • int status = MODEM.waitForResponse(10000, &response);
  • int status = MODEM.waitForResponse(240000, &response); // MODIFIED send can take longer than10 seconds
    if ( status != 1) {
  • written = 0; // MODIFIED let caller know send failed.
    if (status == 4 && response.indexOf("Operation not allowed") != -1 ) {
    stop();
    break;
    @@ -437,7 +438,7 @@
    }

MODEM.sendf("AT+USOCL=%d", _socket);

  • MODEM.waitForResponse(10000);
  • MODEM.waitForResponse(360000); // MODIFIED close can take a long time

NBSocketBuffer.close(_socket);

@@ -455,4 +456,4 @@
}
}
}
-}
\ No newline at end of file
+}

I don't know if it has anything to do with this sketch or not but the MKR1500 no longer works. There is no response for AT commands. I've been running basically this same code for a couple of months, tweaking here and there. One thing I did change was moved to MKRNB 1.4.0 library but wouldn't think that would be the cause. I have another board and it works. Anyone know how I can find if the problem is SARA or maybe the uart is failing on the SAMD?

I guess you already tried MKRNB->Tools>SerialSARAPasstrough ?!?
With this sketch loaded into the MKR it's also possible to use the uConnect Software from ublox for debugging!

I did try it and send an AT command and got no response. But I will try their program as maybe it does something and can connect. Thanks.

I'm running my other MKR1500 and its running OK, hope it doesn't die. Anyway it ran over 3 days without hanging and triggering the software WDT and it did restart OK. Think the main reason for triggering the SWDT has been not connecting to cellular so maybe this module works better than the one that died or the cell tower just happens to be doing better the last few days.

I think this is more or less the same problem as in

I use the MQTT lib from GitHub - 256dpi/arduino-mqtt: MQTT library for Arduino
with good results with a Mosquitto broker under Ubuntu. Maybe a little more convenient...

About the dead mkr : Mr
janakelarsson
wrote about bricking his modem with no proper shutdown and added some remedy to the libs.
Maybe yours is bricked the same way. Add hardReset() by janakelarsson · Pull Request #64 · arduino-libraries/MKRNB · GitHub

I just added a
// Proper Modem Shutdown
MODEM.sendf("AT+CFUN=15");
MODEM.waitForResponse(10000);
to the WD Shutdown... Merry Christmas

I changed my sleep to 30 minutes and the program has been running for over 4 days with no WDT resets. Possibly the AT&T tower doesn't like the activity when the sleep is 15 seconds under some circumstances. I stopped it just now and added the suggested code above to the WD shutdown. Maybe that will eliminate bricking the modem. In my opinion the modem should be tougher than that and not die in this case. Would expect it to survive any abrupt resets, power losses, and etc. Just to make sure that the UART on the SAMD didn't die, I soldered a USB cable to the board so that could connect directly to the modem and verified that the modem won't answer AT commands, which was no surprise.