Connection Closed

I’m trying to use an Arduino MKR NB1500 to upload load cell data to Losant. The board connects but instantly disconnects. After a lot of google and head against my desk banging, I’m here asking for help. Hopefully, I’m not doing something really dumb.

I have an activated Hologram SIM card and Hologram reports the device as connected.

Losant Log:
image

Serial Monotor:
image

#include <MKRNB.h>
#include <Losant.h>

#include "arduino_secrets.h"
// Please enter your sensitive data in the Secret tab or arduino_secrets.h
// PIN Number
const char PINNUMBER[]     = SECRET_PINNUMBER;

// Losant credentials.
const char* LOSANT_DEVICE_ID = "xxxx38";
const char* LOSANT_ACCESS_KEY = "81bxxxx63";
const char* LOSANT_ACCESS_SECRET = "1xxxx1";
LosantDevice device(LOSANT_DEVICE_ID);
int losantAttempts = 0;
#define SECRET_PIN " "
#define SECRET_GPRS_APN "hologram"
#define SECRET_GPRS_LOGIN " "
#define SECRET_GPRS_PASS " "
const char GPRS_APN[]      = SECRET_GPRS_APN;
const char GPRS_LOGIN[]    = SECRET_GPRS_LOGIN;
const char GPRS_PASSWORD[] = SECRET_GPRS_PASS;

// initialize the library instance
NBClient client;
GPRS gprs;
NB nbAccess;
NBScanner scannerNetworks;
String signalStr;
String carrier;

// URL, path and port (for example: example.org)
char server[] = "cloudsocket.hologram.io";
char path[] = "/";
int port = 9999; // port 80 is the default for HTTP

float ambTemp = 0;
float LPTank1 = 0;
float LPTank2 = 0;
float LPTank3 = 0;
float LPTotal = 0;

void setup() {
  // initialize serial communications and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }

  Serial.println("Starting Arduino web client.");
  // connection state
  boolean GSMconnected = false;

  // After starting the modem with NB.begin()
  // attach to the GPRS network with the APN, login and password
  while (!GSMconnected) {
    if (nbAccess.begin(PINNUMBER) == NB_READY) {
      GSMconnected = true;
      Serial.println("GSM connected");
    } 
    else {
      Serial.println("Not connected");
      delay(1000);
    }
  }

  NBScanner scannerNetworks;
  carrier = scannerNetworks.getCurrentCarrier();  
  signalStr = scannerNetworks.getSignalStrength();
  Serial.print("Carrier: ");
  Serial.println(carrier);
  Serial.print("Signal Strength: ");
  Serial.println(signalStr);
    
  boolean GPRSconnected = false;
  Serial.println("GPRS Connecting..");
  while (!GPRSconnected) {
    if (gprs.attachGPRS() == GPRS_READY) {
      GPRSconnected = true;
      Serial.println("GPRS Connected");
      delay(2000);
    } 
    else {
      Serial.println("GPRS Connection Failed");
      delay(1000);
    }
  }    
  delay(2000);
  Serial.print("Connecting to Losant");
  device.connect(client, LOSANT_ACCESS_KEY, LOSANT_ACCESS_SECRET);
  while(!device.connected()) {    
    Serial.print(".");
    delay(500);
  }
  
  Serial.println("CONNECTED!!!");
}


void loop() {
  ambTemp = random(60,100);
  LPTank1 = random(65,70);
  LPTank2 = random(65,70);
  LPTank3 = random(65,70);
  LPTotal = LPTank1 + LPTank2 + LPTank3;
  Serial.println("Sending Data..");
  StaticJsonDocument<200> jsonBuffer;  //220 is MAX Size or Losant Disconnects
  JsonObject allData = jsonBuffer.to<JsonObject>();  
  allData["AmbTemp"] = ambTemp;
  allData["LPTank1"] = LPTank1;
  allData["LPTank2"] = LPTank2;  
  allData["LPTank3"] = LPTank3;   
  allData["LPTotal"] = LPTotal;
  device.sendState(allData);   
  Serial.println(" Data Sent");
  device.loop();
  delay(10000); 
}

PLEASE HELP! :man_facepalming:

The first thing to check is whether you can connect to any broker at all. Here’s a snippet that connects to Eclipse’s public sandbox broker. Give that a try.

This is what I get in the serial monitor:

connecting to the mqtt broker…

iot.eclipse.org

MQTT connection failed! Error code = -2

-2 is connection refused:

Looks like the MQTT endpoint has changed since that code was published. It’s now mqtt.eclipseprojects.io. Details here:

Success.

Warming up…

