Some Questions about the working of the ArduinoIOTCloud library

Hello,

I am in the process of creating a module (custom PCB, Arduino nano 33 iot as the brains) to control a gasoline powered generator, that now has to be started by manually operating the controls on the control panel of the generator.

The PCB controls: Start motor, ignition, Added electromechanical fuel valve, added servo motor for choke, AC output of generator, ...

The algorithm to start the generator (FSM) is not perfect but works fine for the moment.
Even when freezing outside.

The problem i have is with integrating the arduino IOT cloud library and thus the logic for it.
I am not a seasoned C coder, and i don't fully understand the inner workings of the library.
The Generator can be started via the cloud or via 2 external hardware inputs.
It must start at all times even when there is no connection to the router or cloud.
But this is not always the case, sometimes the generator will be running and the arduino will just restart, this of course interferes with the correct operation of the generator.

The topics i would like to discussion are:

  1. the watchdog timer: where in the library could i see the time it takes for it to reset the Arduino nano 33 IOT
  2. the watchdog timer: if i disable it, once the connection is lost to the router (or cloud), it will not automatically try to reconnect in my experience, am i correct in assuming this?
  3. General Library question once i call the class "ArduinoCloud.begin(ArduinoIoTPreferredConnection);" can i later change this statement to "ArduinoCloud.begin(ArduinoIoTPreferredConnection, False);" to disable the watchdog timer?
    Or is this a one time deal?
  4. if i write a value to the "Thing cloud variables", but i disable all the rest of the
    "ArduinoIOTCloud" functions, will this couse a problem? this method compiles, but that does not make it correct.

I will probably add sone questions as i can think of them to solve my problem, but these are the biggest hurdles for now.

Here is the code, Please excuse some of the makeshift parts in this, i will clean all up when i advance with the issues.

/*
  RM PR0034-PCB:V0.1B-FIRM:V1.0
  This code is writen for an arduino nano 33 iot plugged into the RM INDUSTRIES PR0034 V0.1B Generator autmatisation PCB
  

  Sketch generated by the Arduino IoT Cloud Thing "Untitled 2"   https://create.arduino.cc/cloud/things/27f030b6-2699-4a75-aaf6-863a350e076b

  Arduino IoT Cloud Variables description
  none

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

  String errorState;
  String stateName;
  int servo;
  bool fuelValve;
  bool run;
  bool startMotor;

  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.

  Servo pos(0) -> choke aan
  Servo pos(100) -> choke uit


  State Description:
    Wait,       Check for start input, check for generator state, when start input=1 and generator not running goto: Start1
    Start1,     While "start inpu=1" Preparation of generator controls (choke, iginition, fuel valve), when ready goto: start2
    Start2,     start sequence of generator, when running goto: Running
    Running,    Generator running, waiting for signal to shut off, goto: Shutoff
    ShutOff,
    Error,

    
  Refferences:
  Read and write struct from EEPROM: https://docs.arduino.cc/learn/built-in-libraries/eeprom
*/

//Defines
#define FLASH_DEBUG       0         //Part of FlashStorage_SAMD LIB. Use 0-2. Larger for more debugging messages


//included librairies
#include "thingProperties.h"
#include <Servo.h>
#include <FlashStorage_SAMD.h>      // To be included only in main(), .ino with setup() to avoid `Multiple Definitions` Linker Error

#include <RTCZero.h>



//Declare IO (Digital pin name)
const int IO_Servo1 = 9;            //choke servo position
const int IO_Servo1_en = 12;        //choke servo enable
const int IO_CutOffA = 7;           //Ignition relay A
const int IO_CutOffB = 6;           //Ignition relay B
const int IO_FuelValve = 4;         //Fual vale solenoid
const int IO_StartMotor = 5;        //Start motor solenoid
const int IO_LED = 13;              //Onboard LED pin
const int IO_Ac_Detect = 2;         //Generator Ac detect relay
const int IO_Run1 = 10;             //Run input from 230Vac contact (active HIGH)
const int IO_Run2 = 11;             //Run input from loop contact (active Low)


