An indication that the connection to the Internet and the cloud is working

Hello
I am looking for a way where I can tell if my Arduino Nano 33 IoT is connected to the Internet and to the Arduino cloud. I know that this information can be seen in the serial monitor when the Arduino is connected by a cable to the computer. I am looking for a solution to the situation when the Arduino is not connected to the computer. I was thinking, for example, of some variable that tells me that the connection is working (wifi and to the cloud) and then, I can turn on an LED when the variable shows me that everything is working. Is there such a thing?
Thank you

1 Like

And just what would this information be? Since you know this, just test in your code for it's existence.

I didn't write the code.
This information is printed on the serial monitor by the code that is automatically generated when you start a new sketch on the Arduino IoT cloud.

There appears to be a function to check the connection. Stick this line in the loop. It prints 0 when it's trying to connect and 1 when its connected, though it may well be a Boolean.

Serial.print(ArduinoCloud.connected());
1 Like

Hi eldord,

I use the following lines at the beginning of the Loop -

  while (ArduinoCloud.connected() == 0)
  {
    ArduinoCloud.update(); //required so things don't crash on us
    // Serial.print("Waiting for connection to Arduino IoT Cloud");
    // Serial.print("\r");
    delay(1500);
  }

  // Serial.print("Connection to IoT Cloud");
  // Serial.print("\r");

  digitalWrite(led, LOW);   // turn the LED on

HTH?

Arduino recommend that the calls to ArduinoCloud.update() are regular. I.e. every loop and without delays. The code above will only call it if the internet connection is lost.

In my home IoT I use the built-in LED to indicate error level and I've just ported the sketch across to use it on the Arduino IoT. It is below. It allows error messages to be defined in a prioritised order and flashes the built in LED a number of times corresponding to the highest error currently active. No flashes = NO_ERR, maximum flashes =IOT_ERR, etc.

I included a couple of fake intermediate level errors VEML6070_ERR and BME280_ERR which can be set and cleared via IoT cloud variables force_bme280_error and force_veml6070_error to force errors via dashboard switches.

As fake tasks for my test Thing, I blinked a second LED and updated an IoT number. That's one local task and one IoT task.

I tested the Thing with the router powered up and it all functioned as expected; second LED flashing, IoT number updating and fake errors indicated when forced via dashboard settings.

I then switched off the router and after a few seconds the built-in LED indicated IOT_ERR as expected. Importantly, the second LED was still blinking correctly throughout, indicating that the local task was still operating correctly and calls to ArduinoCloud.update() were not causing any problems.

I then switched the router back on and IoT functionality was quietly restored.

So in short, I don't see any real need to diverge from the Arduino recommended practice of calling ArduinoCloud.update() every loop.

If a section of code is truly sensitive to whether the IoT connection is available, just qualify it with the ArduinoCloud.connected().

/* 
  Sketch generated by the Arduino IoT Cloud Thing "Untitled"
  https://create.arduino.cc/cloud/things/38fb921c-4052-4eff-a94f-eef3f7872fd8 

  Arduino IoT Cloud Variables description

  The following variables are automatically generated and updated when changes are made to the Thing

  int test_int;
  bool force_bme280_error;
  bool force_veml6070_error;

  Variables which are marked as READ/WRITE in the Cloud Thing will also have functions
  which are called when their values are changed from the Dashboard.
  These functions are generated with the Thing and added at the end of this sketch.
*/
/* 
  This sketch demonstrates a method for indicating error status via the built-in LED.
  A prioritised list of error states is defined, each of which can be either active or 
  inactive.
  
  When no errors are active, the LED remains off. When an error is active the LED blinks.
  The highest priority error that is currently active is relected by the number of times
  the LED blinks before an LED off gap.
  
  This sketch is for the ESP32 architecture.
*/

#include "thingProperties.h"

//--------------------------------------------------------------------------------------
// Timer related declarations
//--------------------------------------------------------------------------------------
hw_timer_t * timer = NULL;
portMUX_TYPE timerMux = portMUX_INITIALIZER_UNLOCKED;
void IRAM_ATTR onTimer();

//--------------------------------------------------------------------------------------
// Declare the error messages and associate with levels.
// Error levels start at 0 and increase with errLevel right-to-left.
//--------------------------------------------------------------------------------------
#define MAX_ERR_MESSAGES 4
volatile bool errorsActive[MAX_ERR_MESSAGES]; // Holds status of each error; false = no error
enum errLevel {NO_ERR, VEML6070_ERR, BME280_ERR, IOT_ERR};
volatile int errorLevel = 0;          // Holds the current highest priority error. Zero is no error.

