Stop Code Execution with 4x4 Keypad

Hello,
I am using a 4x4 keypad to control a 16 channel relay(only using 14 channels), and have different keys on the keypad doing different sorts of turning on and off on the relay. One of my keys(the '#') will run through a for loop turning on the individual relay and then off after a set delay. Code posted here:

else if (key == '#'){
      for(int i = 0; i < 14; i++){
        digitalWrite(relayPin[i], LOW);  
        delay(wait); 
        digitalWrite(relayPin[i], HIGH); 
        delay(wait);
      }
  }

Now here comes my question, is there any way to program a key on the keypad to stop this loop in the middle of execution? For example, if I went through the first 8 channels turning them on then off, then I want to kill the program by pressing the '' key so no more channels will activate after that 8th one. Not sure if its possible but I have tried some things and it has not worked due to the fact it gets stuck in that loop and will never read the '' key until that loop has been broke. An idea I had was to read two keys but I still would then somehow have to read the key during the loop. Please let me know if you have any questions about my question :smile:

Maybe you are thinking about something like this?

void loop() {
  static bool halt = false;
  // Maybe still do something here.
  if (halt) {
    return;
  }

  // ...
  if (key == '"') {
    halt = true;
    return;
  }
}

Or if you really do not want to do anything anymore, then perhaps something like this?

void loop() {
  // ...

  if (key == '"') {
    while (true);
  }
}

I tried something like this earlier but the issue I run into with this is it will not read the keypad key I press while that loop is executing. It just ignores it and carries out until the for loop condition has been met. I did just throw that in and I will see if that works!

Can you share your entire sketch and indicate (with a comment inside of the code for example) exactly where you want to halt the program?

#include <Keypad.h>

const int wait = 1000;
const byte ROWS = 4; //four rows
const byte COLS = 4; //four columns
char keys[ROWS][COLS] = {
  {'1','2','3','A'},
  {'4','5','6','B'},
  {'7','8','9','C'},
  {'*','0','#','D'}
};
byte rowPins[ROWS] = {46, 47, 48, 49}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {50, 51, 52, 53}; //connect to the column pinouts of the keypad
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
const int relayPin[16] = {22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37};
int pushed[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
int relayStatus[] = {HIGH, HIGH, HIGH, HIGH, HIGH, HIGH, HIGH, HIGH, HIGH, HIGH, HIGH, HIGH, HIGH, HIGH, HIGH, HIGH};

void setup() {
  for(int i=0; i<14; i++){
    pinMode(relayPin[i], OUTPUT);
    digitalWrite(relayPin[i], HIGH);
  }
}
void loop(){
  static bool halt = false;
  char key = keypad.getKey();
  if(halt){
    return;
  }
  if (key == '1'){
    digitalWrite(relayPin[0], LOW);
    delay(wait);
    digitalWrite(relayPin[0], HIGH);
  }
  if (key == '2'){
    digitalWrite(relayPin[1], LOW);
    delay(wait);
    digitalWrite(relayPin[1], HIGH);
  }
  if (key == '3'){
    digitalWrite(relayPin[2], LOW);
    delay(wait);
    digitalWrite(relayPin[2], HIGH);
  }
  else if (key == 'A'){
    digitalWrite(relayPin[3], LOW);
    delay(wait);
    digitalWrite(relayPin[3], HIGH);
  }
  if (key == '4'){
    digitalWrite(relayPin[4], LOW);
    delay(wait);
    digitalWrite(relayPin[4], HIGH);
  }
  if (key == '5'){
    digitalWrite(relayPin[5], LOW);
    delay(wait);
    digitalWrite(relayPin[5], HIGH);
  }
  if (key == '6'){
    digitalWrite(relayPin[6], LOW);
    delay(wait);
    digitalWrite(relayPin[6], HIGH);
  }
  if (key == 'B'){
    digitalWrite(relayPin[7], LOW);
    delay(wait);
    digitalWrite(relayPin[7], HIGH);
  }
  if (key == '7'){
    digitalWrite(relayPin[8], LOW);
    delay(wait);
    digitalWrite(relayPin[8], HIGH);
  }
  if (key == '8'){
    digitalWrite(relayPin[9], LOW);
    delay(wait);
    digitalWrite(relayPin[9], HIGH);
  }
  if (key == '9'){
    digitalWrite(relayPin[10], LOW);
    delay(wait);
    digitalWrite(relayPin[10], HIGH);
  }
  if (key == 'C'){
    digitalWrite(relayPin[11], LOW);
    delay(wait);
    digitalWrite(relayPin[11], HIGH);
  }
  if (key == '*'){
    digitalWrite(relayPin[12], LOW);
    delay(wait);
    digitalWrite(relayPin[12], HIGH);
  }
  if (key == '0'){
    digitalWrite(relayPin[13], LOW);
    delay(wait);
    digitalWrite(relayPin[13], HIGH);
  }
  if (key == '#'){
      for(int i = 0; i < 14; i++){
        digitalWrite(relayPin[i], LOW);  
        delay(wait); 
        digitalWrite(relayPin[i], HIGH); 
        delay(wait);
      }
  }
  if (key == 'D'){      // When 'D' is pressed I would like the program to stop.
    halt = true;
    return;
  }
}

void controlRelay(int number){
  if(pushed[number] == 1){
      digitalWrite(relayPin[number], LOW);// Turn ON relay
     }else{
      digitalWrite(relayPin[number], HIGH); // turn OFF
     }
}

Ah, I see.

You probably want to read the keypress inside of this for-loop too then.

For example:

  if (key == '#') {
      for (int i = 0; i < 14; i++) {
        if (keypad.getKey() == 'D') {
          while (true);  // Or the other mechanism suggested above.
        }
        digitalWrite(relayPin[i], LOW);  
        delay(wait); 
        digitalWrite(relayPin[i], HIGH); 
        delay(wait);
      }
  }
1 Like

Just check for the key inside the for statement and if you find it has been pressed use continue; to abort the loop.

To catch key presses that happen during the waiting time, you'll have to replace the delay() function with sth. like this:

bool delayWithKeyCheck(unsigned long d; char k) { // returns true if key 'k' was pressed before delay 'd' has passed
  unsigned long then = millis();
  bool delayHasPassed = false;
  while ((readKeyboardKey() != k) && !delayHasPassed) {
    delayHasPassed = (millis() - then) > d;
  }
  return !delayHasPassed;
}

edit: I was afk, didn't see the other replies. Should fit anyway, just adapt the key-reading code to your code.

1 Like

This makes a lot of sense. Very good thinking....Should work no problem! Thank you both for the help!

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.