1

I have an issue when trying to upload sensor data to ThingSpeak using the GSMSSLClient with the Arduino MKR GSM 1400 over MQTT. Each time I attempt to establish an MQTT connection, the state is always -2. Below is the relevant sections of my code to do this:

        const char broker[] = "mqtt3.thingspeak.com";
        const int port = 8883;
    GSMSSLClient sslClient;
    GPRS gprs;
    GSM gsmAccess;

    PubSubClient mqttClient(sslClient);

This was what I started with before initializing the MQTT connection. It failed and I thought of implementing the handling of certificates to attempt the connection again. I thus followed the steps in https://www.mathworks.com/matlabcentral/answers/1889632-how-to-download-root-certificate-for-use-with-industrial-communication-toolbox-mqtt-functions to download the root certificate, specifically the DigiCert Global Root G2 PEM certificate. I set it up this way:

        const char* caCert = \
        "-----BEGIN CERTIFICATE-----\n" \
        "XXXXXXXXXXXXXXXXXXXXXXXXXXX\n" \
        "XXXXXXXXXXXXXXXXXXXXXXXXXXX\n" \
        "XXXXXXXXXXXXXXXXXXXXXXXXXXX\n" \
        "-----END CERTIFICATE-----\n";
    sslClient.setTrustedRoot(caCert);

This failed as well. From the SSLCertificateManagement_Example in the MKRGSM library, I saw the certificate was in DER format, so I then used followed the steps here to convert the .pem to .der. I then used the sed command on Linux to format it in the structure 0xab, Below is the command:

        sed 's/../0x&, /g'

I then implemented this in the code in the arduino_secrets.h file:

        const uint8_t CA_CERT[] = {
        0x12, 0x34, 0x56, 0x78, 
        0x9a, 0xbc, 0xcd, 0xe1,  
        };

Then in the .ino file:

        sslClient.setTrustedRoot((const char*)CA_CERT));

It still failed. I then attempted to use the openssl command to get the certificates. I used two variations:

        openssl s_client -showcerts -connect mqtt3.thingspeak.com:443
        openssl s_client -showcerts -connect api.thingspeak.com:443

which output certificates which were similar to each other, but not similar to what I had downloaded from the link I had shared initially with the steps. I attempted to use these certificates as well, both in .pem and .der format but the connection still failed with state -2.

PS: Using port 1883 and GSMClient works and the data is uploaded to ThingSpeak successfully.

Here is a relatively verbose version of my code:

        #include <Adafruit_Sensor.h>
        #include <DHT.h>  
        #include <MKRGSM.h>
        #include "arduino_secrets.h"
        #include <PubSubClient.h>
    #define DHTPIN 6
    #define DHTTYPE DHT11

    DHT dht(DHTPIN, DHTTYPE);

    // GSM credentials
    // PIN Number
    const char PINNUMBER[] = SECRET_PIN;
    // APN data
    const char GPRS_APN[] = SECRET_GPRS_APN;
    const char GPRS_LOGIN[] = SECRET_GPRS_LOGIN;
    const char GPRS_PASSWORD[] = SECRET_GPRS_PASS;

    // MQTT credentials
    const char* mqttServer = &quot;mqtt3.thingspeak.com&quot;;
    const int mqttPort = 8883; 

    const char* mqttClientID = SECRET_MQTT_CLIENT_ID;
    const char* mqttUser = SECRET_MQTT_USERNAME;
    const char* mqttPass = SECRET_MQTT_PASSWORD;
    String topicString = &quot;channels/&quot; + String(SECRET_CH_ID) + &quot;/publish&quot;;
    char topic[50];

    // GSM classes
    GSMClient client;
    GPRS gprs;
    GSM gsmAccess;

    PubSubClient mqttClient(client);

    const char* caCert = \
    &quot;-----BEGIN CERTIFICATE-----\n&quot; \
    &quot;XXXXXXXXXXXXXXXXXXXXXXXXXXX\n&quot; \
    &quot;XXXXXXXXXXXXXXXXXXXXXXXXXXX\n&quot; \
    &quot;XXXXXXXXXXXXXXXXXXXXXXXXXXX\n&quot; \
    &quot;-----END CERTIFICATE-----\n&quot;;

    void setup() {
      Serial.begin(115200);

      Serial.println(&quot;Initializing DHT11...&quot;);
      dht.begin();

      Serial.println(&quot;Starting Arudino web client.&quot;);
      boolean connected = false;

      delay(10000);

      while (!connected) {
        if ((gsmAccess.begin(PINNUMBER) == GSM_READY) &amp;&amp; (gprs.attachGPRS(GPRS_APN, GPRS_LOGIN, GPRS_PASSWORD) == GPRS_READY)) {
          connected = true;
        } else {
          Serial.println(&quot;Not connected to cellular network. Retrying...&quot;);
          delay(1000);
        }
       }

       Serial.println(&quot;Connected to cellular network&quot;);

       sslClient.setTrustedRoot(caCert);

       mqttClient.setServer(mqttServer, mqttPort);
       mqttClient.setKeepAlive(60);

       // MQTT connection
       if (mqttConnect()) {
         Serial.println(&quot;Connected to MQTT broker&quot;);
       } else {
         Serial.println(&quot;Failed to connect to MQTT broker&quot;);
       }
    }

    bool mqttConnect() {
      Serial.println(&quot;Connecting to MQTT...&quot;);

      if (mqttClient.connect(mqttClientID, mqttUser, mqttPass)) {
        Serial.println(&quot;MQTT connected&quot;);
        return true;
      } else {
        Serial.print(&quot;MQTT connection failed. State: &quot;);
        Serial.println(mqttClient.state());
        return false;
      }
    }

    void loop() {
      if (!mqttClient.connected()) {
        Serial.println(&quot;MQTT disconnected. Reconnecting...&quot;);
        mqttConnect();
      }

      mqttClient.loop();

      float humidity = dht.readHumidity();
      float temperature = dht.readTemperature();

      if (isnan(humidity) || isnan(temperature)) {
        Serial.println(&quot;Failed to read from DHT sensor!&quot;);
      } else {
        Serial.print(&quot;Humidity: &quot;); Serial.print(humidity); Serial.println(&quot;%&quot;);
        Serial.print(&quot;Temperature: &quot;); Serial.print(temperature); Serial.println(&quot;°C&quot;);
      }

      String payload = &quot;field1=&quot; + String(temperature) + &quot;&amp;field2=&quot; + String(humidity);

      // Publish to MQTT topic
      if (mqttClient.publish(topic, payload.c_str())) {
        Serial.print(&quot;Publishing to: &quot;);
        Serial.println(topic);
        Serial.print(&quot;Payload: &quot;);
        Serial.println(payload);
        Serial.println(&quot;Data published to ThingSpeak MQTT.&quot;);
      } else {
        Serial.println(&quot;MQTT publish failed.&quot;);
      }

      delay(15000);
    }

Gil Sven
  • 167
  • 8

0 Answers0