Connecting causes thing to pause

Hi,

Questions:

When my nano eSP32-based Thing connects to WiFi, the number of loops per second decreases dramatically, from ca. 45,000 loops/sec to ca. 4,200. You can see that here:

Any idea why this might be? Just curious, is all.

More importantly, when it connects to the Arduino Cloud, there is a temporary hiccup of maybe three quarters of a second. This is not a problem at the start, but it is a big problem later, and this "drop cloud connection and reconnect" happens regularly - maybe on average every ten minutes. This is a showstopper in this circuit, because the circuit is an LED message scroller, and the scrolling totally stops during this time. See it here:

This circuit does not yet have any shared variables so presumably all it is telling the Cloud is "I am here"?

So my questions, and yes I have googled all over the place...:

  1. Is there any reason the disconnect/reconnect happens regularly?

  2. Or is there a way to NOT have the code halt while this happens?

  3. The ArduinoCloud.update(); at the beginning of every loop: would it not be better if I did that, say, a few times a second, in a non time critical Thing? What is the Best Practice? I am still not quite clear on that.

Any advice welcome!

Michael

Ciao @michaelwillems
There’s a similar conversation here

Basically:

  • change the thing update policy from “on change” to “every n seconds)
  • remove the watchdog (but be aware that this needs to manage the reconnection )
  • manage the cloud update() time using millis
    By using these tips you should improve your connection to the cloud

Hope this helps

1 Like

Yes, helpful. An yes, that conversation was similar but not the same (and probably in the wrong forum).

I will do the "every second" update, although that will generate more traffic. Remember, the circuit I describe able does not yet have any cloud variables, so we are increasing the update frequency from zero to a lot.

And re the halt when it disconnects/connects: will doing the cloud update() time less frequently cause an improvement here? Is it only during these cloud update() events that it checks whether it is still connected? I'll try that tonight.

As for using millis(): I think that is a good idea, so that is why am asking if there is a Best Practice from Arduino's end. Would you prefer connects every second? Every 100 ms? Every 2 seconds? Etc? (If there is no preference I'll do it the way it suits me, probably no more than 10x/second).

Grazie mille, (or "Grazie milli()"?) :grinning:
M

So 10 ms between updates (or even slower) is fine. As is the rest.

But the frequent disconnect/reconnects to Arduino Cloud still happen regularly, at the same frequency. This leads me to suspect perhaps it is the Cloud end that is the issue?

I do not care of it disconnects/reconnects, but I DO care off the scroller pauses while this happens. That is a showstopper. So... any suggestions?

Thanks for any thoughts you may have. Important enough, because this means I can't use The Cloud for anything that is pretty much real time, like a text scroller...

Michael

Are you close to the router?
You can check your wifi signal strength with this code:

  long rssi = WiFi.RSSI();
  Serial.print("RSSI:");
  Serial.println(rssi);

Good tip, and I will try. I am not sure it is WiFi though: none of my other devices lose connectivity and yes, I am very close to the router.

In fact I may just try a few Traceroutes when I get home tonight to make sure this is not the issue.

Maybe something with the code?
Btw ArduinoIotCloud library is pretty large and could have conflict with some other libraries used...

The code is very simple as yet:

/*=====================================================================

  MINI PROJECT BY MICHAEL WILLEMS (michael@willems.ca)
  Connected LED Message Scroller 32 x 8

  DATE:     3 Nov 2023

  VERSION:  0.1   Added IoT Cloud,
                  Modified code for Arduino ESP32.

  =====================================================================*/


/*-----------------------------------------------------------------------
  I. INCLUDES, DEFINITIONS ETC:
  -----------------------------------------------------------------------*/

/*
  Sketch generated by the Arduino IoT Cloud Thing "Untitled"
  https://create.arduino.cc/cloud/things/8d9216ef-39aa-410c-9062-544bc032b28d

  Arduino IoT Cloud Variables description

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

  - No variables have been created, add cloud variables on the Thing Setup page
    to see them declared here

  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.
*/

// For Arduino Cloud:
#include "thingProperties.h"

// The Rest:

#include <EEPROM.h>   //for storing message nr.

// Include all the scrolling LED display stuff:
#include <MD_Parola.h>
#include <MD_MAX72xx.h>
#include <SPI.h>
// Define hardware type, size, and output pins:
#define HARDWARE_TYPE MD_MAX72XX::FC16_HW
#define MAX_DEVICES 4
#define CS_PIN 3
// Create a new instance of the MD_Parola class with hardware SPI connection:
MD_Parola myDisplay = MD_Parola(HARDWARE_TYPE, CS_PIN, MAX_DEVICES);


int button=7;                 // for selecting future functions
long buttonTimer = 0;         // to see how long the button has been pressed
boolean buttonActive = false; // to set if the button is currently pressed
long longPressTime = 500;     // 500 - how long to push button before clock enters SET mode?
boolean longPressActive = false;
char *ScrollMsg[] = {"Passport Photos $20", "Film Developing", "Photo Restoration", "Photo Printing", "Portraits"};  
byte messageNumber;           //what message to display from above array
int brightnessValue;          // pot setting for brightness
int ldrvalue;                 // reading the LDR

unsigned long oneseccounter;  // to flash the heartbeat LED *2*x/sec
unsigned long cloudupdatecounter;
int heartbeatled = 10;
unsigned long loopcount;      // to count the loops per second


/*-----------------------------------------------------------------------
  II. THE SETUP: (executes once)
  -----------------------------------------------------------------------*/

void setup() {
  // Initialize serial and wait for port to open:
  Serial.begin(9600);

  // Delay allows 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);

  /*
     The following function allows you to obtain more information
     related to the state of network and IoT Cloud connection and errors
     the higher number the more granular information you’ll get.
     The default is 0 (only errors).
     Maximum is 4
  */
  setDebugMessageLevel(2);
  ArduinoCloud.printDebugInfo();

  // Now my stuff:

  // Allocate EEPROM memory:
  EEPROM.begin(256);
  delay(500);
  
  // Intialize the object:
  myDisplay.begin();

  // Set the intensity (brightness) of the display (0-15):
  brightnessValue = map(analogRead(A0),400,3500,10,0);  // pot setting for brightness
  myDisplay.setIntensity(brightnessValue);
  //myDisplay.setIntensity(3);  //TEST

  // Clear the display:
  myDisplay.displayClear();
  
  // Display the message:
  messageNumber = EEPROM.read(0);
  if (messageNumber > 4) {messageNumber == 0;}
  myDisplay.displayText(ScrollMsg[messageNumber], PA_CENTER, 55, 0, PA_SCROLL_LEFT, PA_SCROLL_LEFT);   // was 65

  // Misc:
  pinMode(heartbeatled, OUTPUT);
  pinMode(button,INPUT_PULLUP);
  oneseccounter = millis();
  cloudupdatecounter = millis();
  loopcount = 0;

} // end of setup


/*-----------------------------------------------------------------------
  II. THE LOOP: (executes continuously)
  -----------------------------------------------------------------------*/

void loop() {

  // The cloud update, every 10 ms:
  if ((millis() - cloudupdatecounter) > 10) {
    ArduinoCloud.update();        // Update the Cloud editor
    cloudupdatecounter = millis();
  }
  
  //The once per half second stuff:
  if ((millis() - oneseccounter) > 500) {
    // Toggle the on-board LED on-off (heartbeat):
    digitalWrite (heartbeatled, !(digitalRead(heartbeatled)));

    // Measure the light and adjust display brightness:
    ldrvalue = analogRead(A0);    // LDR with 2 kOhm resistor in series
    if (ldrvalue < 400) { ldrvalue = 400; }         // just in case
    if (ldrvalue > 3000) { ldrvalue = 3000; }       // just in case
    brightnessValue = map(ldrvalue,400,3000,10,0);  // now scale it
    myDisplay.setIntensity(brightnessValue);        // now set it

    // Print the loops per second count:
    Serial.println(loopcount*2);
   loopcount = 0;
  
    // Finally, reset the half second counter:
    oneseccounter = millis();
    
  } // end of once per half second stuff
  
  
   if (myDisplay.displayAnimate()) {
    myDisplay.displayReset();
  }
  
  // Now check the button: is it pressed? If so, do something
  if (digitalRead(button) == LOW) {
    if (buttonActive == false) {
      buttonActive = true;
      buttonTimer = millis();  // i.e. start the timer
    }  
    if ((millis() - buttonTimer > longPressTime) && (longPressActive == false)) {
      longPressActive = true;
      //Here, do the change of message...
      messageNumber++;
      if (messageNumber>4) {messageNumber = 0;}
      EEPROM.write(0, messageNumber);
      EEPROM.commit();
      myDisplay.displayClear();
      myDisplay.displayText(ScrollMsg[messageNumber], PA_CENTER, 55, 0, PA_SCROLL_LEFT, PA_SCROLL_LEFT);  // 55 is speed
    }
  } else {
    if (buttonActive == true) {
      if (longPressActive == true) {
       longPressActive = false;
      }
    }  
    buttonActive = false;
  }


  loopcount++;
} // end of loop




/*-----------------------------------------------------------------------
  IV. FUNCTIONS: (if they exist: execute when called)
  -----------------------------------------------------------------------*/


What should this do?

Instead of this, you have the constrain() function:

ldrvalue = constrain(ldrvalue , 400, 3000);

Ah, good feedback.

Re the displayReset, I can't recall - old code I am re-using. Not causing problems in the other devices and there was good reason, I seem to recall.

Ah, constrain - I did not even think of this function. Superb, thank you!

1 Like

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