//Variable Declaration
int Var_ChokePos = 0;                       //variable to store the servo position
int Var_StartRetry = 0;                     //Variable to store the star retry index number
const int Var_StartRetryMax = 3;            //The maximum amount of times the start sequence is tried before aborting
int Var_AcState = 0;                        //variable that stored the Generator AC output state
int Var_StartGeneratorState = 0;            //variable that stores the generator start state
int Var_Run3 = 0;                           //Run variable from arduino Cloud
int Var_ErrorMessage = 0;                   //0:no problem, 1:not able to start 2; lost ac power (unexpected shut off)
const int Var_ChokeEngaged = 5;             //Position of servo in active, engaged position
const int Var_ChokeDisengaged = 85;         //Position of servo in non active, disengaged 
uint8_t FSMgeneral;                         //variable that stores the Finite state machine current state

const int WRITTEN_SIGNATURE = 0xBEEFDEED;   //Part of FlashStorage_SAMD LIB. Signature is the first dataset in the Eeprom emulated flash memory, to check viability
int FlashStorage_SAMD_payload = 0;          //for FlashStorage_SAMD LIB. amount of data stored in the flash memory
int FlashStorage_SAMD_Index = 0;            //Part of FlashStorage_SAMD LIB. Stores the index of the adres pointer. this will get a value after reading out the flash.
byte ErrorCount;                            //for FlashStorage_SAMD LIB. the amount of errors in the flash
byte ErrorCountMax = 30;                    //for FlashStorage_SAMD LIB. The maximum amount of errors that we will save
byte ErrorCountLocation = 4;                //for FlashStorage_SAMD LIB. the adres where the variable "ErrorCount" is stored

unsigned long time_now = 0;                 //Declare Values to use Millis() as delay
bool ArduinoIOTCloudDesired = LOW;           //For Arduino IOT Cloud, this variable is set high if we want to use the Cloud, Low if we dont

//Struct declared for error handling
struct ErrorMessage
{
    long ErrorMessageUnixtime;    //the unix time stamp
    byte ErrorMessageValue;       //the error value we want to 
};

//FSMgeneral state Declaration
enum FSMgeneral
{
  Wait,             //Wait for an input, when input goto: Start1
  Start1,           //Preparation of generator controls, when ready goto: start2
  Start2,           //start sequence of generator, when running goto: Running
  Running,          //Generator running, waiting for signal to shut off, goto: Shutoff
  ShutOff,          //Generator is shuting down
  EarlyShutOff,     //When the gennerator start signals stops before running
  Error,            //undefined problem
};

//Declare objects
Servo servo1;  // create servo object to control a servo



