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;
}
}
}