Locking Out Push Button with Select-able Delay?

I have a program i am working on where a relay is turned on -> waits a delay -> then turns off after either one of two things happen: 1) A set timer is reached OR 2) someone pushes a push button to trigger it.

Right now 75% of my code is working and i am stuck on how i go about "locking out" the push button from triggering the relay, for a select-able amount of delay time.

The timer portion of the code, with select-able times, is working. Depending on what analog 1 see's, it will trigger the relay appropriately after the selected time.

I tried to implement this same approach for the lock out timer, using analog 2 , to determine how long of a delay. I used a variable i called LOK to either read the button if it is unlocked (LOK = 0) or if it is locked (LOK =1) to wait the allotted delay time before unlocking and allowing the button to be read again.

I've tried all sorta of things and it still isn't functioning right. Maybe there is a better or simpler way to do this but I've racked my brain, and key word searching isn't helping.

Code below - please forgive random comments. I've been chopping up and moving things around i haven't eddited any comments , so some may be from other snippets of codes from otehr projects.

int DUMP = 2; // Pin connected to big dump relay
int BUTTON = 3; // Pin connected to manual dump push button.
int BUTTONlight = 4; // Pin connected to push button light.


int BUTstate; // Current reading from BUTTON pin
int lastBUTstate = LOW; // Previous reading from BUTTON pin

long lastDebounce = 0; // Last time output was changed
long Delay = 50; // Debounce Time

unsigned long LOT;

unsigned long DUMPTIME;
unsigned long prevTIME;

int a=0;
int d=0;

int LOK = 0;


void setup()
{ 
  pinMode(A1, INPUT);
  pinMode(A2, INPUT);
  
  pinMode (BUTTON, INPUT);
  pinMode (BUTTONlight, OUTPUT);
  pinMode (DUMP, OUTPUT);
  
  digitalWrite(DUMP, HIGH);
  delay(10000);
  digitalWrite(DUMP, LOW);
  
}

int readDTselector(int pin)
// returns the button number pressed, or zero for none pressed 
// int pin is the analog pin number to read 
{
  int b,c = 1;
  c=analogRead(pin); // get the analog value  
  if (c>1000)
  {
    b=0; // buttons have not been pressed
  }   
  else
    if (c<1000 && c>600)
    {
      b=1; // button 1 pressed
    }     
    else
      if (c<520 && c>400)
      {
        b=2; // button 2 pressed
      }       
      else
        if (c>100 && c<400)
        {
          b=3; // button 3 pressed
        }         
        else
          if (c<100)
          {
            b=4; // button 4 pressed
          }           
  return b; 
  }

int readLOselector(int pin)
// returns the button number pressed, or zero for none pressed 
// int pin is the analog pin number to read 
{
  int e,g = 2;
  g=analogRead(pin); // get the analog value  
  if (g>1000)
  {
    e=0; // buttons have not been pressed
  }   
  else
    if (g<1000 && g>600)
    {
      e=1; // button 1 pressed
    }     
    else
      if (g<520 && g>400)
      {
        e=2; // button 2 pressed
      }       
      else
        if (g>100 && g<400)
        {
          e=3; // button 3 pressed
        }         
        else
          if (g<100)
          {
            e=4; // button 4 pressed
          }           
  return e; 
  }

void loop()
{
  DTselect();
  LOselect(); 
  int reading = digitalRead(BUTTON);
  
  
  unsigned long currTIME = millis();
    
  if (LOK == 0)
  {
    digitalWrite(BUTTONlight, HIGH);
    if (reading != lastBUTstate)
    {
      lastDebounce = millis();
    }
  
    if ((millis() - lastDebounce) > Delay)
    {
      BUTstate = reading;
    }
  }
  
  if ((currTIME - prevTIME) >= DUMPTIME || BUTstate == HIGH ) // Count to 2 minutes
   {
     LOK = 1;
     digitalWrite(BUTTONlight, LOW);
     digitalWrite(DUMP, HIGH);
     delay(10000);
     digitalWrite(DUMP, LOW);
     prevTIME = currTIME;
   }
  
  if (LOK == 1)
  {
    delay(LOT);
    LOK = 0;
  }
  
  lastBUTstate = reading;
}

