Issue with millis() timing

The following code should:

Start Pump 1 when Hi Limit activated (Water tank full)
Latch Pump 1 on until Lo Limit reached (Pump water until tank empty)
If not empty >30 seconds Start Pump 2
If not empty >60 seconds Set Alarm 1

What i am getting when testing is all 3 outputs on straight away when Hi Limit activated instead of the 30 second sequence i had planned.

Any ideas where i am going wrong?

#include <SPI.h>
//.........................................................................................
// Variables

// Set Arduino Pin Numbers:

// Float Switch Pin Numbers:
const int PIN_FLOAT_HI_LIMIT = 2; // High Level Limit (Hi)
const int PIN_FLOAT_LO_LIMIT = 3; // Low Level Limit (Lo)

// Pump Pin Numbers
const int PIN_PUMP_1_ACTIVE = 4; // Pump 1 Run
const int PIN_PUMP_2_ACTIVE = 5; // Pump 2 Run

// Alarm LED Pin Numbers:
const int PIN_ALARM_1 = 6; // Warning Expected Pump Time Exceeded

// Input Status
int STATE_FLOAT_HI_LIMIT = 0; // High Level Limit (Hi) Status
int STATE_FLOAT_LO_LIMIT = 0; // Low Level Limit (Lo) Status

// Output Status
int STATE_ALARM_1 = 0; // Alarm 1 Status
int STATE_PUMP_1 = 0;  // Pump 1 Run Status
int STATE_PUMP_2 = 0;  // Pump 2 Run Status

// Global Variables Used For Timer
unsigned long startMillis; // Reset Timer Reference
unsigned long currentMillis; // Current Timer Value
const unsigned long period = 30000; // Set Period 1s = 1000ms Set=30s

//.........................................................................................
void setup() {
  // put your setup code here, to run once:
  
  // Start SPI Libary
  SPI.begin();

  // Initialise Float Switches as Inputs
  pinMode(PIN_FLOAT_HI_LIMIT, INPUT_PULLUP);
  pinMode(PIN_FLOAT_LO_LIMIT, INPUT_PULLUP);

  // Initialsie Pumps as Outputs
  pinMode(PIN_PUMP_1_ACTIVE, OUTPUT);
  pinMode(PIN_PUMP_2_ACTIVE, OUTPUT);

  // Initialise Alarm LEDs as Outputs
  pinMode(PIN_ALARM_1, OUTPUT);
}

//.........................................................................................
void loop() {
  // put your main code here, to run repeatedly:

  // IO Read/Write
  // Input Status Check (Read)
  
  STATE_FLOAT_HI_LIMIT = digitalRead(PIN_FLOAT_HI_LIMIT); // High Level Limit (Hi) Status Check
  STATE_FLOAT_LO_LIMIT = digitalRead(PIN_FLOAT_LO_LIMIT); // Low Level Limit (Lo) Status Check
  
  // Output Set (Write)
  
  digitalWrite(PIN_ALARM_1, STATE_ALARM_1);      // SET - Warning Expected Pump Time Exceeded
  digitalWrite(PIN_PUMP_1_ACTIVE, STATE_PUMP_1); // SET - Pump 1 Run
  digitalWrite(PIN_PUMP_2_ACTIVE, STATE_PUMP_2); // SET - Pump 2 Run

//.........................................................................................
// Hi Limit Float Activated  
  if (STATE_FLOAT_HI_LIMIT == HIGH) 
    {  

// Latch - Pump Run Until Lo Limit Float De-Activated
    while (STATE_FLOAT_LO_LIMIT == HIGH) 
      {
      startMillis = millis(); // Initial Pump Run Start Time 0s
      digitalWrite(PIN_PUMP_1_ACTIVE, HIGH); // Duty Pump On
      
// Pump Run Time >30s Start Standby Pump
      if (currentMillis - startMillis >= period) // Time Elapsed >= 30s
        {
        startMillis = millis(); // Reset Time 0s
        digitalWrite(PIN_PUMP_2_ACTIVE, HIGH); //Standby Pump On
        
// Pump Run Time >60s Set Alarm 1
        if (currentMillis - startMillis >= period) // Total Time Elapsed >= 60s
          {
          digitalWrite(PIN_ALARM_1, HIGH); // SET - Warning Expected Pump Time Exceeded
          }
      
      STATE_FLOAT_LO_LIMIT = digitalRead(PIN_FLOAT_LO_LIMIT); // Loop Exit
      if (STATE_FLOAT_LO_LIMIT == LOW)
          {
          break;
          }
         }
      }
    }

// Lo Limit Float De-Activated Pump/'s OFF
  else (STATE_FLOAT_HI_LIMIT == LOW && STATE_FLOAT_LO_LIMIT == LOW);
    {
    digitalWrite(PIN_PUMP_1_ACTIVE, LOW); //Duty Pump Off
    digitalWrite(PIN_PUMP_2_ACTIVE, LOW); //Standby Pump Off
    }
    
}
if (currentMillis - startMillis >= period)

