Hi, I have a function in a .cpp file that runs for a while. I've noticed that after about 20 seconds that it runs the device crushes and restarts - could this be related to the watchdog? Is it possible to disable it when running this function?
My sketch is very long, this is the relevant function:
String SF1MAIN_FillKOH() {
Serial.println(">> SF1: Starting KOH Fill Sequence...");
//Defintions
// unsigned long SF1_Elapsed_Time = millis(); // Record the start time
bool UF_Drain_open_triggered = false; // Track UF drain sequence
unsigned long MainElapsedTime = 0;
//Pre-requisite conditions for starting:
if (readDigitalInput(LVL_P1_LOW) || readDigitalInput(LVL_P1_HIGH)){
return "SF1 Failed - Panel Level Sensor is HIGH";
}
//Set-Up
ValveControl(PIN_OUTLET, HIGH); //Open Panel Outlet Valve
setPumpVoltage(0); //Set Pump voltage to 0V
digitalWrite(PIN_PMPC1, LOW); //Make sure pump is off
SetValveGroupClosed(PANEL_A1_VALVES); //Close (HIGH) all Panel A1 Valves
SetValveGroupClosed(PANEL_A2_VALVES); //Close (HIGH) all Panel A2 Valves
SetValveGroupClosed(PANEL_B1_VALVES); //Close (HIGH) all Panel B1 Valves
SetValveGroupClosed(PANEL_B2_VALVES); //Close (HIGH) all Panel B2 Valves
delay(1000);
ValveControl(GVA11, HIGH); //Open (HIGH) GVA11 to feed outlet to UF
ValveControl(GVA12, HIGH); //Open (HIGH) GVA12 to feed inlet from KOH tank
ValveControl(GVB1, LOW); //Close (LOW) GVB1 to make sure no N is flowing into panel
ValveControl(GVB2, HIGH); //Open (HIGH) GVB2 for N flow into KOH tank
Serial.println(">> SF1: Set-Up Complete");
delay(10000);
//Start Filling UF first, open UF drains after 5 seconds for 5 seconds then close them and continue for 1 minute before switch to outlet manifold filling
SF1MAIN_Elapsed_Time = millis(); // Record the start time
setPumpVoltage(SF1_FILL_VOLTAGE); // Set Pump voltage
digitalWrite(PIN_PMPC1, HIGH); // Turn pump ON
Serial.println(SF1MAIN_Elapsed_Time);
// Main fill loop
MainElapsedTime = (millis() - SF1MAIN_Elapsed_Time);
while (MainElapsedTime < SF1_UF_FILL_TIME_MS) {
bool lvlLow = readDigitalInput(LVL_P1_LOW);
bool lvlHigh = readDigitalInput(LVL_P1_HIGH);
// UF drain trigger (only once)
if (!lvlLow && !lvlHigh && !UF_Drain_open_triggered) {
Serial.println(">> SF1: UF Fill wDrain");
delay(5000);
digitalWrite(PIN_UF_DRAIN, HIGH); // Open drain
delay(SF1_UF_DRAIN_TIME_MS);
digitalWrite(PIN_UF_DRAIN, LOW); // Close drain
UF_Drain_open_triggered = true;
Serial.println(">> SF1: Finished UF Fill wDrain");
}
// Exit if either level sensor triggers
if (lvlLow || lvlHigh) {
break;
}
ArduinoCloud.update();
OptaController.update();
MainElapsedTime = (millis() - SF1MAIN_Elapsed_Time);;
Serial.println(MainElapsedTime);
delay(1000); // avoid tight polling
}
Serial.println("Unsigned Long");
unsigned long fillDuration = millis() - SF1MAIN_Elapsed_Time;
ArduinoCloud.update();
OptaController.update();
// Stop pump and close GVA11
Serial.println(">> SF1: UF Fill wDrain Finished, Pump Off");
setPumpVoltage(0);
ValveControl(GVA11, false);
// Toggle GVA12 (close 3s, reopen)
ValveControl(GVA12, false);
delay(3000);
ValveControl(GVA12, true);
// Resume pump and open all panels
setPumpVoltage(3000);
SetValveGroupOpen(PANEL_A1_VALVES);
SetValveGroupOpen(PANEL_A2_VALVES);
SetValveGroupOpen(PANEL_B1_VALVES);
SetValveGroupOpen(PANEL_B2_VALVES);
// Wait for final level confirmation
while (!readDigitalInput(LVL_P1_LOW) && !readDigitalInput(LVL_P1_HIGH)) {
ArduinoCloud.update();
OptaController.update();
delay(100);
}
setPumpVoltage(0); // Final pump off
ValveControl(GVA12, false);
// Format fill time as mm:ss
unsigned long totalSeconds = fillDuration / 1000;
unsigned int minutes = totalSeconds / 60;
unsigned int seconds = totalSeconds % 60;
char timeStr[16];
snprintf(timeStr, sizeof(timeStr), "%02u:%02u", minutes, seconds);
Serial.print(">> KOH UF Fill Completed in ");
Serial.println(timeStr);
return ("KOH UF Fill Completed in " + String(timeStr));
}
I can say that when I moved it to my main.ino and added ArduinoCloud.update();
OptaController.update(); it stopped crushing. I would rather keep the function in a seperate .cpp file but then I cannot get the ArduinoCloud.update() to work
By default, the Arduino Cloud IoT Thing sketch program will automatically reset the Opta if 33 seconds elapse without the ArduinoCloud.update function being called. So if your sketch program doesn't call ArduinoCloud.update, or if it has code that causes long delays between calls to that function, then it is expected that the Opta will reset.
However, it is essential to design your Thing sketch code so that ArduinoCloud.update() is called frequently. The reason is that this function is what handles the syncing of your Arduino CloudVariables between the device and the Arduino Cloud servers and your dashboards.
If the sketch code causes long intervals to occur during which ArduinoCloud.update() is not called, this will result in problems such as lags in response of the board to actions taken in the Arduino Cloud dashboard and of response of the dashboard to changes made to the Cloud Variable values by the Thing sketch program.
If you redesign the function so that it is non-blocking, as recommended by @J-M-L, then you will be able to do that.