void setup() {
  //Declare pinmodes
  pinMode(IO_Servo1, OUTPUT);
  pinMode(IO_Servo1_en, OUTPUT);
  pinMode(IO_CutOffA, OUTPUT);
  pinMode(IO_CutOffB, OUTPUT);
  pinMode(IO_FuelValve, OUTPUT);
  pinMode(IO_StartMotor, OUTPUT);
  pinMode(IO_LED, OUTPUT);
  pinMode(IO_Ac_Detect, INPUT_PULLUP);
  pinMode(IO_Run1, INPUT_PULLUP);
  pinMode(IO_Run2, INPUT_PULLUP);

  //Set relays to correct output
  digitalWrite(IO_Servo1, 0);
  digitalWrite(IO_Servo1_en, LOW);
  digitalWrite(IO_CutOffA, LOW);
  digitalWrite(IO_CutOffB, LOW);
  digitalWrite(IO_FuelValve, LOW);
  digitalWrite(IO_StartMotor, LOW);
  digitalWrite(IO_LED, LOW);

  // Initialize serial
  Serial.begin(9600);     // Initialize serial and wait for port to open:
  delay(5000);            // This delay gives the chance to wait for a Serial Monitor without blocking if none is found
  
  //Error Handling
  FlashStorage_SAMD_Setup();
  FlashStorage_SAMD_ReadErrors();

  // ---- IOT cloud initialisation ----
  if (ArduinoIOTCloudDesired = HIGH){
    initProperties();                                                       //include the defined in thingProperties.h
    ArduinoCloud.begin(ArduinoIoTPreferredConnection);                      //Connect to Arduino IoT Cloud (,false: disable the watchdog timer)
    ArduinoCloud.addCallback(ArduinoIoTCloudEvent::SYNC, onIoTSync);        //Set the Initial values for the cloud variables
    setDebugMessageLevel(4);                                                //Debug level from 0:no to 4: everything
    ArduinoCloud.printDebugInfo();                                          //no idea about exact information
  }


  //Attach phisical pin to object servo
  servo1.attach(IO_Servo1);  // attaches the servo on pin 9 to the servo object

  //Declare startup state in FSMgeneral
  FSMgeneral = Wait;
}

void onIoTSync() {
  // set your initial values here
  run = 0;
  Var_Run3 = 0;
  stateName = "FSMstate: Boot UP";

}

void loop() {
  Serial.println("State: VOID LOOP ");

  CustomCloudHandler();             //Update the cloud if we use IOT mode

  switch (FSMgeneral)
  {
    case (Wait):
      {
        stateName = "FSM State: wait";    //update the cloud variable state to wait
        CustomCloudHandler();             //Update the cloud if we use IOT mode
        Var_StartRetry = 0;               //reset the index
        while (1)
        {
          CustomCloudHandler();              //Update the cloud if we use IOT mode

          if (RunGenerator() && digitalRead(IO_Ac_Detect) == HIGH)  //We want to start the generator and it is not running
          {
              FSMgeneral = Start1;
              break;  //break out of while loop
          }
          
          
          if (digitalRead(IO_Ac_Detect) == HIGH)  //Detect that generator hase been started manualy
          {
            ErrorHandler(3);
            while(digitalRead(IO_Ac_Detect) == HIGH)
            {
              if ((digitalRead(IO_Run1) == HIGH) || (digitalRead(IO_Run2) == LOW) || (Var_Run3 == HIGH))
              {
                ErrorHandler(5);
                while((digitalRead(IO_Run1) == HIGH) || (digitalRead(IO_Run2) == LOW) || (Var_Run3 == HIGH)){
                  CustomCloudHandler();              //Update the cloud if we use IOT mode, stay in this loop until generator is off
                }
              }
              CustomCloudHandler();              //Update the cloud if we use IOT mode, Stay in this loop until generator hase been shut off
            }
          }
          
        }
        break;
      }
      
    case (Start1):
      {
        stateName = "FSM State: start1";             //update the cloud variable state to wait
        CustomCloudHandler();              //Update the cloud if we use IOT mode, Stay in this loop until generator hase been shut off
        digitalWrite(IO_FuelValve, HIGH);   //open the fual valve so fuel hase time to fill carb bowl
        fuelValve = HIGH;                   //Update ITOcloud variable
        Ignition(1);                        //Set Ignition to enable
        
        for (Var_ChokePos = Var_ChokeDisengaged; Var_ChokePos >= Var_ChokeEngaged; Var_ChokePos -= 1) // go from choke position disengaged to engaged in steps of 1
        {
          servo1.write(Var_ChokePos);              // tell servo to go to position in variable 'Var_ChokePos'
          delay(15);                                // waits 15 ms for the servo to reach the position
          servo = Var_ChokePos;                     //write the Var_ChokePos to the IOTcloud variable
          CustomCloudHandler();              //Update the cloud if we use IOT mode, Stay in this loop until generator hase been shut off
        }

        if (RunGenerator() && (digitalRead(IO_Ac_Detect) == LOW)) //Still needed to start generator?
        {
          FSMgeneral = Start2;
          break;
        }
        else 
        {
          FSMgeneral = EarlyShutOff;
          break;
        }
        break;
      }

    case (Start2):
      {
        Serial.write("Start2");
        Serial.print('\n');
        stateName = "Start2";     //update the cloud variable state to wait
        CustomCloudHandler();              //Update the cloud if we use IOT mode, Stay in this loop until generator hase been shut off
        Serial.print(digitalRead(IO_Ac_Detect));

        time_now = millis(); //set current millis time to start couting (every 50ms servo reduce, if not started after 2 sec, wait)
        while (RunGenerator()) //Continues testing if generator stil needs to be run
        {
          stateName = "Start2: in while";     //update the cloud variable state to wait
          CustomCloudHandler();              //Update the cloud if we use IOT mode, Stay in this loop until generator hase been shut off

          if (Var_StartRetry < Var_StartRetryMax) //tried to start the less than the maximum amount of times
          {
            if ((millis() - time_now > 5000)) //wait 2sec before starting the motor // && (digitalRead(IO_StartMotor == LOW)
            {
              stateName = "Start2: Started start motor";     //update the cloud variable state to wait
              CustomCloudHandler();              //Update the cloud if we use IOT mode, Stay in this loop until generator hase been shut off
              digitalWrite(IO_StartMotor, HIGH); //Enable start motor
              startMotor = HIGH; //write value to IOTcloud variable
            }

            if (millis() - time_now > 10000) //wait 3.5 sec before desengaging choke
            {
              stateName = "Start2: Started Servo Desengagment";     //update the cloud variable state to wait
              CustomCloudHandler();              //Update the cloud if we use IOT mode, Stay in this loop until generator hase been shut off
              //Close the servo
              if ((Var_ChokePos < Var_ChokeDisengaged) && (digitalRead(IO_Ac_Detect) == LOW)) //Servo disengaging and not yet started
              {
                stateName = "Start2: SubA";     //update the cloud variable state to wait
                CustomCloudHandler();              //Update the cloud if we use IOT mode, Stay in this loop until generator hase been shut off
                Var_ChokePos++;
                servo1.write(Var_ChokePos);
                servo = Var_ChokePos;     //write value to IOTcloud variable
                delay(50); //50ms delay time between each servo degree
              }

              else if ((Var_ChokePos < Var_ChokeDisengaged) && (digitalRead(IO_Ac_Detect) == HIGH)) //Servo disengaging and started
              {
                stateName = "Start2: SubB";     //update the cloud variable state to wait
                CustomCloudHandler();              //Update the cloud if we use IOT mode, Stay in this loop until generator hase been shut off
                Var_ChokePos++;
                servo1.write(Var_ChokePos);
                servo = Var_ChokePos;     //write value to IOTcloud variable
                delay(100); //100ms delay time between each servo degree
              }

              else if ((Var_ChokePos >= Var_ChokeDisengaged) && (digitalRead(IO_Ac_Detect) == LOW)) //servo desengaged and not yet started
              {
                //Some waiting time before stopping start motor
                digitalWrite(IO_StartMotor, LOW); //DISABLE start motor
                startMotor = LOW;    //write value to IOTcloud variable
                Var_StartRetry++;
                stateName = "Start2: SubC";     //update the cloud variable state to wait
                CustomCloudHandler();              //Update the cloud if we use IOT mode, Stay in this loop until generator hase been shut off
                FSMgeneral = Start1;
                break;
              }

              else if ((Var_ChokePos >= Var_ChokeDisengaged) && (digitalRead(IO_Ac_Detect) == HIGH)) //servo desengaged and started
              {
                stateName = "Start2: SubD";     //update the cloud variable state to wait
                CustomCloudHandler();              //Update the cloud if we use IOT mode, Stay in this loop until generator hase been shut off
                FSMgeneral = Running;
                delay(700);
                digitalWrite(IO_StartMotor, LOW); //DISABLE start motor
                startMotor = LOW;    //write value to IOTcloud variable
                delay(2000); //delay before desengaging

                break;
              }
            }
          }
          else  //tried to start the the maximum amount of times
          {
            ErrorHandler(1);
            FSMgeneral = Error;
            break;
          }
        }

        if (!RunGenerator())
        {
          stateName = "EarlyShutOff///";     //update the cloud variable state to wait
          CustomCloudHandler();              //Update the cloud if we use IOT mode, Stay in this loop until generator hase been shut off
          FSMgeneral = EarlyShutOff;
          break;
        }
        break;
      }

    case (Running):
      {
        stateName = "Running";             //update the cloud variable state to wait
        CustomCloudHandler();              //Update the cloud if we use IOT mode, Stay in this loop until generator hase been shut off
        while ((digitalRead(IO_Ac_Detect) == HIGH) && (RunGenerator()))
        {
          CustomCloudHandler();              //Update the cloud if we use IOT mode, Stay in this loop until generator hase been shut off
          //DID I STUTTER?
        }
        
        if ((digitalRead(IO_Ac_Detect) == LOW) && (RunGenerator()))
        {
          ErrorHandler(2);    //errorcode 2: Lost AC power, unexpected cut off
          Var_ErrorMessage = 2;
        }
        
        FSMgeneral = ShutOff;
        break;
      }

    case (ShutOff):
      {
        time_now = millis(); //set current millis time to start couting
        stateName = "ShutOff";             //update the cloud variable state to wait
        CustomCloudHandler();              //Update the cloud if we use IOT mode, Stay in this loop until generator hase been shut off

        digitalWrite(IO_FuelValve, LOW);       //Disable fuel suply to carb and leave running to empty bowl
        fuelValve = LOW;     //write value to IOTcloud variable
        digitalWrite(IO_StartMotor, LOW);     //DISABLE start motor
        startMotor = LOW;    //write value to IOTcloud variable

        //delay(10000);
        while (millis() - time_now <= 10000)
        {
          CustomCloudHandler();              //Update the cloud if we use IOT mode, Stay in this loop until generator hase been shut off
        }

        Ignition(2);  //Set Ignition to disable

        //delay(5000);
        while (millis() - time_now <= 15000)
        {
          CustomCloudHandler();              //Update the cloud if we use IOT mode, Stay in this loop until generator hase been shut off
        }

        Ignition(0);  //Set Ignition to manual operation

        servo1.write(100);                 //Make sure the servo is off
        FSMgeneral = Wait;
        break;
      }

    case (EarlyShutOff):
      {
        time_now = millis(); //set current millis time to start couting
        stateName = "EarlyShutOff";     //update the cloud variable state to wait
        CustomCloudHandler();              //Update the cloud if we use IOT mode, Stay in this loop until generator hase been shut off
        digitalWrite(IO_FuelValve, LOW);
        fuelValve = LOW; //write value to IOTcloud variable
        digitalWrite(IO_StartMotor, LOW);
        startMotor = LOW; //write value to IOTcloud variable

        //Force iginition to off, no manual influence possible
        digitalWrite(IO_CutOffA, HIGH);     //Dual relay setup when A is not equal to B = run, A and B is high = no run, A and B is low = switch operation
        digitalWrite(IO_CutOffB, HIGH);     //Dual relay setup when A is not equal to B = run, A and B is high = no run, A and B is low = switch operation

        //delay(3000);    //make shure the generator stopped due to inertia of motor
        while (millis() - time_now <= 3000)
        {
          CustomCloudHandler();              //Update the cloud if we use IOT mode, Stay in this loop until generator hase been shut off
        }

        //Make ignition choise available again for manual use
        digitalWrite(IO_CutOffA, LOW);      //Dual relay setup when A is not equal to B = run, A and B is high = no run, A and B is low = switch operation
        digitalWrite(IO_CutOffB, LOW);      //Dual relay setup when A is not equal to B = run, A and B is high = no run, A and B is low = switch operation

        servo1.write(Var_ChokeDisengaged);                 //Make sure the servo is off
        //delay(5000);                        //chill
        while (millis() - time_now <= (3000 + 5000))
        {
          CustomCloudHandler();              //Update the cloud if we use IOT mode, Stay in this loop until generator hase been shut off
        }
        FSMgeneral = Wait;                  //Next state Wait
        break;
      }

    case (Error):
      {
        stateName = "Error";        //update the cloud variable state to wait
        CustomCloudHandler();              //Update the cloud if we use IOT mode, Stay in this loop until generator hase been shut off

        digitalWrite(IO_FuelValve, LOW);       //Disable fuel to carb
        fuelValve = LOW;                       //write value to IOTcloud variable
        delay(4000);                        //Wait for the fuel to exit carb via engine

        //Force iginition to off, no manual influence possible
        digitalWrite(IO_CutOffA, HIGH);     //Dual relay setup when A is not equal to B = run, A and B is high = no run, A and B is low = switch operation
        digitalWrite(IO_CutOffB, HIGH);     //Dual relay setup when A is not equal to B = run, A and B is high = no run, A and B is low = switch operation

        delay(3000);                        //make shure the generator stopped due to inertia of motor

        //Make ignition choise available again for manual use
        digitalWrite(IO_CutOffA, LOW);      //Dual relay setup when A is not equal to B = run, A and B is high = no run, A and B is low = switch operation
        digitalWrite(IO_CutOffB, LOW);      //Dual relay setup when A is not equal to B = run, A and B is high = no run, A and B is low = switch operation

        servo1.write(100);                 //Make sure the servo is off
        delay(5000);                        //chill
        onIoTSync();                         //sych base values for cloud
        FSMgeneral = Wait;                  //Next state Wait
        break;
      }
  }
}

