Using Millis to Turn On/Off Relay for a set interval

This makes total sense, now that I'm reviewing the code again.

Ok so I tested the code on my hardware and overall I really like the improvements to the functionality, especially the button features, but I'm still haunted by the RelayValve4 only turning off briefly every 15 seconds. The goal is to have RelayValve4 turn on for 15 seconds during ST_RUN then turn off, and stay off, until the else if condition is met.

I would assume that the same problem will arise when the else if condition is met.

This is another problem I'm seeing. The controller is almost constantly in a delay state so I have to keep my finger on the button for 15 or 30 seconds, depending on the condition that's running, in order for the ST_SHUTDOWN register.

Is it possible to put the delay(s) in an initialization state that runs only once when either the if or else if condition is met? I feel like it's groundhog day with this problem.

Here is the code, I had to to get rid of the sprintf function, it wasn't displaying correctly on my LCD. Also I moved the startup message down to the ST_IDLE case.

#include <Wire.h> //allows communication over i2c devices
#include <EEPROM.h> //Electronically erasable programmable memory library
#include <LiquidCrystal_I2C.h> //allows interfacing with LCD screens
#include <Bounce2.h> //Button debouncing library

//Inputs
int pressureInput = A7; //sets the analog input pin for the pressure transducer
int RedEnd = 10; //sets address of end loop button on Nano digital pins

//Digital Outputs
int ConcRelay1 = 2; //sets address of concentrator1 relay on digital pins found on Nano
int ConcRelay2 = 3; //sets address of concentrator2 relay on digital pins found on Nano
int CompRelay3 = 4; //sets address of compressor relay on digital pins found on Nano
int ValveRelay4 = 5; //sets address of unloader valve relay on digital pins found on Nano

//Start and stop pressure values
const int Start = 40; //concentrators and compressor start at 40 PSI
const int Stop = 85; //concentrators and compressor stop at 85 PSI

const long solenoidInterval = 30000;  // 30 sec
const long warmInterval     = 15000;  // 15 sec


LiquidCrystal_I2C lcd (0x27, 16, 2); //sets the LCD I2C communication address; format (address, columns, rows)
Bounce debouncer = Bounce (); //instantiates a bounce object

// -----------------------------------------------------------------------------

// this is the EEPROM section
int eeAddress1 = 10;                // this sets the eeAddress1 tag and sets the address to 10, eeprom
int eeAddress2 = 20;                // this sets the eeAddress2 tag and sets the address to 20, eeprom

//Debounce section
byte butState;

// -----------------------------------------------------------------------------
void setup () //setup routine, runs once when system turned on or reset
{
    //  this section assigns the inputs and outputs
 
    // inputs
    pinMode (RedEnd,INPUT_PULLUP);              // End loop button
    butState = digitalRead (RedEnd);

    // outputs
    pinMode      (ConcRelay1, OUTPUT);            // concentrator1 relay
    digitalWrite (ConcRelay1, LOW);        // initially sets output tag "ConcRelay1" low
    pinMode      (ConcRelay2, OUTPUT);          // concentrator2 relay
    digitalWrite (ConcRelay2, LOW);       // initially sets output tag "ConcRelay2" low
    pinMode      (CompRelay3, OUTPUT);            // comperssor relay
    digitalWrite (CompRelay3, LOW);         // initially sets output tag "CompRelay3" low
    pinMode      (ValveRelay4, OUTPUT);         // unloader valve relay
    digitalWrite (ValveRelay4, LOW);      // initially sets output tag "ValveRelay4" low 
  
    // Retrieves the setpoints from the arduino eeprom so the unit can start up after a power fail
    EEPROM.get (eeAddress1, Start);         // retrieves the start psi from eeprom
    EEPROM.get (eeAddress2, Stop);          // retrieves the stop psi from eeprom
  
    //  Starts up the different libraries
    Serial.begin (9600); // start the serial monitor at 9600 baud
    lcd.init ();         // start the lcd library
    lcd.backlight ();    // turn on the lcd backlight
    lcd.clear ();        // clear the cld screen
    Wire.begin ();       // start the I2C library

    //Start up messge
    lcd.setCursor (2,0); //sets cursor to column 2, row 0
    lcd.print ("Hello There!"); //prints label
    lcd.setCursor (0,1); //sets cursor to column 0, row 1
    lcd.print ("Press Red Button");

    lcd.clear ();
}

// -----------------------------------------------------------------------------
void monitor ()
{
    // measure pressure
    int psi = analogRead (pressureInput);
    psi = map (psi, 102, 922, 0, 150);

// This section prints the PSI value caluculated from transducer to the LCD screeen
  lcd.clear ();
  Serial.print(psi, 1); //prints value from previous line to serial
  Serial.println("psi"); //prints label to serial
  lcd.setCursor(0,0); //sets cursor to column 0, row 0
  lcd.print("Current= "); //prints label
  lcd.setCursor(10,0); //sets cursor to column 10, row 0
  lcd.print(psi); //prints pressure value to lcd screen
  lcd.setCursor(12,0); //sets cursor to column 12, row 0
  lcd.print("PSI"); //prints label after value
  lcd.print("   "); //to clear the display after large values or negatives

  lcd.setCursor(0,1); //sets cursor to column 0, row 1
  lcd.print ("Min=40 ; Max=85"); //prints Start and Stop pressure values

    // check for stop condition
    if (psi >= Stop )  {
        digitalWrite (ConcRelay1 ,  LOW);
        digitalWrite (ConcRelay2 ,  LOW);
        digitalWrite (CompRelay3 ,  LOW);
        digitalWrite (ValveRelay4 , HIGH);

        delay (solenoidInterval);
        
        digitalWrite (ValveRelay4 , LOW);
    }

    else if (psi <= Start){
        digitalWrite (ConcRelay1 , HIGH);
        digitalWrite (ConcRelay2 , HIGH);
        digitalWrite (ValveRelay4 , HIGH);

        delay (warmInterval);

        digitalWrite (ValveRelay4 , LOW);
        digitalWrite (CompRelay3 , HIGH);
    }
}

// -----------------------------------------------------------------------------
void loop ()
{
    enum { ST_IDLE, ST_RUN, ST_SHUTDOWN };
    static int state = ST_IDLE;

    switch (state)  {
    case ST_RUN:
        monitor ();
        break;

    case ST_SHUTDOWN:
        digitalWrite (ConcRelay1 ,  LOW);
        digitalWrite (ConcRelay2 ,  LOW);
        digitalWrite (CompRelay3 ,  LOW); 
        digitalWrite (ValveRelay4 , HIGH);

        lcd.clear ();
        lcd.setCursor (1,0); //sets cursor to column 1, row 0
        lcd.print ("Program Ended!"); //prints label
        delay(45000);
        
        state = ST_IDLE;
        break;

    case ST_IDLE:
       
        lcd.setCursor (2,0); //sets cursor to column 2, row 0
        lcd.print ("Hello There!"); //prints label
        lcd.setCursor (0,1); //sets cursor to column 0, row 1
        lcd.print ("Press Red Button");

        break;
    }

    byte but = digitalRead (RedEnd);
    if (butState != but)  {
        butState = but;
        delay (10);         // debounce

        if (LOW == but)  {  // press
            if (ST_IDLE == state)
                state = ST_RUN;
            else
                state = ST_SHUTDOWN;
        }
    }
}