connecting to the mqtt broker…

mqtt.eclipseprojects.io

You’re connected to the MQTT broker!

Subscribing to topic: telstradev

Waiting for messages on topic: telstradev

Received a message with topic ’

telstradev’, length 16 bytes:

Hello MQTT world

Good first step. The next thing to check is whether you can connect to Losant’s broker using that MQTT library. That example is using ArduinoMQTTClient. Losant’s Arduino library is using arduino-mqtt.

Losant’s library is a thin wrapper around the underlying MQTT library. There’s nothing wrong with using any MQTT library directly if it works.

Before line 50, mqttClient.connect(...), you’ll need to add these two lines:

mqttClient.setId("YOUR_DEVICE_ID");
mqttClient.setUsernamePassword("YOUR_ACCESS_KEY", "YOUR_ACCESS_SECRET");

Losant’s broker URL is broker.losant.com.

Please give that a try. If this works, it points to some issue with the underlying MQTT library and this specific family of Arduino devices.

Success! Thanks for the help BTW.

Warming up…

connecting to the mqtt broker…

broker.losant.com.

You’re connected to the MQTT broker!

Subscribing to topic: telstradev

Waiting for messages on topic: telstradev

Just as a sanity check, can you check Losant’s application/device log? I’m assuming you’re using a default access key and secret, which does not let you subscribe to custom topics (i.e. telstradev). The connection would have succeeded, but you would have been subsequently disconnected when that subscribe was attempted.

I might be missing something but it looks the same as the original issue?

That’s expected. You are attempting to publish to the custom topic, telstradev, however access to that topic was not granted to your access key, so the broker disconnects your device.

The subscription to the telstradev topic also failed, but invalid subscribes are silent failures on our broker - they don’t disconnect the device. I incorrectly stated that invalid subscribes will cause a disconnect in my previous post.

You can find more details about using custom topics here:

All that said, you now have a path forward. I would recommend using this MQTT library directly. To publish state, you need to send a message to the topic losant/YOUR_DEVICE_ID/state. The format of the payload is:

{
  "data" : {
    "aStringAttribute": "The attribute value",
    "aNumberAttribute": 42
  }
}

Details can be found here:

I would recommend using the ArduinoJSON library to build the JSON payloads.

I have not had a chance to test that but I plan to tomorrow. Thanks again for the help!

I changed the topic to state and it seems I am staying connected now but I’m having trouble getting data sent to Losant. Do you have an example of that?

Does the application log display anything?

This one?
image

I don’t have an example, but according to the log, it doesn’t appear that any publish was attempted by the device. For example, if you publish with an invalid payload, you’d get a message like this:

In your previous attempt, the example code was publishing data because the broker disconnected the device due to an unauthorized topic. I would recommend trying the example code again and only changing the topic.

I haven’t been able to get something to compile with that library. Sorry, I’m not very good at this.

Getting your code to compile, unfortunately, isn’t something we’re going to be able to help with. However, you did have the example running 2 days ago and connecting. I recommend going back to that and slowly and incrementally adding functionality. The first step will be using the code from 2 days ago and changing just the topic string.

I think I just can’t figure out what to replace “device” with. Or maybe it won’t work even if I do?

void loop() {

  // mqttClient.poll();

  // delay(2000);

  // mqttClient.beginMessage(topic);
  // mqttClient.print("Hello MQTT world");
  // mqttClient.endMessage();

  ambTemp = random(60,100);
  LPTank1 = random(65,70);
  LPTank2 = random(65,70);
  LPTank3 = random(65,70);
  LPTotal = LPTank1 + LPTank2 + LPTank3;
  Serial.println("Sending Data..");
  StaticJsonDocument<200> jsonBuffer;  //220 is MAX Size or Losant Disconnects
  JsonObject allData = jsonBuffer.to<JsonObject>();  
  allData["AmbTemp"] = ambTemp;
  allData["LPTank1"] = LPTank1;
  allData["LPTank2"] = LPTank2;  
  allData["LPTank3"] = LPTank3;   
  allData["LPTotal"] = LPTotal;
  device.sendState(allData); // Here
  Serial.println(" Data Sent");
}

It would be something like this:

char message[256];
serializeJson(allData, message);

mqttClient.beginMessage("losant/YOUR_DEVICE_ID/state");
mqttClient.print(message);
mqttClient.endMessage();

The JsonObject you’re creating now needs a top-level “data” property:

{
  "data": {
    "AmbTemp": xyz,
    "LPTank1": xyz,
    ...
  }
}

That property was automatically added by the Losant library, but since you’re using MQTT directly, you need to add it yourself.