I don't see where you are setting currentMillis. Eliminate currentMillis, and just write

if (millis() - startMillis >= period)

This might give you some ideas;

//larryD
//Sump pump sketch.
//Version 1.0 Jan 8, 2019
//
//Water at >= High level turns ON 1st pump.
//At 30sec 2nd pumps turns ON if Low level is not reached.
//At 60sec Alarm ON if Low level not reached.
//At <= Low level Pumps and Alarm OFF.
//Pumps alternate.
//

#define PUMPON   LOW
#define PUMPOFF  HIGH

#define ALARMON  LOW
#define ALARMOFF HIGH

const byte heartBeatLED = 13;
const byte Pump1        = 8;
const byte Pump2        = 9;
const byte Alarm        = 4;
const byte sensorPin    = A0;

byte currentPump        = Pump1;

bool firstPumpFlag      = false;
bool secondPumpFlag     = false;

int LowThreshold  = 102;  //10%
int HighThreshold = 930;  //90%

//timing variables
unsigned long MillisHeartBeat;
unsigned long Millis1stPump;
unsigned long Millis2ndPump;
unsigned long MillisCheckSump;

//***********************************************************************************
void setup()
{
  pinMode (heartBeatLED, OUTPUT);

  pinMode (Pump1, OUTPUT);
  digitalWrite(Pump1, PUMPOFF);

  pinMode (Pump2, OUTPUT);
  digitalWrite(Pump2, PUMPOFF);

  pinMode (Alarm, OUTPUT);
  digitalWrite(Alarm, ALARMOFF);

} //END of setup()

//***********************************************************************************
void loop()
{
  //*************************
  //code to see if the sketch is blocking, LED will toggle every 500ms
  if (millis() - MillisHeartBeat >= 500)
  {
    MillisHeartBeat = millis();

    //toggle LED state
    digitalWrite(heartBeatLED, !digitalRead(heartBeatLED));
  }

  //*************************
  //is it time to check the sump?
  if (millis() - MillisCheckSump >= 50) //every 50ms
  {
    //re-initialize this timer
    MillisCheckSump = millis();

    //go and check the sump
    checkSumpCondition();
  }

  //*************************
  //None blocking code goes here
  //*************************

} //END of loop()

//***********************************************************************************
//                     c h e c k S u m p C o n d i t i o n ( )
//
void checkSumpCondition()
{
  //*************************
  //has the water gone below the 'low' threshold?
  if (analogRead(sensorPin) <= LowThreshold)
  {
    //disable pump timing
    firstPumpFlag  = false;
    secondPumpFlag = false;

    //stop pumps
    digitalWrite(Pump1, PUMPOFF);
    digitalWrite(Pump2, PUMPOFF);

    //cancel alarm
    digitalWrite(Alarm, ALARMOFF);
  }

  //*************************
  //when not timing, has the water gone above the 'high' threshold?
  if (firstPumpFlag == false && secondPumpFlag == false && analogRead(sensorPin) >= HighThreshold)
  {
    //water too high, start the 1st pump
    digitalWrite(currentPump, PUMPON);

    //enable 1st pump timing
    firstPumpFlag = true;

    //time the 1st pump started
    Millis1stPump = millis();

    //handle next pump selection
    if (currentPump == Pump1)
    {
      currentPump = Pump2;
    }
    else
    {
      currentPump = Pump1;
    }
  }

  //*************************
  //is the 1st pump timing enabled and has it expired?
  if (firstPumpFlag == true && millis() - Millis1stPump >= 30000)
  {
    //timer has expired, start the 2nd pump
    digitalWrite(currentPump, PUMPON);

    //disable 1st pump timing
    firstPumpFlag = false;

    //enable 2nd pump timing
    secondPumpFlag = true;

    //Time the 2nd pump started
    Millis2ndPump = millis();

    //handle next pump selection
    if (currentPump == Pump1)
    {
      currentPump = Pump2;
    }
    else
    {
      currentPump = Pump1;
    }
  }

  //*************************
  //is the 2nd pump timing enabled and has it expired?
  if (secondPumpFlag == true && millis() - Millis2ndPump >= 30000)
  {
    //timer has expired, bring up alarm
    digitalWrite(Alarm, ALARMON);
  }

} //END checkSumpCondition()

//***********************************************************************************

Perehama:

if (currentMillis - startMillis >= period)

I don't see where you are setting currentMillis. Eliminate currentMillis, and just write

if (millis() - startMillis >= period)