unsigned long previousMillis = 0;
const long interval = 1000;   
unsigned long currentMillis;

// Define an LED to demonstrate a local (non-iot) task
#define LED2 23
bool led2State = false;

void setup() {
  // Initialize serial and wait for port to open:
  Serial.begin(9600);
  // This delay gives the chance to wait for a Serial Monitor without blocking if none is found
  delay(1500); 

  // Defined in thingProperties.h
  initProperties();

  // Connect to Arduino IoT Cloud
  ArduinoCloud.begin(ArduinoIoTPreferredConnection);

  setDebugMessageLevel(2);
  ArduinoCloud.printDebugInfo();
  
  pinMode(LED_BUILTIN,OUTPUT);
  pinMode(LED2,OUTPUT);

  // Configure the hardware timer to provide interrupts every at 4Hz and start it.
  // Board specific timer configuration to provide a 4Hz interrupt.
  // This configuration is for a DOIT ESP32 DEVKIT.
  timer = timerBegin(0, 80, true);
  timerAttachInterrupt(timer, &onTimer, true);
  timerAlarmWrite(timer, 250000, true);
  timerAlarmEnable(timer);

  setError(IOT_ERR);
}

void loop() {
  ArduinoCloud.update();
  // Your code here
  
  if (ArduinoCloud.connected()){
    clearError(IOT_ERR);
  }
  else{
    setError(IOT_ERR);
  }
  
  // Give the Thing a couple of tasks.
  // Update a value - an IoT task
  // Blink a second LED - a local task
  currentMillis = millis();
  if (currentMillis - previousMillis >= interval) {
    previousMillis = currentMillis;
    
    // Write a value to the Arduino IoT
    test_int = currentMillis & 10000;

    // Toggle the second LED
    digitalWrite(LED2,led2State);
    led2State = !led2State;
  }
  
}



//----------------------------------------------
// ERROR HANDLING FUNCTION DEFINITIONS START 
//----------------------------------------------

// Service hardware timer interrupts
void IRAM_ATTR onTimer() {
  // Mandatory call marking start of ISR
  portENTER_CRITICAL_ISR(&timerMux);

  // Manage the toggling of the built-in LED to indicate the current error level
  static int state = 0;
  static int count = 0;
  static int maxCount = 0;
  static int errorLevel;
  
  if (state==0){
    errorLevel = getErrorLevel();
    if(errorLevel>0){
      count = 0;
      maxCount = 3 + 2 * errorLevel;
      state = 1;
    }
  }
  else{
    count++;
    if ((count>3) && (count<=maxCount)){
      digitalWrite(LED_BUILTIN, count % 2);
    }
    else if (count>maxCount){
      state = 0;
      digitalWrite(LED_BUILTIN, 0);
    }
  }
  
  // Mandatory call marking end of ISR
  portEXIT_CRITICAL_ISR(&timerMux);
}

// Set an error level
void setError(errLevel _err){
  errorsActive[_err] = true;
}

// Clear an error level
void clearError(errLevel _err){
  errorsActive[_err] = false;
}


// Get the highest priority error currently flagged
int getErrorLevel(){
  int highestError = 0;
  for (int i=0; i<MAX_ERR_MESSAGES; i++){
    if (errorsActive[i]){
      highestError = i;
    }
  }
  return highestError;
}

//----------------------------------------------
// ERROR HANDLING FUNCTION DEFINITIONS END
//----------------------------------------------



//----------------------------------------------
// React to IoT switch changes to force errors
//----------------------------------------------

/*
  Since ForceBme280Error is READ_WRITE variable, onForceBme280ErrorChange() is
  executed every time a new value is received from IoT Cloud.
*/
void onForceBme280ErrorChange()  {
  if (force_bme280_error)
    setError(BME280_ERR);
  else
    clearError(BME280_ERR);
}


/*
  Since ForceVeml6070Error is READ_WRITE variable, onForceVeml6070ErrorChange() is
  executed every time a new value is received from IoT Cloud.
*/
void onForceVeml6070ErrorChange()  {
  if (force_veml6070_error)
    setError(VEML6070_ERR);
  else
    clearError(VEML6070_ERR);
}

1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.