void onStateChange() {
  // Add your code here to act upon State change
  stateName = FSMgeneral;
}

void onRunChange() {
  // Add your code here to act upon Run change
  Serial.write("F.C. onRunChange");
  Serial.print('\n');
  Var_Run3 = run; //Set cloud variable to onboard variable
}

void onfuelValveChange() {
  // Add your code here to act upon State change

}

bool RunGenerator() {
  if (ArduinoIOTCloudDesired == LOW) {
    if (((digitalRead(IO_Run1) == HIGH) || (digitalRead(IO_Run2) == LOW)) && (digitalRead(IO_Ac_Detect) == LOW)) {
      return HIGH;
    }
    else if (!((digitalRead(IO_Run1) == HIGH) || (digitalRead(IO_Run2) == LOW))) {
      return LOW;
    }
  }
  else if (ArduinoIOTCloudDesired == HIGH) {
    if (((digitalRead(IO_Run1) == HIGH) || (digitalRead(IO_Run2) == LOW) || (Var_Run3 == HIGH)) && (digitalRead(IO_Ac_Detect) == LOW)) {
      return HIGH;
    }
    else if (!((digitalRead(IO_Run1) == HIGH) || (digitalRead(IO_Run2) == LOW) || (Var_Run3 == HIGH))) {
      return LOW;
    }
  }
}

