Question about "Heartbeat" and timer.setInterval( )

All -

Environment:
Arduino IDE 1.8.3 (Mac iOS)
Arduino MKR1000
Blynk 2.10.1 (Mac iOS)

I have a functional sketch that sends data from various sensors using BlynkTimer. The timer calls 4 separate functions that send data using the Blynk.virtualWrite( ) command. I have all 4 timer intervals set for 15 seconds.

The problem I am having is a dropped connection to the Blynk Cloud. It is not immediate. and not consistent. By reading some of the other posts, I have decided to simplify the sketch to just a basic WiFi example that sends no data and has no timers.

It is the “Arduino_WiFi_Shield_101” sketch. (No changes)

By doing this I can prove to myself that the physical connection is not the problem, but rather there is something in the sketch that is causing either a “flood” issue, or that perhaps because I am not “pushing” data often to keep the connection alive. “Heartbeat” ???

As of this evening, I have had a solid connection for 5 hours. No data of course, but just an “Online” status.

As I understand it, Blynk sends a ping every 8 seconds just to tell the server that everything is OK. If it does not receive a ping, it tries to reconnect because of the simple structure in the loop( ) section of the sketch

// Begin the loop section
void loop()
{
  Blynk.run();
  timer.run();
}

The specific questions are:

Is there a recommended protocol or “common practice” in how I set up my timer intervals so that I send the data as Blynk is expecting to receive it? All of the test examples seem to be set for 1000 millis.

Should I NOT have the same interval for the four timer functions so that they do not “stack” on top of each other. My understanding is that they process in the order in which they are called … some process perhaps slower than others.

Lastly … just for clarity … what is the significance of the “L” in the timer.Interval function? “timer.setInterval(15000L, flowSensorData);”

I have never used the “log” to monitor the interaction with the server, and I am not sure how to interpret the data even if I knew how to set it up … perhaps that is for another day.

Thanks for all the help in the past … and I appreciate the wonderful support by the community and techs.

Jim

Hey @at_th_land, we all experience this flood issue. There is a maximum amount of VirtualWrites you can make before your hardware will drop a connection… this is more prevalent on the ESP8266.

You can try to stagger the timers so that you’re sending VirtualWrites in sequence.

That’s just because some of them demonstrate a “clock effect” at 1s intervals.

Never really found this to be an issue especially on 15s intervals.

It means the variable in a long data type as opposed to an integer or float. For small values it’s not really required but if you wanted a 1 day interval the value would overflow an integer in milliseconds.

This is fixed with the master branch of the Arduino core. 2.40-RC1 has a memory leak bug so go for the master.

1 Like

Great! I will give it a go tomorrow :smiley:

You could just go to 2.40-RC1 and apply the simple patch for the memory leak in axTLS from Fix memory leak of ssl_ext_host_name, losing memory every SSL disconnect by earlephilhower · Pull Request #50 · igrr/axtls-8266 · GitHub

2 Likes

Thanks for the quick replies …

Since I am not sure what is causing the disconnect … is there a way to look at the log file, and see what response I am getting from the server? Again, I have not used any debugging other than simple analysis of the serial monitor.

The sensors are a DHT22( temp and humidity), a TMP36 temp (used for water temp), and a Hall effect sensor to count revolutions of a water wheel (less than 100 rpm).

All of my variables for the sensor data have been defined as integers EXCEPT for the DHT22 which are “float”. All are global.


//********************************************************************************
// Assign variables to be used throughout the sketch.  These will be global variables

int currentPinStatus; // used in the water flow function
int priorPinStatus;  // used in the water flow function
int tempCounter;  // used in the water flow function
float temp;  // For DHT sensor temperature reading
float humidity;  // For DHT sensor humidity reading
float tempSensorVolts; // for the TMP36 analog sensor
int waterSensorTemp;  // a converted number based on voltage
int waterFlowStatus;
int revCounter; // this is to pass a value of how many revolutions from the waterwheel
int powerStatus; // this is a yes/no variable to show if running on backup power
int currentState; // used to compare a change in value of a digital.read from HIGH to LOW
int priorState; // used to compare a change in value of a digital.read from HIGH to LOW
int rssi;  // this is a variable that will be used later for WiFi signal stregnth - needed to make it global
boolean currentTempRange; // used to compare a change in value of water temp range
boolean priorTempRange;  // used to compare a change in value of water temp range
boolean inTempRange = true; // used to compare a change in value of water temp range
boolean currentFlowRange; // used to compare a change in value of water flow range
boolean priorFlowRange;  // used to compare a change in value of water flow range
boolean inFlowRange = true; // used to compare a change in value of water flow range

Later in the code … the functions are defined individually.


// *************************************************************************************************
// Read the DHT sensor for Humidity and Air Temperature
void climateStatus()
{
  humidity = dht.readHumidity();
  temp = ((dht.readTemperature()) * 1.8) + 32;
  // or dht.readTemperature(true) for Fahrenheit

  if (isnan(humidity) || isnan(temp))
  {
    SerialUSB.println("Failed to read from DHT sensor!");
    return;
  }
  // convert t and h back to whole numbers for display to the History graph
// and to the gauge widgets
// I have done this using the "/pin./" format within Blynk
  Blynk.virtualWrite(V1, humidity);
  Blynk.virtualWrite(V0, temp);
  Blynk.virtualWrite(V2, temp);
}

The timer intervals are all called in the setup( ) section of the sketch.

  // This is where the Blynk timer is used to call the various functions to push data
  // Set the interval to be called every 15 seconds or longer perhaps 60 seconds

  // Check Air temp and humidity
  timer.setInterval(15000L, climateStatus);
  // Check water temp
  timer.setInterval(15000L, tempSensorData);
  // Check water wheel flow
  timer.setInterval(15000L, flowSensorData);
  // Check power status
  timer.setInterval(15000L, powerSensorStatus);
  // Display and refresh the LCD
  timer.setInterval(15000L, lcdDisplay);
  // Display and send RSSI data to verify WiFi signal strength
  timer.setInterval(15000L, printWiFiStatus);

If I am calling the functions within this snippet of code, do you see any reason to call one at 10 seconds, another at 15, and another at some other time? All of the widgets are set for “push”, rather than a fixed interval. I am using the same variables to update an LCD display mounted in the actual device housing.

I think my understanding would be increased if I knew specifically what is causing me to drop the connection, rather that just posting the code and asking for someone to look at it with “sharper eyes” than my own. After 65 they do get a little fuzzy :grinning:

Thanks again for the help … my goal is to also post meaningful answers some day. Usually you guys have answered the easy ones before I can chime in.

Jim

Add this as the first line of code but remove it when you have finished debugging:

#define BLYNK_PRINT Serial

OK … I can do that.

This will open the serial monitor? Or does it create a different log file? How is it read?

Debug details will appear in Serial Monitor.

Thanks … will test and reply after I have done my homework.