ArduinoCloud.update() error after using CellLocate service on MKR GSM 1400

Hello there.


I got an Arduino MKR GSM 1400 board because of the CellLocate service (that the SARA-U201 celular module has the ability to perform) and because of the simplicity Arduino IoT Cloud platform has for conecting this particular board.

To use this CellLocate service, I need an active data connection, be able to program AT commands in the sketch, a Thingstream token for using the service and also, to be able to handle the URC (Unsolicited Response Code) of the AT+ULOC command, wich give me the details of latitude and longitude.

What I'm trying to do:

I want to be able to watch in the Map Widget, from Arduino IoT Cloud, the location of the MKR GSM 1400 using the CellLocate service. In theory, asking constantly the device aproximate location, I should be able to send Arduino IoT Cloud the latitude and longitude via a CloudLocation variable.


Without using the AT+ULOC command, the board connects perfectly to the Cloud, and using the next program the Map Widget updates perfectly whithout any problems (even using a delay of 45 seconds).

CloudLocation coordinates; //thingProperties.h tab
//loop() part from a Sketch for Arduino IoT Cloud
void loop() {

  LatD  = LatD  + 0.0001000; //Double variable containing 7 decimals
  LongD = LongD + 0.0001000; //Double variable containing 7 decimals
  coordinates = {LatD, LongD};

The problem is when I run the AT+ULOC command. The ArduinoCloud.update() function stops updating my CloudLocation variable after I request to the Thingstream servers the location of the device. (At the end I left the sketch)

What I think it is:

As I'm just new with Arduino, I don't know exactly what's going on. But, from all my tests with the program, I could guess that the link established with Arduino IoT Cloud at the start of the program is corrupted or broken when the AT+ULOC command establishes connection with the Thingstream servers.

Reading throu the forums, I learn that the ArduinoIoTCloud library isn't too good for recover from a lost of connection, but this particulary issue isn't about lost of Internet connection so, I don't know how to deal with it.

What I'm Asking For:

If anyone have faced this problem or something related to it and managed to pass throu it, I would appreciate the help. Or, if someone knows what is the particular thing that is lost between the Arduino IoT Cloud and the board:

How could I reestablish the Cloud connection without rebooting the program?



#include <ArduinoIoTCloud.h>
#include <Arduino_ConnectionHandler.h>

const char THING_ID[]      = "xxxxxxxxxxxxxxxx";

const char GPRS_APN[]      = SECRET_APN;
const char PINNUMBER[]     = SECRET_PIN;
const char GPRS_LOGIN[]    = "";
const char GPRS_PASSWORD[] = "";

CloudLocation coordenadas;

void initProperties(){

  ArduinoCloud.addProperty(coordenadas, READ, ON_CHANGE, NULL, 60);


GSMConnectionHandler ArduinoIoTPreferredConnection(PINNUMBER, GPRS_APN, GPRS_LOGIN, GPRS_PASSWORD);


#include "thingProperties.h"

#include <MKRGSM.h>

#define LF  0x0A

const char UBLOX_APIKEY[]   = SECRET_UBLOX_APIKEY;    //Rellenar con el Token para hacer uso de CellLocate.

unsigned long baud = 9600;  //Tasa de baudios usada para ambos puertos seriales.

char    respuesta_char[10]; //Variable para guardar la respuesta recibida del módulo.
int     Contador = 0;       //Llevará un contéo de las veces que se reciban datos de CellLocate.
int     indx = 0;           //Índice para concadenar la respuesta recibida del módulo.
int     lastCommaIndex;     //Va a ser el índice que permita cortar el string del URC.
String  Respuesta_str;      //Variable para guardar la respuesta del módulo.
String  Incertidumbre;      //Variables que guardan info del URC dado por el módulo.
String  Latitud, Longitud;  //Variables que guardan info del URC dado por el módulo.
double  LatD, LongD;        //Almacena en formato 'Double' los strings de Latitud y Longitud.

void setup() {
  SerialGMS.begin(baud);  //This serial port is used between the MCU and the SARA-U201 module.
  initProperties(); // Defined in thingProperties.h
  ArduinoCloud.begin(ArduinoIoTPreferredConnection, false); //The 'false' is for shutting down the watchdog.
  //loop I found for waiting for the connection with the Cloud establish.
  while (!ArduinoCloud.connected()) {
    Serial.println("Esperando 1ra conexión a Arduino IoT Cloud.");
  //AT commands for setting up the pre-requisites of the CellLocate service:
  MODEM.send("AT+UGSRV=\"\",\"\",\"" + String(UBLOX_APIKEY) + "\"");
  MODEM.waitForResponse(100);   //Waits for the module to send "OK".
  MODEM.waitForResponse(100);   //Waits for the module to send "OK".
  Serial.println("Configuración del módulo lista...");

void loop() {
  // Your code here
  //loop I found for waiting for the connection with the Cloud to reestablish
  //(I really don't think it works):
  while (!ArduinoCloud.connected()) {
    Serial.println("Esperando conexión a Arduino IoT Cloud.");
  //Sending the AT command for getting the location using CellLocate service:
  //Loop that waits for the URC of the AT+ULOC command
  while (true) {
    if (SerialGSM.available() > 0) {
      respuesta_char[indx] =;
      //Looks for an "end character" in the serial responses:
      if (respuesta_char[indx] == LF) {
        Serial.print("Recibí: ");
        respuesta_char[indx - 1] = 0;
        indx = -1;
        Respuesta_str = String(respuesta_char);
        //Conditional that search for the waited answer:
        if (Respuesta_str.startsWith("+UULOC: ") && Respuesta_str.endsWith(",95")) {
          //This section is for cutting the URC response and getting the Latitude, Longitude and Uncertanty:
          lastCommaIndex = Respuesta_str.lastIndexOf(',');
          Incertidumbre = Respuesta_str.substring(lastCommaIndex + 1);
          lastCommaIndex = Respuesta_str.lastIndexOf(',');
          Longitud = Respuesta_str.substring(lastCommaIndex + 1);
          lastCommaIndex = Respuesta_str.lastIndexOf(',');
          Latitud = Respuesta_str.substring(lastCommaIndex + 1);
          //Convertion from String to Double:
          LatD  = Latitud.toDouble();
          LongD = Longitud.toDouble();
          //Updating the CloudLocation variable:
          coordenadas = {LatD, LongD};
          Serial.println("Solicitud #: "    + String(Contador));
          Serial.println("Latitud(95%): "  + Latitud);
          Serial.println("Longitud(95%): " + Longitud);
          Serial.println("Incertidumbre(95%): " + Incertidumbre + "m");
        //This is in case that the URC comes with an error (usually comes wiht different format):
        else if (Respuesta_str.startsWith("+UULOC") | Respuesta_str.startsWith("+UUOC") |
                 Respuesta_str.startsWith("UULOC") | Respuesta_str.startsWith("+ULOC")) {
          Serial.println("Se recibió una respuesta de +ULOC erronea");