I am using a LILYGO® TTGO T-SIM7600 ESP32 (ESP32-WROVER and SIM7600) as the location where it will be has no wireless and only 3/4G connectivity.
This is the example code that I started with and its runs as network connects, then I can send a MQTT topic to toggle the LED but around 24hrs it cannot reconnect to MQTT being broker.hivemq.com. Error below…
No other error. Network (4G) is connected and registered just the MQTT connection is failing after approx 24hrs.
Is there a timeout? What am I missing or need to look for? Reading this below…
Do I just need to disconnect and reconnect?
This code is based on Tiny_GSM MQTTClient and the PubSubClient.h library.
Or do I revise the keep alive?
// Set the keep-alive interval to 30 seconds
mqttClient.setKeepAlive(30);
Or add a disconnect
mqtt.disconnect(); // Disconnect from MQTT
I am expecting this code to keep the SIM connected waiting for MQTT messages, in this case the LED toggle topic.
/**************************************************************
*
* For this example, you need to install PubSubClient library:
* https://github.com/knolleary/pubsubclient
* or from http://librarymanager/all#PubSubClient
*
* TinyGSM Getting Started guide:
* https://tiny.cc/tinygsm-readme
*
* For more MQTT examples, see PubSubClient library
*
**************************************************************
* This example connects to HiveMQ's showcase broker.
*
* You can quickly test sending and receiving messages from the HiveMQ webclient
* available at http://www.hivemq.com/demos/websocket-client/.
*
* Subscribe to the topic GsmClientTest/ledStatus
* Publish "toggle" to the topic GsmClientTest/led and the LED on your board
* should toggle and you should see a new message published to
* GsmClientTest/ledStatus with the newest LED status.
*
**************************************************************/
#define TINY_GSM_MODEM_SIM7600
// Set serial for debug console (to the Serial Monitor, default speed 115200)
#define SerialMon Serial
// Set serial for AT commands (to the module)
// Use Hardware Serial on Mega, Leonardo, Micro
#define SerialAT Serial1
// See all AT commands, if wanted
//#define DUMP_AT_COMMANDS
// Define the serial console for debug prints, if needed
#define TINY_GSM_DEBUG SerialMon
// Add a reception delay, if needed.
// This may be needed for a fast processor at a slow baud rate.
// #define TINY_GSM_YIELD() { delay(2); }
// Define how you're planning to connect to the internet
// These defines are only for this example; they are not needed in other code.
#define TINY_GSM_USE_GPRS true
#define TINY_GSM_USE_WIFI false
// set GSM PIN, if any
#define GSM_PIN ""
// Your GPRS credentials, if any
const char apn[] = "YourAPN";
const char gprsUser[] = "";
const char gprsPass[] = "";
// Your WiFi connection credentials, if applicable
const char wifiSSID[] = "YourSSID";
const char wifiPass[] = "YourWiFiPass";
// MQTT details
const char *broker = "broker.hivemq.com";
const char *topicLed = "GsmClientTest/led";
const char *topicInit = "GsmClientTest/init";
const char *topicLedStatus = "GsmClientTest/ledStatus";
#include <TinyGsmClient.h>
#include <PubSubClient.h>
#include <Ticker.h>
#include <SPI.h>
#include <SD.h>
// Just in case someone defined the wrong thing..
#if TINY_GSM_USE_GPRS && not defined TINY_GSM_MODEM_HAS_GPRS
#undef TINY_GSM_USE_GPRS
#undef TINY_GSM_USE_WIFI
#define TINY_GSM_USE_GPRS false
#define TINY_GSM_USE_WIFI true
#endif
#if TINY_GSM_USE_WIFI && not defined TINY_GSM_MODEM_HAS_WIFI
#undef TINY_GSM_USE_GPRS
#undef TINY_GSM_USE_WIFI
#define TINY_GSM_USE_GPRS true
#define TINY_GSM_USE_WIFI false
#endif
#ifdef DUMP_AT_COMMANDS
#include <StreamDebugger.h>
StreamDebugger debugger(SerialAT, SerialMon);
TinyGsm modem(debugger);
#else
TinyGsm modem(SerialAT);
#endif
TinyGsmClient client(modem);
PubSubClient mqtt(client);
Ticker tick;
#define uS_TO_S_FACTOR 1000000ULL // Conversion factor for micro seconds to seconds
#define TIME_TO_SLEEP 60 // Time ESP32 will go to sleep (in seconds)
#define UART_BAUD 115200
#define PIN_DTR 25
#define PIN_TX 27
#define PIN_RX 26
#define PWR_PIN 4
#define SD_MISO 2
#define SD_MOSI 15
#define SD_SCLK 14
#define SD_CS 13
#define LED_PIN 12
int ledStatus = LOW;
uint32_t lastReconnectAttempt = 0;
void mqttCallback(char *topic, byte *payload, unsigned int len)
{
SerialMon.print("Message arrived [");
SerialMon.print(topic);
SerialMon.print("]: ");
SerialMon.write(payload, len);
SerialMon.println();
// Only proceed if incoming message's topic matches
if (String(topic) == topicLed) {
ledStatus = !ledStatus;
digitalWrite(LED_PIN, ledStatus);
SerialMon.print("ledStatus:");
SerialMon.println(ledStatus);
mqtt.publish(topicLedStatus, ledStatus ? "1" : "0");
}
}
boolean mqttConnect()
{
SerialMon.print("Connecting to ");
SerialMon.print(broker);
// Connect to MQTT Broker
boolean status = mqtt.connect("GsmClientTest");
// Or, if you want to authenticate MQTT:
// boolean status = mqtt.connect("GsmClientName", "mqtt_user", "mqtt_pass");
if (status == false) {
SerialMon.println(" fail");
return false;
}
SerialMon.println(" success");
mqtt.publish(topicInit, "GsmClientTest started");
mqtt.subscribe(topicLed);
return mqtt.connected();
}
void setup()
{
// Set console baud rate
Serial.begin(115200);
delay(10);
// Set LED OFF
pinMode(LED_PIN, OUTPUT);
digitalWrite(LED_PIN, HIGH);
pinMode(PWR_PIN, OUTPUT);
digitalWrite(PWR_PIN, HIGH);
delay(300);
digitalWrite(PWR_PIN, LOW);
SPI.begin(SD_SCLK, SD_MISO, SD_MOSI, SD_CS);
if (!SD.begin(SD_CS)) {
Serial.println("SDCard MOUNT FAIL");
} else {
uint32_t cardSize = SD.cardSize() / (1024 * 1024);
String str = "SDCard Size: " + String(cardSize) + "MB";
Serial.println(str);
}
Serial.println("\nWait...");
delay(1000);
SerialAT.begin(UART_BAUD, SERIAL_8N1, PIN_RX, PIN_TX);
// Restart takes quite some time
// To skip it, call init() instead of restart()
Serial.println("Initializing modem...");
if (!modem.restart()) {
Serial.println("Failed to restart modem, attempting to continue without restarting");
}
String name = modem.getModemName();
DBG("Modem Name:", name);
String modemInfo = modem.getModemInfo();
DBG("Modem Info:", modemInfo);
#if TINY_GSM_USE_GPRS
// Unlock your SIM card with a PIN if needed
if (GSM_PIN && modem.getSimStatus() != 3) {
modem.simUnlock(GSM_PIN);
}
#endif
#if TINY_GSM_USE_WIFI
// Wifi connection parameters must be set before waiting for the network
SerialMon.print(F("Setting SSID/password..."));
if (!modem.networkConnect(wifiSSID, wifiPass)) {
SerialMon.println(" fail");
delay(10000);
return;
}
SerialMon.println(" success");
#endif
#if TINY_GSM_USE_GPRS && defined TINY_GSM_MODEM_XBEE
// The XBee must run the gprsConnect function BEFORE waiting for network!
modem.gprsConnect(apn, gprsUser, gprsPass);
#endif
SerialMon.print("Waiting for network...");
if (!modem.waitForNetwork()) {
SerialMon.println(" fail");
delay(10000);
return;
}
SerialMon.println(" success");
if (modem.isNetworkConnected()) {
SerialMon.println("Network connected");
}
#if TINY_GSM_USE_GPRS
// GPRS connection parameters are usually set after network registration
SerialMon.print(F("Connecting to "));
SerialMon.print(apn);
if (!modem.gprsConnect(apn, gprsUser, gprsPass)) {
SerialMon.println(" fail");
delay(10000);
return;
}
SerialMon.println(" success");
if (modem.isGprsConnected()) {
SerialMon.println("GPRS connected");
}
#endif
// MQTT Broker setup
mqtt.setServer(broker, 1883);
mqtt.setCallback(mqttCallback);
}
void loop()
{
// Make sure we're still registered on the network
if (!modem.isNetworkConnected()) {
SerialMon.println("Network disconnected");
if (!modem.waitForNetwork(180000L, true)) {
SerialMon.println(" fail");
delay(10000);
return;
}
if (modem.isNetworkConnected()) {
SerialMon.println("Network re-connected");
}
#if TINY_GSM_USE_GPRS
// and make sure GPRS/EPS is still connected
if (!modem.isGprsConnected()) {
SerialMon.println("GPRS disconnected!");
SerialMon.print(F("Connecting to "));
SerialMon.print(apn);
if (!modem.gprsConnect(apn, gprsUser, gprsPass)) {
SerialMon.println(" fail");
delay(10000);
return;
}
if (modem.isGprsConnected()) {
SerialMon.println("GPRS reconnected");
}
}
#endif
}
if (!mqtt.connected()) {
SerialMon.println("=== MQTT NOT CONNECTED ===");
// Reconnect every 10 seconds
uint32_t t = millis();
if (t - lastReconnectAttempt > 10000L) {
lastReconnectAttempt = t;
if (mqttConnect()) {
lastReconnectAttempt = 0;
}
}
delay(100);
return;
}
mqtt.loop();
}
Serial Logs
10:29:56.874 -> AT+CGREG?
10:29:56.874 ->
10:29:56.874 -> +CGREG: 0,1
10:29:56.874 ->
10:29:56.921 -> OK
10:29:56.921 -> AT+CIPRXGET=4,0
10:29:56.921 ->
10:29:56.921 -> +CIPRXGET: 4,0,0
10:29:56.974 ->
10:29:56.974 -> OK
10:29:56.974 -> AT+CIPCLOSE?
10:29:56.974 ->
10:29:56.974 -> +CIPCLOSE: 0,0,0,0,0,0,0,0,0,0
10:29:57.021 ->
10:29:57.021 -> OK
10:29:57.021 -> === MQTT NOT CONNECTED ===
10:29:57.122 -> AT+CGREG?
10:29:57.122 ->
10:29:57.122 -> +CGREG: 0,1
10:29:57.157 ->
10:29:57.157 -> OK
10:29:57.157 -> === MQTT NOT CONNECTED ===
10:29:57.275 -> AT+CGREG?
10:29:57.275 ->
10:29:57.275 -> +CGREG: 0,1
10:29:57.321 ->
10:29:57.321 -> OK
10:29:57.321 -> === MQTT NOT CONNECTED ===
10:29:57.423 -> AT+CGREG?
This thread is similar to adjust to 0>
https://github.com/knolleary/pubsubclient/issues/344