void ErrorHandler(int ErrorCode) {
  if (ErrorCode == 0)
  {
    //no error
  }
  else if (ErrorCode == 1)
  {
    //not able to start
    FlashStorage_SAMD_WriteError(ErrorCode);
    Serial.write("Error Handler Code 1: ");
    Serial.write("Not able to start engine");
    Serial.print('\n');
    errorState = "Error Handler Code 1: Not able to start engine";
    CustomCloudHandler();              //Update the cloud if we use IOT mode, Stay in this loop until generator hase been shut off
  }
  else if (ErrorCode == 2)
  {
    //loss of AC power, unexpected engine cut-off
    FlashStorage_SAMD_WriteError(ErrorCode);
    Serial.write("Error Handler Code 2: ");
    Serial.write("Loss of AC power, unexpected engine cut-off");
    Serial.print('\n');
    errorState = "Error Handler Code 2: loss of AC power, unexpected engine cut-off";
    CustomCloudHandler();              //Update the cloud if we use IOT mode, Stay in this loop until generator hase been shut off
  }
  else if (ErrorCode == 3)
  {
    //Manual generator operation
    FlashStorage_SAMD_WriteError(ErrorCode);
    Serial.write("Error Handler Code 3: ");
    Serial.write("Generator has manualy been opperated");
    Serial.print('\n');
    errorState = "Generator has manualy been opperated";
    CustomCloudHandler();              //Update the cloud if we use IOT mode, Stay in this loop until generator hase been shut off
  }
  else if (ErrorCode == 4)
  {
    //unknown input for the ignition function
    FlashStorage_SAMD_WriteError(ErrorCode);
    Serial.write("Error Handler Code 4: ");
    Serial.write("Unknown firmware ignition settings");
    Serial.print('\n');
    errorState = "Unknown firmware ignition settings";
    CustomCloudHandler();              //Update the cloud if we use IOT mode, Stay in this loop until generator hase been shut off
  }
  else
  {
    //unknown error 
    Serial.write("Error Handler Code: ");
    Serial.write("unknown");
    Serial.print('\n');
    errorState = "Unknown error";
    CustomCloudHandler();              //Update the cloud if we use IOT mode, Stay in this loop until generator hase been shut off
  }
  //Reset the error state to nothing
  errorState = "";
}