I have tried the above with no joy the loop dosnt exit and the sequence dosnt run through

Look at code in post #2.

It should do 99.9% of what you need.

You will need to use switches instead of analog input.

larryd:
This might give you some ideas;

//larryD

//Sump pump sketch.
//Version 1.0 Jan 8, 2019
//
//Water at >= High level turns ON 1st pump.
//At 30sec 2nd pumps turns ON if Low level is not reached.
//At 60sec Alarm ON if Low level not reached.
//At <= Low level Pumps and Alarm OFF.
//Pumps alternate.
//

#define PUMPON   LOW
#define PUMPOFF  HIGH

#define ALARMON  LOW
#define ALARMOFF HIGH

const byte heartBeatLED = 13;
const byte Pump1        = 8;
const byte Pump2        = 9;
const byte Alarm        = 4;
const byte sensorPin    = A0;

byte currentPump        = Pump1;

bool firstPumpFlag      = false;
bool secondPumpFlag     = false;

int LowThreshold  = 102;  //10%
int HighThreshold = 930;  //90%

//timing variables
unsigned long MillisHeartBeat;
unsigned long Millis1stPump;
unsigned long Millis2ndPump;
unsigned long MillisCheckSump;

//***********************************************************************************
void setup()
{
 pinMode (heartBeatLED, OUTPUT);

pinMode (Pump1, OUTPUT);
 digitalWrite(Pump1, PUMPOFF);

pinMode (Pump2, OUTPUT);
 digitalWrite(Pump2, PUMPOFF);

pinMode (Alarm, OUTPUT);
 digitalWrite(Alarm, ALARMOFF);

} //END of setup()

//***********************************************************************************
void loop()
{
 //*************************
 //code to see if the sketch is blocking, LED will toggle every 500ms
 if (millis() - MillisHeartBeat >= 500)
 {
   MillisHeartBeat = millis();

//toggle LED state
   digitalWrite(heartBeatLED, !digitalRead(heartBeatLED));
 }

//*************************
 //is it time to check the sump?
 if (millis() - MillisCheckSump >= 50) //every 50ms
 {
   //re-initialize this timer
   MillisCheckSump = millis();

//go and check the sump
   checkSumpCondition();
 }

//*************************
 //None blocking code goes here
 //*************************

} //END of loop()

//***********************************************************************************
//                     c h e c k S u m p C o n d i t i o n ( )
//
void checkSumpCondition()
{
 //*************************
 //has the water gone below the 'low' threshold?
 if (analogRead(sensorPin) <= LowThreshold)
 {
   //disable pump timing
   firstPumpFlag  = false;
   secondPumpFlag = false;

//stop pumps
   digitalWrite(Pump1, PUMPOFF);
   digitalWrite(Pump2, PUMPOFF);

//cancel alarm
   digitalWrite(Alarm, ALARMOFF);
 }

//*************************
 //when not timing, has the water gone above the 'high' threshold?
 if (firstPumpFlag == false && secondPumpFlag == false && analogRead(sensorPin) >= HighThreshold)
 {
   //water too high, start the 1st pump
   digitalWrite(currentPump, PUMPON);

//enable 1st pump timing
   firstPumpFlag = true;

//time the 1st pump started
   Millis1stPump = millis();

//handle next pump selection
   if (currentPump == Pump1)
   {
     currentPump = Pump2;
   }
   else
   {
     currentPump = Pump1;
   }
 }

//*************************
 //is the 1st pump timing enabled and has it expired?
 if (firstPumpFlag == true && millis() - Millis1stPump >= 30000)
 {
   //timer has expired, start the 2nd pump
   digitalWrite(currentPump, PUMPON);

//disable 1st pump timing
   firstPumpFlag = false;

//enable 2nd pump timing
   secondPumpFlag = true;

//Time the 2nd pump started
   Millis2ndPump = millis();

//handle next pump selection
   if (currentPump == Pump1)
   {
     currentPump = Pump2;
   }
   else
   {
     currentPump = Pump1;
   }
 }

//*************************
 //is the 2nd pump timing enabled and has it expired?
 if (secondPumpFlag == true && millis() - Millis2ndPump >= 30000)
 {
   //timer has expired, bring up alarm
   digitalWrite(Alarm, ALARMON);
 }

} //END checkSumpCondition()

//***********************************************************************************

Thanks i will take a look. I see you are using a sensor instead of High and Low floats switches what type of sensor is it that you are using ultrasonic?

mtom1991:
Thanks i will take a look. I see you are using a sensor instead of High and Low floats switches what type of sensor is it that you are using ultrasonic?

No, you can use a 'water float' that closes/opens two limit switches.

The output of the switches are connected to A0 analog input, provides:
2.5V
0V
5V

Never close both switches at the same time ! :wink: