Hi!
I use Arduino MKR GSM 1400 and the SIM card (along with some Milone eTape) to turn on and off pumps when their tanks get to a certain level and report that value to a Google sheet for my records. A few weeks ago the Arduino would lose connection to the cloud and when it did the code stopped working entirely, causing the code to interrupt, and it flooded my lab overnight. This happened several times over the course of a week. It was irritating and somewhat dangerous. ![]()
Since removing the ArduinoCloud.update(); line everything has worked perfectly and my lab has not flooded. However, this defeats the purpose of subscribing to the cloud service, and I want to be able to view the values on the sheet again so we're trying to troubleshoot.
I am assuming because of this that there is some sort of interrupt in ArduinoCloud.update(); that happens if connection is lost. As such, I'm trying to put in an if statement to only call ArduinoCloud.update(); if the connection is right, or something like this:
if ( ArduinoIoTPreferredConnection.getStatus() == (NetworkConnectionState::CONNECTED)) {
ArduinoCloud.update();
Serial.print("Update Success");
}
However, with this, ArduinoCloud.update(); somehow never gets called. If I remove the if statement and just leave ArduinoCloud.update(); there alone, the cloud updates and my Google sheet gives me the value I entered, but then we're back where we were, not knowing if the lab will flood if connection is lost.
Here is all my code:
#include "thingProperties.h"
#define LEVEL0_PIN A1
#define LEVEL1_PIN A2
// declare floats to hold measured voltages and calculated resistances
float r0_ref = 0;
float r0_sense = 0;
float v0_ref = 0;
float v0_sense = 0;
float r1_ref = 0;
float r1_sense = 0;
float v1_ref = 0;
float v1_sense = 0;
// declare arrays to hold values of sensors
int numSamples = 10;
int arrV0_ref[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
int arrV0_sense[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
int arrV1_sense[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
// declare avg values and related vars
float avgRef0_numerator = 0;
float avgSense0_numerator = 0;
float avgRef0 = 0;
float avgSense0 = 0;
float avgSense1_numerator = 0;
float avgSense1 = 0;
float supplyVoltage = 3.3;
float adcToVoltage = supplyVoltage / 1023;
//declare constants and variables for converting voltage to level
int refR1 = 560;
int senseR1 = 560;
float refRCalc = 0;
float senseR0Calc = 0;
float senseR1Calc = 0;
float totalLength = 12.4; //length of tape in inches
float currentResPerInch = 0;
float level_0 = 0;
float level_1 = 0;
float R_min = 400;
float correction0 = 0; //value is consistently an amount off
float correction1 = 1.5; //value is consistently an amount off
//declare variables related to controlling relay
float maxLevel0 = 8; //value on level_0 that will trigger relay to turn off pumps
float minLevel0 = 5; //value on level_0 that will trigger relay to turn on pumps
float maxLevel1 = 6; //value on level_1 that will trigger relay to turn off pumps
float minLevel1 = 3; //value on level_1 that will trigger relay to turn on pumps
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(1000);
// 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(3);
ArduinoCloud.printDebugInfo();
//define pins
pinMode(A0, INPUT);
pinMode(LEVEL0_PIN, INPUT);
pinMode(LEVEL1_PIN, INPUT);
pinMode(5, OUTPUT);
digitalWrite(5, LOW);
pinMode(7, OUTPUT);
digitalWrite(7, LOW);
}
void loop() {
if ( ArduinoIoTPreferredConnection.getStatus() == (NetworkConnectionState::CONNECTED)) {
ArduinoCloud.update();
Serial.print("Update Success");
}
avgRef0_numerator = 0;
avgSense0_numerator = 0;
avgSense1_numerator = 0;
avgRef0 = 0;
avgSense0 = 0;
avgSense1 = 0;
// read the analog pins and print them into arrays
for (int idx = 0; idx < 10; idx++) {
//take measurements
//arrV0_ref[idx] = analogRead(refPin);
//arrV0_sense[idx] = analogRead(sensePin);
arrV0_ref[idx] = analogRead(A0);
arrV0_sense[idx] = analogRead(LEVEL0_PIN);
arrV1_sense[idx] = analogRead(LEVEL1_PIN);
//add values to running averages
avgRef0_numerator = avgRef0_numerator + arrV0_ref[idx];
avgSense0_numerator = avgSense0_numerator + arrV0_sense[idx];
avgSense1_numerator = avgSense1_numerator + arrV1_sense[idx];
delay(100); //100 ms delay means data should be output appx every second
} //for sensing arrays
//calculate averages
avgRef0 = avgRef0_numerator / numSamples;
avgSense0 = avgSense0_numerator / numSamples;
avgSense1 = avgSense1_numerator / numSamples;
//convert adc count value to voltage
avgRef0 = adcToVoltage * avgRef0;
avgSense0 = adcToVoltage * avgSense0;
avgSense1 = adcToVoltage * avgSense1;
//convert voltages to resistance
refRCalc = avgRef0 * refR1 / (supplyVoltage - avgRef0);
senseR0Calc = avgSense0 * senseR1 / (supplyVoltage - avgSense0);
senseR1Calc = avgSense1 * senseR1 / (supplyVoltage - avgSense1);
//get scale
currentResPerInch = (refRCalc - R_min) / totalLength;
//convert resistances to level and correct for small but consistent error
level_0 = totalLength - ((senseR0Calc - R_min) / currentResPerInch);
level_0 = level_0 + correction0;
level_1 = totalLength - ((senseR1Calc - R_min) / currentResPerInch);
level_1 = level_1 + correction1;
if (level_0 > maxLevel0) {
digitalWrite(5, HIGH);
} //using the normally on option of the relay, so writing a high will switch it off
if (level_1 > maxLevel1) {
digitalWrite(7, HIGH);
} //if level > maxLevel turn off pump
if (level_0 < minLevel0) {
digitalWrite(5, LOW);
}
if (level_1 < minLevel1) {
digitalWrite(7, LOW); //using the normally on option of the relay, so writing a low will switch it on
} //if level < minLevel turn on pump
//output to arduino Serial Monitor for review
Serial.print("Ref V= ");
Serial.print(refRCalc, 1);
Serial.println("; ");
Serial.print("V0= ");
Serial.print(senseR0Calc, 1);
Serial.print("; ");
Serial.print("V1= ");
Serial.print(senseR1Calc, 1);
Serial.println(';');
Serial.print("Level 0:");
Serial.print(level_0, 1);
Serial.println(';');
Serial.print("Level 1:");
Serial.print(level_1, 1);
Serial.println(';');
Serial.print(currentResPerInch, 1);
Serial.println(' ');
reportedlevel0 = level_0;
reportedlevel1 = level_1;
}
Thank you for your help, if you take the time to look. I'm at my wits' end on this... I'm a beginner user (and a water chemist, not a programmer by training!!) so I'm doing my best! Thank you! ★