void Ignition(int IgnitionCode) {
  if (IgnitionCode == 0){  //Set iginition to manual operation
    digitalWrite(IO_CutOffA, LOW);     //Dual relay setup when A is not equal to B = run, A and B is high = no run, A and B is low = switch operation
    digitalWrite(IO_CutOffB, LOW);     //Dual relay setup when A is not equal to B = run, A and B is high = no run, A and B is low = switch operation
  }
  else if (IgnitionCode == 1) { //Set iginition to enable 
    digitalWrite(IO_CutOffA, HIGH);     //Dual relay setup when A is not equal to B = run, A and B is high = no run, A and B is low = switch operation
    digitalWrite(IO_CutOffB, LOW);      //Dual relay setup when A is not equal to B = run, A and B is high = no run, A and B is low = switch operation 
  }
  else if (IgnitionCode == 2) { //Set iginition to Disable 
    digitalWrite(IO_CutOffA, HIGH);     //Dual relay setup when A is not equal to B = run, A and B is high = no run, A and B is low = switch operation
    digitalWrite(IO_CutOffB, HIGH);     //Dual relay setup when A is not equal to B = run, A and B is high = no run, A and B is low = switch operation
  }
  else {  //in case of a fault in the program set ignition to manual
    ErrorHandler(4);
    digitalWrite(IO_CutOffA, LOW);     //Dual relay setup when A is not equal to B = run, A and B is high = no run, A and B is low = switch operation
    digitalWrite(IO_CutOffB, LOW);     //Dual relay setup when A is not equal to B = run, A and B is high = no run, A and B is low = switch operation
  }
}

