Please help with Interrupt handler for keypad pin entry

I would greatly appreciate any help on this. I am working on a kegerator project, because i like to drink, build stuff, and mess with computers, its only natural.
The arduino will control the temperature of the kegerator, display the temperature on a 1.8" tft, also show pictures of the beer being dispensed, while its dispensing.
I will use relays to HOPEFULLY control electronic valves instead of actual taps. The main reason for this is because i want to be able to lock the thing so that my kids, neighbors kids, or even drunk neighbors don't wander into the garage and drink my beer.
I have made most of it work so far. but now im stuck.

PROBLEM: I have created an interrupt that powers the relay to open the valve, but first checks the "Lock" value. I am using the keypad pin code to control that value as 0 = not locked and 1 = locked.
There is another interrupt that calls for the keypad to get the key. It seems though that it does not give it any time at all for the key to be entered and returns to the main loop. Since i don't expect any critical temperature change to happen over a short amount of time it would not be and issue for it to wait for a bit to receive the key. What it CANNOT do is wait indefinitely for a code to be entered without returning to the loop, this would cause temperature issues. I have tried various wait loops, for loops, and just plain delay to give it time to receive the pin code. All have failed.

Can anyone give me even a hint as to where to move from here?

I included a VERY cleaned up version of my code so all the other mumbo jumbo is not a distraction, just enough for the concept of what im doing to show, so that its easier for you guys to see what im doing wrong.

#include <Password.h>
#include <Keypad.h>
Password password = Password( "4321" );
const byte ROWS = 4;
const byte COLS = 3;
char keys[ROWS][COLS] = {
  {'1','2','3',},
  {'4','5','6',},
  {'7','8','9',},
  {'*','0',' ',}
};
byte rowPins[ROWS] = {22, 23, 24, 25};
byte colPins[COLS] = {26, 27, 28};

Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

volatile int Locked = 1;

const int Relay5 = 42;

long debouncing_time = 15;
volatile unsigned long last_micros;

void setup(){
Serial.begin(9600);

pinMode (Relay5, OUTPUT);
digitalWrite(Relay5, HIGH);

keypad.addEventListener(keypadEvent);
keypad.setDebounceTime(250);

attachInterrupt(1, PinCode, FALLING);
attachInterrupt(2, Button1press, FALLING);
}

void loop(){
Serial.println("Pretend there is alot of other stuff going on here.");
delay(5000);
//Temperature readings, screen displaying temps images, relays controling cooling, blah blah stuff.
}

void PinCode(){
if((long)(micros() - last_micros) >= debouncing_time *1000) {
Serial.println("ENTER PIN");
keypad.getKey();
}
last_micros = micros();
attachInterrupt(1, PinCode, CHANGE);
}

void keypadEvent(KeypadEvent eKey){
switch (keypad.getState()){
case PRESSED:
switch (eKey){
case ' ': guessPassword(); break;
default:
password.append(eKey);
}
}}

void guessPassword(){
if (password.evaluate()){
Locked = 0;
Serial.println("VALID PASSWORD ");
Serial.println(Locked);
password.reset();
}
else{
Locked = 1;
Serial.println("INVALID PASSWORD ");
Serial.println(Locked);
password.reset();
}}

void Button1press() {
 if((long)(micros() - last_micros) >= debouncing_time *1000) {
  if(Locked == 0) {digitalWrite(Relay5, LOW);}
  attachInterrupt(2, Button1release, RISING);
  }
  last_micros = micros();
  }
void Button1release() {
 if((long)(micros() - last_micros) >= debouncing_time *1000) {
  digitalWrite(Relay5, HIGH);  
  attachInterrupt(2, Button1press, FALLING);
  }
  last_micros = micros();
  }

Why are you using microseconds and interupts on human activities? For human button presses millis() are fast enough and interupts are not needed. Unless you're Superman and can press and release a button that quickly... :roll_eyes:

techxjster:
I included a VERY cleaned up version of my code so all the other mumbo jumbo is not a distraction, just enough for the concept of what I'm doing to show, so that its easier for you guys to see what I'm doing wrong.

Don't really need the code, you have already explained the problem in full. You simply have no idea of the purpose of interrupts. Common "newbie" mistake.

You need to start by writing code to perform the individual parts of your task within the"loop" framework. This means you do not use the "delay()" function, nor do you ever use a "while" loop. Every action must complete (almost) immediately and proceed through the "loop". All "waits" are implemented by the time comparisons as you would seem to have understood, which is fine, but the involve polling the corresponding inputs.

Once you have the pieces working, they simply cascade within the loop, one after another.

What Paul__B said and also look up 'Finite State Machine' and the switch...case statement.

Henry, The microseconds ordeal is a debounce thing because of the way the buttons fluctuate voltage when they change, thats the way i understand it to be anyway. I tried it without this and the results were spastic. I agree it seems fast but it fixes the results, good enough for me.

Paul, I believe I understand what you are saying, get rid of the BS in my loop so that it runs as fast as possible. This would eliminate the need for the interrupts that i have in place. I have the display running which even when setup for high-speed is slow, you can see the refresh rate. This is one of the main causes for the Loop to take so long and the reason I implemented the interrupts for the buttons. So I got rid of all of that, and set the buttons as digital reads during the loop with if conditions to power relays when needed. and then. So now my loop has gets temperatures controls 4 relays based on the temperature, and 4 relays based on the buttons if it is unlocked, and also supposed to get the key from the keypad. I am getting the same results that I was getting before.

When i type the key nothing happens, if i repeatedly tap the pound sign, enter key for the pin code basically, i get an INVALID PASSWORD return.

If i take all the temperature and button stuff out the keypad works as it should. But to me is worthless if none of the functions its intended to unlock work.

What am I missing?

techxjster:
What am I missing?

Sounds complex, but I think we might need to see the real code!

Shouldn't be using microseconds.

Tech,

"Shouldn't be using microseconds" does NOT mean to pull it fron your code, it means "change Micros to Millis".

Your loop code doesn't need to be shortened, your Interrupt Service Routine does. Try letting your ISR set a flag to indicate condition and return to your main loop. Then let subs in the main code determine what the condition needs, what appropriate action to take, perform the action, and then reset the flag. That lets you take as long as you need to address the action.