Как опубликовать sh и подписаться на брокера MQTT через модуль GSM в Arduino / ESP8266? - PullRequest
0 голосов
/ 15 апреля 2020

В настоящее время я работаю в проекте, где мне нужно опубликовать sh и, возможно, подписаться на MQTT topi c по сети GSM (я использую ESP8266 и GSM-модуль Ai Thinker A6 GSM). Пока что я могу публиковать sh сообщение для брокера один раз, используя пример кода MQTT из библиотеки TinyGSM, где они передают экземпляр клиента GPRS в класс клиента Pubsub, но когда я добавляю код в l oop для публикации sh сообщение непрерывно каждые n секунд. Сообщение публикуется только один или два раза, а затем останавливается.

Я сомневаюсь, что функция mqttclient.l oop () в пустоте l oop (). Но мне просто интересно, есть ли какая-либо другая библиотека, которая полностью протестирована, потому что сам разработчик TinyGSM упомянул, что этот код не тестируется в github.

Пример кода с mqtt publi sh в l oop

    // Select your modem:
    #define TINY_GSM_MODEM_SIM800
    // #define TINY_GSM_MODEM_SIM808
    // #define TINY_GSM_MODEM_SIM868
    // #define TINY_GSM_MODEM_SIM900
    // #define TINY_GSM_MODEM_SIM7000
    // #define TINY_GSM_MODEM_SIM5360
    // #define TINY_GSM_MODEM_SIM7600
    // #define TINY_GSM_MODEM_UBLOX
    // #define TINY_GSM_MODEM_SARAR4
    // #define TINY_GSM_MODEM_M95
    // #define TINY_GSM_MODEM_BG96
    // #define TINY_GSM_MODEM_A6
    // #define TINY_GSM_MODEM_A7
    // #define TINY_GSM_MODEM_M590
    // #define TINY_GSM_MODEM_MC60
    // #define TINY_GSM_MODEM_MC60E
    // #define TINY_GSM_MODEM_ESP8266
    // #define TINY_GSM_MODEM_XBEE
    // #define TINY_GSM_MODEM_SEQUANS_MONARCH

    // 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

    // or Software Serial on Uno, Nano
    //#include <SoftwareSerial.h>
    //SoftwareSerial SerialAT(2, 3); // RX, TX

    // See all AT commands, if wanted
    // #define DUMP_AT_COMMANDS

    // Define the serial console for debug prints, if needed
    #define TINY_GSM_DEBUG SerialMon

    // Range to attempt to autobaud
    #define GSM_AUTOBAUD_MIN 9600
    #define GSM_AUTOBAUD_MAX 115200

    // Add a reception delay - 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
    #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>

    // 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);

    #define LED_PIN 13
    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);
        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
      SerialMon.begin(115200);
      delay(10);

      pinMode(LED_PIN, OUTPUT);

      // !!!!!!!!!!!
      // Set your reset, enable, power pins here
      // !!!!!!!!!!!

      SerialMon.println("Wait...");

      // Set GSM module baud rate
      // TinyGsmAutoBaud(SerialAT,GSM_AUTOBAUD_MIN,GSM_AUTOBAUD_MAX);
      SerialAT.begin(9600);
      delay(3000);

      // Restart takes quite some time
      // To skip it, call init() instead of restart()
      SerialMon.println("Initializing modem...");
      modem.restart();
      // modem.init();

      String modemInfo = modem.getModemInfo();
      SerialMon.print("Modem Info: ");
      SerialMon.println(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() {

      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;
      }
      else
      {
       mqtt.publish("Topic/test","Hi");
       delay(1000);
      }
      mqtt.loop();
    }
...