Description
My company is an Arduino partner and we are working on a project for a client given to us by Arduino.
I was advised by an Arduino Solutions Architect, my company's contact to Arduino, to post this issue here so it can be escalated internally.
If it belongs in a different repo, such as the Arduino mbed OS repo or the ArduinoIoTCloud repo, please let me know.
Description of issue
Using the Portenta H7 and Cat.M1 shield, I cannot reliably connect to the Arduino Cloud. I am certain that the Cat.M1 connection works; If I use the bare <GSM.h> library, I can connect to the network and even ping and receive responses from different websites such as "www.example.com".
However, if I use this library to connect to the Arduino IoT cloud, I cannot established a secure connection, usually failing with the error codes:
MQTT_ERROR -2 and TLS_ERROR -31.
I have attached two sketches and some serial logs that demonstrate what I've mentioned above.
gsm_sketch.ino
This sketch and log demonstrate that I can connect to the cellular network. This tells me that my configuration of bands, APN, etc. is correct and that the module is indeed functioning.
The corresponding log is gsm_sketch.log
gsm_cloud_sketch.ino
This sketch demonstrates that I can establish a connection to the Cat.M1 network, but cannot connect to the Arduino IoT cloud.
It shows the error codes mentioned above.
The corresponding logs are gsm_cloud_sketch.log and gsm_cloud_sketch2.log
- Note: sometimes the NTP time sync succeeds, and sometimes it fails.
- Note: Every once in a blue moon this same sketch succeeds, but the connection is dropped within two minutes. I've attached an image showcasing the connection time given by the Arduino IoT cloud portal.
- An issue not shown in these logs is that sometimes the device hangs without restarting. There is no hardfault, probably gets caught in a loop somewhere.
- Another issue in this sketch and the gsm_sketch.ino is that the cellular connection is always established on the last retry, which has a 32 second wait period. This means that the watchdog on the ArduinoCloud instance (which has a window of 30 seconds) MUST be disabled in order to get the device to connect to the network. However, if it is disabled, the device will periodically hang.
Connection time of device
Hardware
- Portenta H7
- Cat. M1/NB IoT shield
gsm_sketch.ino and log
#include <Arduino_DebugUtils.h>
#include <GSM.h>
REDIRECT_STDOUT_TO(Serial);
#define SECRET_CELL_APN ""
#define SECRET_OPTIONAL_CELL_PIN ""
#define SECRET_OPTIONAL_CELL_USERNAME ""
#define SECRET_OPTIONAL_CELL_PASSWORD ""
const char GPRS_APN[] = SECRET_CELL_APN;
const char PINNUMBER[] = SECRET_OPTIONAL_CELL_PIN;
const char GPRS_LOGIN[] = SECRET_OPTIONAL_CELL_USERNAME;
const char GPRS_PASSWORD[] = SECRET_OPTIONAL_CELL_PASSWORD;
const unsigned int USA_BANDS = BAND_5 | BAND_12 | BAND_13;
unsigned int heartbeat = 0;
void initCATM1 ()
{
GSM.trace(Serial);
while (!GSM.begin(SECRET_OPTIONAL_CELL_PIN, SECRET_CELL_APN, SECRET_OPTIONAL_CELL_USERNAME,
SECRET_OPTIONAL_CELL_PASSWORD, CATM1, USA_BANDS))
{
Serial.println("Error connecting to cellular");
}
Serial.println("Connected to cellular");
}
void setup ()
{
Serial.begin(115200);
delay(1500);
Serial.println("***********************");
Serial.println("**** DEVICE BOOTUP ****");
Serial.println("***********************");
setDebugMessageLevel(4);
initCATM1();
heartbeat = millis();
}
void loop ()
{
if (millis() - heartbeat >= 10000)
{
Serial.println("Heartbeat");
heartbeat = millis();
}
}
/* EOF */
gsm_cloud_sketch.ino
#include <ArduinoIoTCloud.h>
REDIRECT_STDOUT_TO(Serial);
#define SECRET_CELL_APN ""
#define SECRET_OPTIONAL_CELL_PIN ""
#define SECRET_OPTIONAL_CELL_USERNAME ""
#define SECRET_OPTIONAL_CELL_PASSWORD ""
#define DEVICE_ID ""
#define THING_ID ""
const char GPRS_APN[] = SECRET_CELL_APN;
const char PINNUMBER[] = SECRET_OPTIONAL_CELL_PIN;
const char GPRS_LOGIN[] = SECRET_OPTIONAL_CELL_USERNAME;
const char GPRS_PASSWORD[] = SECRET_OPTIONAL_CELL_PASSWORD;
const unsigned int USA_BANDS = BAND_5 | BAND_12 | BAND_13;
CloudTemperature temperature1;
CatM1ConnectionHandler ArduinoIoTPreferredConnection(PINNUMBER, GPRS_APN, GPRS_LOGIN, GPRS_PASSWORD, CATM1, USA_BANDS);
unsigned int heartbeat = 0;
void initProperties ()
{
ArduinoCloud.addProperty(temperature1, READ, 10 * SECONDS, NULL);
}
void onCellConnect ()
{
Serial.println("**** [CCLL] CONNECTED ****");
}
void onCellDisconnect ()
{
Serial.println("**** [CCLL] DISCONNECTED ****");
}
void onCellError ()
{
Serial.println("**** [CCLL] Error ****");
}
void initCloud ()
{
ArduinoIoTPreferredConnection.addCallback(NetworkConnectionEvent::CONNECTED, onCellConnect);
ArduinoIoTPreferredConnection.addCallback(NetworkConnectionEvent::DISCONNECTED, onCellDisconnect);
ArduinoIoTPreferredConnection.addCallback(NetworkConnectionEvent::ERROR, onCellError);
// Defined in thingProperties.h
initProperties();
ArduinoCloud.setThingId(THING_ID);
ArduinoCloud.setDeviceId(DEVICE_ID);
// Connect to Arduino IoT Cloud
ArduinoCloud.begin(ArduinoIoTPreferredConnection, false);
ArduinoCloud.printDebugInfo();
}
void setup ()
{
Serial.begin(115200);
delay(1500);
GSM.trace(Serial);
GSM.setTraceLevel(5, false, false);
Serial.println("***********************");
Serial.println("**** DEVICE BOOTUP ****");
Serial.println("***********************");
setDebugMessageLevel(4);
initCloud();
heartbeat = millis();
}
void loop ()
{
ArduinoCloud.update();
if (millis() - heartbeat >= 10000)
{
Serial.println("Heartbeat");
heartbeat = millis();
}
}