vshymanskyy / TinyGSM

A small Arduino library for GSM modules, that just works
GNU Lesser General Public License v3.0
1.96k stars 726 forks source link

ESP32 SIM800 and MQTT (PubSubClient) not working ... #340

Closed euquiq closed 5 years ago

euquiq commented 5 years ago

Hello!

I manage to connect (and pass through a Last will on connection into my own (mosquitto, linux server based) broker. I can see my broker receiving the user / pass (and last will) and returning the ACK.

Then my Arduino Sketch subscribes into two topics. Again, I can see the topic subscription request on my mosquitto log, and the ACK is sent back.

All is fine.

Fifteen seconds (or so) later, PubSubClient indicates that MQTT broker is disconnected (from my arduino) and thus another MQTT connection is started. This behavior keeps going and going.

In the brief moments that my mqtt client SEEMS to be connected, I try to send an MQTT package into it, but nothing is being received by TinyGSM (and PubSubClient).

It is to be noted that this same hardware works flawlessly with my own code (I did implement the at commands, and then the mqtt protocol itself, in order to connect, publish, subscribe and receive packets). SO I know that the Gsm modem works fine, my gsm sim data plan is OK, and my remote Linux based Mosquitto broker is working fine too.

I could go on using my own code, but if I managed to get TinyGSM / PubSubClient working, it would be a tremendous simplification (way easier to manage and upgrade) than my custom code. So I really want this to work.

Any ideas or help are appreciated a lot!

Euquiq

/* ==== Defines TINY GSM ==== */
#define TINY_GSM_MODEM_SIM800
#define TINY_GSM_RX_BUFFER 96
#define TINY_GSM_USE_GPRS true
#define TINY_GSM_USE_WIFI false
//#define TINY_GSM_DEBUG Serial
/* ==== Defines MQTT PUBSUBCLIENT ==== */
#define MQTT_MAX_PACKET_SIZE 96                     //Original 128bytes /74
#define MQTT_SOCKET_TIMEOUT 15                      //Original 15 seconds /30
#define MQTT_KEEPALIVE 90

/* ==== INCLUDES ==== */
#include "HardwareSerial.h"                         //CONNECTING INTO GSM 
#include <TinyGsmClient.h>                          //TinyGSM library
#include <PubSubClient.h>                           //MQTT PUBLISH and SUSCRIBE  https://github.com/knolleary/pubsubclient

PubSubClient mqttclient;
HardwareSerial SerialGSM(2);
TinyGsm modemGSM(SerialGSM);
TinyGsmClient gsmClient(modemGSM);

long mqtttimer = 0;                                 // Timer for counting 5 seconds and retrying mqtt connection
byte mqtttarea = 1;                                 //Indicator for establishing in which task / state is the mqtt client

void setup() {
    Serial.begin(115200);                                                           //Start debug console connectivity
    delay(200);
    tinygsm_setup();
}

void loop() {
mqtt_motor();
//Bunch of code, unrelated

}

void tinygsm_setup() {
    SerialGSM.begin(115200, SERIAL_8N1);
    delay(3000);
    Serial.println("MODEM GSM" + modemGSM.getModemInfo());
    //Reset Modem
    if (!modemGSM.restart())
    {
        Serial.println("Restarting GSM Modem failed");
        delay(10000);
        ESP.restart();
    }           
    Serial.println("IMEI: " + modemGSM.getIMEI());
    Serial.println("SIM STATUS: " + (String)modemGSM.getSimStatus()); //1=SIM OK
    //Log into gsm Network
    if (!modemGSM.waitForNetwork())
    {
        Serial.println("Failed to connect to network");
        delay(10000);
        ESP.restart();
        return;
    }
    //get into GPRS:
    if (!modemGSM.gprsConnect("myapn", "user", "pass")) {
        Serial.println("GPRS Connection Failed");
        delay(10000);
        ESP.restart();
        return;
    }
    IPAddress local = modemGSM.localIP();
    Serial.println("IP: " + local.toString());
    mqttclient.setClient(gsmClient);   // Attach gsmClient into my mqtt client object
    Serial.println("Setup GSM Success");
}

void mqtt_motor() {
    switch (mqtttarea) {
    case 0: 
        if (!mqttclient.connected() && millis() - mqtttimer > 5000) {
            Serial.println("MQTT CON");
            if (mqttclient.connect("hostid", "MQTTUsername", "MQTTPassword", "TOPICFORWILL", 0, 0, "LASTWILL")) {
                //CONNECTION OK! NOW SUBSCRIBE
                if (mqttclient.subscribe("TOPIC/WHATEVER")) {                                               //First topic subscription
                    if (mqttclient.subscribe("TOPIC/WHATEVER2")) {
                        Serial.println("MQTT OK!");
                        return;                                                                     //Get outta here!
                    }
                }
                mqttclient.disconnect();                                                            //For some reason, subscription has failed.
                Serial.println("MQTT NO SUBSCRIBE");
            }
            else { //Could not connect!
                Serial.println("MQTT ERR " + (String)mqttclient.state());
            }
            mqtttimer = millis(); //refresh 5 seconds reconnect timer
        }
        else {  //mqtt is connected:

            mqttclient.loop(); //Take a peek into any incoming data from gsmmodem for mqtt to process
        }
        return;
    case 1:                                                                                     // MQTTINIT
        Serial.println("MQTT INI");
        mqttclient.setServer("mymqtthost", 1883);
        mqttclient.setCallback(mqtt_incoming);
        break;
    case 2:                                                                                     // MQTTSTOP
        if (mqttclient.connected()) {                                                           //It is actually connected
            mqttclient.disconnect();                                                            //Disconnect
        }
        break;
    }
    mqtttarea = 0;  //End loop, finish special task:
}

void mqtt_incoming(char* topic, byte* payload, unsigned int length) {
    Serial.println("MQTT INCOMING");
//Bunch of code for mqtt packet processing
//with TinyGSM this callback never happens, even if I keep sending packages at this device

}
euquiq commented 5 years ago

Side note: I wonder internally, how TinyGSM works ... if it establishes a single, transparent connection into gprs, or "tap dances" with AT commands and several channels, in verbose mode, all at once, on an incoming data basis. I will try to give it a look, maybe there I will find some answers

euquiq commented 5 years ago

Update: I fixed it. I moved the mqttclient.loop(); into the main void loop() {} and it started working just fine. I understood that "it was the same" one place or another, provided that it is called periodically, but it seems not, or at least not where is placed in the exposed code on my first post.

Sorry and hopefully this "insight" may help someone else!