Keypad - Exit loop with key press

Hi all,

how can I exit a while loop with the press of a button on the keypad?
Here is a sample of what I want to do. This snippet is mainly the EventKeypad example from the keypad library.

#include <Keypad.h>

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] = {2,3,4,5}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {6,7,8,9}; //connect to the column pinouts of the keypad

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

boolean blink = false;

void setup(){
  Serial.begin(9600);
  pinMode(ledPin, OUTPUT);      // sets the digital pin as output
  digitalWrite(ledPin, HIGH);   // sets the LED on
  keypad.addEventListener(keypadEvent); //add an event listener for this keypad
}
  
void loop(){
  char key = keypad.getKey();
  
  if (key != NO_KEY) {
    Serial.println(key);
  }
  
}

//take care of some special events
void keypadEvent(KeypadEvent key){
  switch (keypad.getState()){
    case PRESSED:
      switch (key){
        case '#': some_function(); break; // enter the function with "#"
      }
    break;

  }
}

// function
void some_function() {

byte stay_in_loop = 1;

	while (stay_in_loop) {
		// set some parameters and exit the loop when all is set.
		// Question: How to exit the loop with button press?
		// Buttons are not processed during this loop...
		if (key_star) {
			stay_in_loop = 0;
		}
	}

}

So what I basically want to do, is to enter a loop with the press of a button. In this loop I have to set some parameters. The program must stay in this loop until all the parameters are set. Then I want to leave the loop and continue the program execution.
The problem is, that I cannot access the keypad in the loop.

Any ideas how I can solve this problem?

Thanks,
Harry

Use a state machine:

Note: code below is untested and guaranteed.

#include <Keypad.h>

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] = {2,3,4,5}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {6,7,8,9}; //connect to the column pinouts of the keypad

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

boolean blink = false;

enum state {WAITING, LOOPING} current_state = WAITING;

void setup(){
  Serial.begin(9600);
  pinMode(ledPin, OUTPUT);      // sets the digital pin as output
  digitalWrite(ledPin, HIGH);   // sets the LED on
  keypad.addEventListener(keypadEvent); //add an event listener for this keypad
}
  
void loop(){
  char key = keypad.getKey();
  
  if (key != NO_KEY) {
    Serial.println(key);
  }
  
  switch(current_state) {
  case WAITING:
  // outside of loop, do nothing
    break;
  case LOOPING:
  // set some parameters.  this set of code will be processed until no longer
  // LOOPING, as set by the keyPadEvent.
    break;
  }    
}

//take care of some special events
void keypadEvent(KeypadEvent key){
  switch (keypad.getState()){
    case PRESSED:
      switch (key){
        case '#': current_state = LOOPING; break; // enter the function with "#"
        case EXITKEY: current_state = WAITING; break; // exit the function with EXITKEY
      }
    break;

  }
}

Thank you very much! It works!

No problem.

Hello to all participants of forum. I have tried the code posted here but it seems to only enter the loop but it doesn't seem to react on push keypad to exit. I have changed the line
"case EXITKEY: current_state = WAITING; break; // exit the function with EXITKEY" to look like
"case '*': current_state = WAITING; break; // exit the function with EXITKEY"
It starts with s waiting parameters on pushing in keypad # button it starts to loop, but it doesn't react to quiting the loop and going to waiting state. I have also tried to change the starting parameter
"enum state {WAITING, LOOPING} current_state = WAITING;" to LOOPING and it still doesnt leave the loop.
I am using a standard keypad 3x4 and a ARDUINO MEGA 2650.
Full code:
#include <Keypad.h>
int relay1 = 22;
int relay2 = 23;
int relay3 = 24;
int relay4 = 25;
int relay5 = 26;
int relay6 = 27;
int relay7 = 28;
int relay8 = 29;

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] = {8, 7, 6 ,5};
byte colPins[COLS] = {4 ,3 ,2};

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

enum state {WAITING, LOOPING} current_state = LOOPING;

void setup()

{
Serial.begin(9600);
pinMode(relay1, OUTPUT);
pinMode(relay1, HIGH);
pinMode(relay2, OUTPUT);
pinMode(relay2, HIGH);
pinMode(relay3, OUTPUT);
pinMode(relay3, HIGH);
pinMode(relay4, OUTPUT);
pinMode(relay4, HIGH);

keypad.addEventListener(keypadEvent);
}

void loop()

{
char key = keypad.getKey();

if (key != NO_KEY)
{
Serial.println(key);
}

switch(current_state)
{
case WAITING:
digitalWrite(relay1, LOW);
digitalWrite(relay2, LOW);
digitalWrite(relay3, HIGH);
break;
case LOOPING:
digitalWrite(relay1, LOW);
digitalWrite(relay2, HIGH);
digitalWrite(relay3, LOW);
delay(15000);
digitalWrite(relay2, LOW);
digitalWrite(relay1, HIGH);
delay(15000);
break;
}

}

//take care of some special events
void keypadEvent(KeypadEvent key)
{
switch (keypad.getState())
{
case PRESSED:
switch (key)
{
case '#': current_state = LOOPING; break; // enter the function with "#"
case '*': current_state = WAITING; break; // exit the function with EXITKEY
}
break;

}
}