int DTselect()
{
  a=readDTselector(1); 
  if (a==0) // no buttons pressed
  {
    DUMPTIME = 210000;
  }   
  else
    if (a==1) // someone pressed a button!
    {
      DUMPTIME = 180000;
    }
    else
     if (a==2) // someone pressed a button!
     {
       DUMPTIME = 150000;
     }
     else
      if (a==3) // someone pressed a button!
      {
        DUMPTIME = 120000;
      }
      else
       if (a==4) // someone pressed a button!
       {
         DUMPTIME = 90000;
       }
  return DUMPTIME; 
 }

int LOselect()
{
  d=readLOselector(2); 
  if (d==0) // no buttons pressed
  {
    LOT = 20000;
  }   
  else
    if (d==1) // someone pressed a button!
    {
      LOT = 15000;
    }
    else
     if (d==2) // someone pressed a button!
     {
       LOT = 10000;
     }
     else
      if (d==3) // someone pressed a button!
      {
        LOT = 5000;
      }
      else
       if (d==4) // someone pressed a button!
       {
         LOT = 0;
       }
   return LOT;    
 }

Right now 75% of my code is working and i am stuck on how i go about "locking out" the push button from triggering the relay, for a select-able amount of delay time.

You are thinking incorrectly. You need to be thinking "How do I ignore, for some period of time, the fact that a switch has changed state?".

Given that, it seems pretty simple.

How do readDTselector() and readLOselector() differ? They look identical to me.

Why do DTselect() and LOselect() return values that you ignore? Why do they diddle with global variables? Why do you need to return a global variable?

I don't understand why you want to ignore the switch for any period of time, when the switch appears to be there to allow an operator to abort a process.

PaulS:
You are thinking incorrectly. You need to be thinking "How do I ignore, for some period of time, the fact that a switch has changed state?".

Given that, it seems pretty simple.

How do readDTselector() and readLOselector() differ? They look identical to me.

Why do DTselect() and LOselect() return values that you ignore? Why do they diddle with global variables? Why do you need to return a global variable?

I don't understand why you want to ignore the switch for any period of time, when the switch appears to be there to allow an operator to abort a process.

I see. Ignoring the state change for a given time vs locking off the entire reading of the switch seems simpler. But i don't still get why the selection of this "given time" isn't operating like the other...

readDTselector() and readLOselector() only differ in the fact that they A) are seperate inputs to drive two seperate times, which may not be in the same position. AKA DUMPTIME is a longer delay for the timer to use, while LOT is the shorter delay i'd like "lock out" the push button from.

What do you mean ignoring values? in the loop DTselect() returns DUMPTIME to the timer portion of the circuit. LOT ideally is my "lock out" time for the pushbutton.

I want to ignore the switch because without doing so, immediately after the if ((currTIME - prevTIME) >= DUMPTIME || BUTstate == HIGH ) is finished, the user could hit the button again and go straight back into that statement. I want to prevent this because it is not an Estop or a back out, it's a trigger to initiate the process. I want to stall this process from being able to be done immeditely after that if() statement is done in my case.

readDTselector() and readLOselector() only differ in the fact that they A) are seperate inputs to drive two seperate times

They each read the input pin. They each make the same decisions. They each return a value that is in a local variable. You only need one of them. You call it with different pin numbers, if appropriate, and store the returned value in different variables.

AKA DUMPTIME is a longer delay for the timer to use, while LOT is the shorter delay i'd like "lock out" the push button from.

That is an explanation of how DTselect() and LOselect() call the two different functions, not why there are two different functions that do exactly the same thing.

What do you mean ignoring values?

In loop(), you call the functions:

void loop()
{
  DTselect();
  LOselect();

You do not save the values that they return. That is ignoring the returned value. If the functions didn't diddle with global variables, which they shouldn't do, what they do would be lost.

What you should have is

void loop()
{
  int DUMPTIME = DTselect();
  int LOT = LOselect();

DUMPTIME and LOT should not be global variables.

I want to ignore the switch because without doing so, immediately after the if ((currTIME - prevTIME) >= DUMPTIME || BUTstate == HIGH ) is finished, the user could hit the button again and go straight back into that statement. I want to prevent this because it is not an Estop or a back out, it's a trigger to initiate the process. I want to stall this process from being able to be done immeditely after that if() statement is done in my case.

So, the name of the variable that contains the pin number that the switch is connected to should reflect the purpose of the switch and the fact that it holds a pin number. The name of the variable that holds the state of the switch should reflect the purpose of the switch and the fact that it holds the state of the switch.

On any given pass through loop(), you know what time it is. At least, relative to when the Arduino was reset.

On any given pass through loop(), you know when the process was last started. Or, you could, if you recorded when the process started. Whatever that process is...

So, on any given pass through loop(), you could know whether or not to allow the process to be started again. If you do not want to let the process start, don't read the start switch state.

So i should combine the two select functions into one and call them with A1 and A2 separately? How do i define the sepaarte times then without separate if/else statements?

PaulS:
So, the name of the variable that contains the pin number that the switch is connected to should reflect the purpose of the switch and the fact that it holds a pin number. The name of the variable that holds the state of the switch should reflect the purpose of the switch and the fact that it holds the state of the switch.

On any given pass through loop(), you know what time it is. At least, relative to when the Arduino was reset.

On any given pass through loop(), you know when the process was last started. Or, you could, if you recorded when the process started. Whatever that process is...

So, on any given pass through loop(), you could know whether or not to allow the process to be started again. If you do not want to let the process start, don't read the start switch state.

How do i know wether or not to allow the process without some indication from the statement when the process is triggered? I set a variable to 1 to indicate lok, but how do i check that with my intended delay in regards to the input?

So i should combine the two select functions into one and call them with A1 and A2 separately?

Yes.

How do i define the sepaarte times then without separate if/else statements?

The separate functions detect which switches on the resistor ladder connected to the two separate pins were pressed. They have NOTHING to do with selecting times. That is done in the DTselect() and LOselect() functions, based on which switch was pressed.

How do i know wether or not to allow the process without some indication from the statement when the process is triggered?

You don't. You must record when the process starts.

I set a variable to 1 to indicate lok

I imagine that you know what lok means. I don't.

but how do i check that with my intended delay in regards to the input?

I'm lost. I don't know what "that" is that you want to to check with regards to what input.

PaulS:
The separate functions detect which switches on the resistor ladder connected to the two separate pins were pressed. They have NOTHING to do with selecting times. That is done in the DTselect() and LOselect() functions, based on which switch was pressed.

Ah. So only using one of the DTselector() or LOselector () on its on, and using DTselect() and LOselect() to determine. Like so?

int readTselector(int pin)
// returns the button number pressed, or zero for none pressed
// int pin is the analog pin number to read
{
  int b,c = 1;
  c=analogRead(pin); // get the analog value 
  if (c>1000)
  {
    b=0; // buttons have not been pressed
  }   
  else
    if (c<1000 && c>600)
    {
      b=1; // button 1 pressed
    }     
    else
      if (c<520 && c>400)
      {
        b=2; // button 2 pressed
      }       
      else
        if (c>100 && c<400)
        {
          b=3; // button 3 pressed
        }         
        else
          if (c<100)
          {
            b=4; // button 4 pressed
          }           
  return b;
  }

int DTselect()
{
  a=readTselector(1);
  if (a==0) // no buttons pressed
  {
    DUMPTIME = 210000;
  }   
  else
    if (a==1) // someone pressed a button!
    {
      DUMPTIME = 180000;
    }
    else
     if (a==2) // someone pressed a button!
     {
       DUMPTIME = 150000;
     }
     else
      if (a==3) // someone pressed a button!
      {
        DUMPTIME = 120000;
      }
      else
       if (a==4) // someone pressed a button!
       {
         DUMPTIME = 90000;
       }
  return DUMPTIME;
 }

int LOselect()
{
  d=readTselector(2);
  if (d==0) // no buttons pressed
  {
    LOT = 20000;
  }   
  else
    if (d==1) // someone pressed a button!
    {
      LOT = 15000;
    }
    else
     if (d==2) // someone pressed a button!
     {
       LOT = 10000;
     }
     else
      if (d==3) // someone pressed a button!
      {
        LOT = 5000;
      }
      else
       if (d==4) // someone pressed a button!
       {
         LOT = 0;
       }
   return LOT;

You don't. You must record when the process starts.

I imagine that you know what lok means. I don't.

LOK is what i am using to "record" when the process starts. in the if() statement i set LOK= 1 to indicate this process ran, then tried to use that indicator to use LOselect() delay time to wait for that ammount of time, and then set LOK back to 0, allowing the button to be read.

 if (LOK == 0)
  {
    digitalWrite(BUTTONlight, HIGH);
    if (reading != lastBUTstate)
    {
      lastDebounce = millis();
    }
 
    if ((millis() - lastDebounce) > Delay)
    {
      BUTstate = reading;
    }
  }
 
  if ((currTIME - prevTIME) >= DUMPTIME || BUTstate == HIGH ) // Count to 2 minutes
   {
     LOK = 1;
     digitalWrite(BUTTONlight, LOW);
     digitalWrite(DUMP, HIGH);
     delay(10000);
     digitalWrite(DUMP, LOW);
     prevTIME = currTIME;
   }
 
  if (LOK == 1)
  {
    delay(LOT);
    LOK = 0;
  }
 
  lastBUTstate = reading;
}

I'm lost. I don't know what "that" is that you want to to check with regards to what input.

I meant how do i use that LOK indicator to check to allow the button press or not?

Still not quite getting what you mean. Just tried an iteration:

/*   
  Modified January 2016 
  By: Adam Alexander
  For: The Ann Arbor Hands-On Museum
*/

int DUMP = 2; // Pin connected to big dump relay
int BUTTON = 3; // Pin connected to manual dump push button.
int BUTTONlight = 4; // Pin connected to push button light.


int BUTstate; // Current reading from BUTTON pin
int lastBUTstate = LOW; // Previous reading from BUTTON pin

long lastDebounce = 0; // Last time output was changed
long Delay = 50; // Debounce Time

unsigned long DUMPTIME;
unsigned long LOT;

unsigned long prevTIME;

int a=0;
int d=0;

int LOK = 0;

void setup()
{ 
  pinMode(A1, INPUT);
  pinMode(A2, INPUT);
  
  pinMode (BUTTON, INPUT);
  pinMode (BUTTONlight, OUTPUT);
  pinMode (DUMP, OUTPUT);
  
  digitalWrite(DUMP, HIGH);
  delay(10000);
  digitalWrite(DUMP, LOW);
  digitalWrite(BUTTONlight, HIGH);
}

int readTselector(int pin)
// returns the button number pressed, or zero for none pressed 
// int pin is the analog pin number to read 
{
  int b,c = 1;
  c=analogRead(pin); // get the analog value  
  if (c>1000)
  {
    b=0; // buttons have not been pressed
  }   
  else
    if (c<1000 && c>600)
    {
      b=1; // button 1 pressed
    }     
    else
      if (c<520 && c>400)
      {
        b=2; // button 2 pressed
      }       
      else
        if (c>100 && c<400)
        {
          b=3; // button 3 pressed
        }         
        else
          if (c<100)
          {
            b=4; // button 4 pressed
          }           
  return b; 
  }


void loop()
{
  int DUMPTIME = DTselect();
  int LOT = LOselect();
  
  int reading = digitalRead(BUTTON);
  
  unsigned long currTIME = millis();
    
  if ((currTIME - prevTIME) >= DUMPTIME) // Count to 2 minutes
   {
     LOK = 1;
     digitalWrite(BUTTONlight, LOW);
     digitalWrite(DUMP, HIGH);
     delay(10000);
     digitalWrite(DUMP, LOW);
     prevTIME = currTIME;
   }
  
  if (reading != lastBUTstate)
  {
    lastDebounce = millis();
  }
  
 
  if (LOK == 1)
  {
    delay(LOT);
    digitalWrite(BUTTONlight, HIGH);
    LOK = 0;
    
  }
  if ((millis() - lastDebounce) > Delay && LOK == 0)
  {
    BUTstate = reading;
  }
  
  if (BUTstate == HIGH)
  {
    LOK = 1;
    digitalWrite(BUTTONlight, LOW);
    digitalWrite(DUMP, HIGH);
    delay(10000);
    digitalWrite(DUMP, LOW);
    prevTIME = currTIME;
  }
  lastBUTstate = reading;
}

int DTselect()
{
  a=readTselector(1); 
  if (a==0) // no buttons pressed
  {
    DUMPTIME = 210000;
  }   
  else
    if (a==1) // someone pressed a button!
    {
      DUMPTIME = 180000;
    }
    else
     if (a==2) // someone pressed a button!
     {
       DUMPTIME = 150000;
     }
     else
      if (a==3) // someone pressed a button!
      {
        DUMPTIME = 120000;
      }
      else
       if (a==4) // someone pressed a button!
       {
         DUMPTIME = 90000;
       }
  return DUMPTIME; 
 }

int LOselect()
{
  d=readTselector(2); 
  if (d==0) // no buttons pressed
  {
    delay(20000);
  }   
  else
    if (d==1) // someone pressed a button!
    {
      delay(15000);
    }
    else
     if (d==2) // someone pressed a button!
     {
       delay(10000);
     }
     else
      if (d==3) // someone pressed a button!
      {
        delay(5000);
      }
      else
       if (d==4) // someone pressed a button!
       {
         delay(0);
       }
 }

And neither of the two timers are working correctly with the combined "readTselector" or the locking variable LOK....

So after some clean up i end up with this, but it still doesn't work right. If any other value than 0 is read from A2 it seems to cycle through the process twice after each button press. So with LOT being 5000 or 5 seconds, it cycles, waits 5 secs, and instead of resetting the LED and waiting for a new button press, it cycles a second time, waits 5 secs, then resets the LED. Also it will sometimes keep getting stuck in the cycle and resetting.

#define DUMP 2          // Pin connected to big dump relay
#define BUTTON 3        // Pin connected to manual dump push button.
#define BUTTONlight 4   // Pin connected to push button light.
#define DELAY 50        // Debounce Time

int BUTstate;           // Current reading from BUTTON pin
int lastBUTstate = LOW; // Previous reading from BUTTON pin

long lastDebounce = 0;  // Last time output was changed

unsigned long DUMPTIME;
unsigned long LOT;
unsigned long prevTIME;

int LOK = 0;

int readTselector(int pin)
// returns the button number pressed, or zero for none pressed 
// int pin is the analog pin number to read 
{
    int c = analogRead(pin); // get the analog value  
    if (c > 1000){
        return 0; // buttons have not been pressed
    }   
    else if (c<1000 && c>600){
        return 1; // button 1 pressed
    }
    else if (c<520 && c>400){
        return 2; // button 2 pressed
    }       
    else if (c>100 && c<400){
        return 3; // button 3 pressed
    }         
    else if (c<100){
        return 4; // button 4 pressed
    } 
    else return 0; // just in case
    }

long DTselect()
{
    switch(readTselector(1)){
        case 0: return 210000; // no buttons pressed
            break;
        case 1: return 180000; // someone pressed a button!
            break;
        case 2: return 150000;
            break;
        case 3: return 120000;
            break;
        case 4: return 90000;
            break;
        default: return 210000; // default
            break;
    }
 }

int LOselect()
{
  switch( readTselector(2) ){
        case 0:  return 20000; // no buttons pressed
            break;
        case 1:  return 15000; // someone pressed a button!
            break;
        case 2:  return 10000;
            break;
        case 3:  return 5000;
            break;
        case 4:  return 0;
            break;
        default: return 0; // default
            break;
    }
 }

void setup()
{ 
    pinMode(A1, INPUT);
    pinMode(A2, INPUT);

    pinMode (BUTTON, INPUT);
    pinMode (BUTTONlight, OUTPUT);
    pinMode (DUMP, OUTPUT);

    digitalWrite(DUMP, HIGH);
    delay(10000);
    digitalWrite(DUMP, LOW);
    digitalWrite(BUTTONlight, HIGH);
}


void loop()
{
    DUMPTIME = DTselect();
    LOT = LOselect();

    int reading = digitalRead(BUTTON);

    unsigned long currTIME = millis();

    if ((currTIME - prevTIME) >= DUMPTIME){// Count to 2 minutes
        LOK = 1;
        digitalWrite(BUTTONlight, LOW);
        digitalWrite(DUMP, HIGH);
        delay(10000);
        digitalWrite(DUMP, LOW);
        prevTIME = currTIME;
    }

    if (reading != lastBUTstate){
        lastDebounce = millis();
    }

    if (LOK == 1){
        delay(LOT);
        digitalWrite(BUTTONlight, HIGH);
        LOK = 0;
    }

    if ((millis() - lastDebounce) > DELAY && LOK == 0){
        BUTstate = reading;
    }

    if (BUTstate == HIGH){
        digitalWrite(BUTTONlight, LOW);
        digitalWrite(DUMP, HIGH);
        delay(10000);
        digitalWrite(DUMP, LOW);
        prevTIME = currTIME;
    }
    lastBUTstate = reading;
}