void FlashStorage_SAMD_Setup() {
  // Check signature at address 0
  int signature;

  EEPROM.get(0, signature);
  
  Serial.println(""); //Make some room on serial display
  Serial.println("- - - Start of Error Setup informarion - - - "); //Make some room on serial display

  // If the EEPROM is empty then no WRITTEN_SIGNATURE
  if (signature != WRITTEN_SIGNATURE)
  {
    
    Serial.println("EEPROM is empty, writing WRITTEN_SIGNATURE and Setting Error Count to 0");

    EEPROM.put(0, WRITTEN_SIGNATURE);                   //Signature
    EEPROM.put(ErrorCountLocation, 0x00);               //Error count, until what adres is the flash used to store errors
    Serial.print("");
  }
  //If the eeprom is not empty get the amount of stored errors, the value this gives is the first next free adres for the error
  else
  {
    EEPROM.get(0, signature);
    Serial.print("EEPROM has already been written it's Signature is: 0x");
    Serial.println(signature, HEX);

    EEPROM.get(ErrorCountLocation, ErrorCount);
    Serial.print("The Error count is: ");
    Serial.println((ErrorCount));                                                                     //This gives the amount of errors that are saved in the flash memory
  }
  
  Serial.println("- - - End of Error Setup informarion - - - ");                                      //Make some room on serial display
  Serial.println("");                                                                                 //Make some room on serial display
}

void FlashStorage_SAMD_ReadErrors() {
  //Print information about the Errors
  Serial.println("");                                                                                 //Make some room on serial display
  Serial.println("- - - Start of Error informarion - - - ");                                          //Make some room on serial display
  Serial.println("Errors are displayed as two values: [Unix timestamp, Error code]");
  Serial.println("Error Codes Decodation:");
  Serial.println("Error Code 1 ->  Not able to start engine");
  Serial.println("Error Code 2 ->  Loss of AC power, unexpected engine cut-off");
  Serial.println("Error Code 3 ->  Generator has manualy been opperated");
  Serial.println("Error Code 4 ->  Unknown firmware ignition settings");
  Serial.println("Error Code 5 ->  unknown");
  Serial.println("");
  Serial.println("Unix timestamp declaration: if value is 0, no time was saved");
  Serial.println(" "); //Make some room on serial display
  
  //Print out the saved errors
  Serial.print("Error Count: ");
  Serial.println(ErrorCount);
  for (int i = (ErrorCountLocation + 1); i < (ErrorCountLocation + 1 + (ErrorCount*(sizeof(struct ErrorMessage)))); i = i + (sizeof(struct ErrorMessage))) {
    ErrorMessage customVar; //Variable to store custom object read from EEPROM.
    EEPROM.get(i, customVar );
    Serial.print("Flash (EEPROM) Error Message: ");
    Serial.print(customVar.ErrorMessageUnixtime );
    Serial.print(", ");
    Serial.println(customVar.ErrorMessageValue );
  }
  
  Serial.println("- - - End of Error informarion - - - ");                                            //Make some room on serial display
  Serial.println("");                                                                                 //Make some room on serial display
}

void FlashStorage_SAMD_WriteError(byte Value) {
  //Fill in the struct
  long testvalue = ArduinoCloud.getLocalTime();
  ErrorMessage customvar = {
    testvalue,
    Value
  };
  int NextOpenEepromAdres = ((ErrorCount*(sizeof(struct ErrorMessage))) + ErrorCountLocation + 1);
  
  //The Time stamp is saved with the most significant byte last, this means, adres9 + adres8 + adres7 + adres6
  ErrorCount++;                                                       //increment the error count with 1
  EEPROM.put(ErrorCountLocation, ErrorCount);                         //Put the error count value in the flash memory
  EEPROM.put(NextOpenEepromAdres, customvar);                         //put the error code in the next open eeprom adres
}

void CustomCloudHandler() {
  if (ArduinoIOTCloudDesired == LOW) {
    //Do Nothing
  }
  else if (ArduinoIOTCloudDesired == HIGH) {
    ArduinoCloud.update();    //synch values with the cloud
  }
}



Thanks in advance for any input,
Manu

I’ve not looked at the code but restarting could be a wiring/load/interface type issue maybe present. IC engines are electrically noisy and maybe a cause .
It would be useful to see a wiring schematic .

1 Like

I would really like to see the answers to your questions too. The watchdog timer seems to be about 16 seconds

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