keep getting key from keypad equal to NO_KEY value

Simon says game! choose a level then generate some random numbers then compare with user input from keypad. i can’t catch user input from keypad for.the first catch from user input by the keypad work fine. in the function play(), the second user input, key, from keypad keep gives NO_KEY value

#include <Keypad.h>
#define SIMPLE 8
#define MEDIUM 16
#define HARD 32
#define ADVANCED 99
int parseInputKey(char);  //coverting funtc from char keypad into number
void music(int);
void generateRandomArray(int);
void play();
const byte ROWS = 4;
const byte COLS = 4;
char keys[ROWS][COLS] = {
   {'1','2','3','A'},
   {'4','5','6','B'},
   {'7','8','9','C'},
   {'*','0','#','D'}
};
byte rowPins[ROWS] = {9, 8, 7, 6};
byte colPins[COLS] = {5, 4, 3, 2};
Keypad aKeyPad = Keypad(makeKeymap(keys),rowPins, colPins, ROWS, COLS);
int pins[5]={0,13,12,11,19};
int freq[5]={0,659,554,440,330};
int num[ADVANCED]={0}; //computer side
int player[ADVANCED]={0};
int buzpin=10;
int freqerr=220;
int difficulty=0;
int arraysize=0;
int isdifficultyset=0;

void setup(){
   int i;
   Serial.begin(9600);
   for (i=0;i<4;i++){
       pinMode(pins[i], OUTPUT);  //LED output
   }
   randomSeed(analogRead(0));
   random(1,5);
  
}

void loop(){
  char key = aKeyPad.getKey();
  if(key != NO_KEY){
    Serial.println("key: ");
    Serial.println(key);
   
    if(isdifficultyset ==0){
      difficulty=parseInputKey(key);
      Serial.println("difficulty: ");
      Serial.println(parseInputKey(key));
     
      if(difficulty != -1){
        isdifficultyset=1;
        music(difficulty);
        generateRandomArray(difficulty);
        play();
        isdifficultyset=0;
      
      }//diff != -1
    }//end for isdifficutlyset ==0
   
     
  }//end for != NO_KEY
 

}//end loop

int parseInputKey(char userinput){ // convert char 1 from keypad turn into number
  int number=-1;
  switch(userinput){  //userinput
    case '1':
      number=1;
      break;
    case '2':
      number=2;
      break;
    case '3':
      number=3;
      break;
    case 'A':
      number=4;
      break; 
    default:
      
      break;
 
  }
return(number); 

 
}//end parse

void music(int level){  // still working on this; ignore this for now. need catching key form keypad problem to be fixed first

  for(int i=0;i< difficulty;i++){
 
   
  }

}//music end

void generateRandomArray(int level){
  int i;
  switch(level){
     case 1:
       arraysize = SIMPLE;
       Serial.println("Simple: ");
       Serial.println(SIMPLE);
       break;
     case 2:
       arraysize = MEDIUM;
       Serial.println("M: ");
       Serial.println(MEDIUM);
       break;
     case 3:
       arraysize = HARD;
       Serial.println("H: ");
       Serial.println(HARD);
       break;
     case 4:
       arraysize = ADVANCED;
       Serial.println("Ad: ");
       Serial.println(ADVANCED);
       break;
     default:
       break;
 
  }
 
  for(i=0;i<arraysize;i++){   //loop nonstop
    num[i]=random(1,5);
    Serial.println("rand: ");
    Serial.println(num[i]);
    delay(300);
  }


}// end generateRandomArray function

void play(){
  int count=1;
  int i=0;
  int j=0;
  int duration=500;
  int waittime=600;
  char key;
  int val;
  int wrong=0;
  do{
  
    delay(waittime);
    for(i=0; i< count; i++){    
      digitalWrite(pins[num[i]],HIGH );   //get correct light for number
      tone(buzpin,freq[num[i]],duration);
      delay(waittime);
      digitalWrite(pins[num[i]],LOW );  
     
    }
    i=0;
   
    do{
     
   
     while((key==aKeyPad.getKey()) && key == NO_KEY){
     
      }
     
          player[i]=parseInputKey(key); // catch user input to compare

          Serial.println("    key: "); //testing key is empty or = NO_KEY
          Serial.println(key);

         
          if (player[i]==num[i]){
            digitalWrite(pins[num[i]],HIGH ); 
            
            tone(buzpin, freq[num[i]],duration);
            delay(waittime);
            digitalWrite(pins[num[i]],LOW); 
            wrong=0;
            i++;
          }
         else {
           for(int i=0; i<4;i++){
             digitalWrite(pins[i],HIGH ); //  HIGH to all 4 lights.
           }
           tone(buzpin, freqerr, duration);
           delay(waittime);
           wrong=1;
           for(int i=0;i<4;i++){    //LOW to all 4 lights
             digitalWrite(pins[i],LOW );
          
           }
          
        
         }//end else
        
     
    }while(wrong==0 && i<count);
    count++;
 
  }while(wrong==0 && count<=arraysize);
 
  if(wrong==0 && count >= arraysize){  // play some music, plz ignore this for now. not done yet
    music(difficulty);
 
  }
 

}//end play

This code looks suspicious

     while((key==aKeyPad.getKey()) && key == NO_KEY){
     
      }

I suspect you think that the variable key stores the previous key press, but if you look at the code, you have 2 local variables called key, one in each function.

I suspect you really want key to always have the last value that was read even in different functions, in which case get rid of the local var declarations of key in the functions and declare it in global scope at top ie above setup()

rogerClark: This code looks suspicious

     while((key==aKeyPad.getKey()) && key == NO_KEY){
     
      }

I suspect you think that the variable key stores the previous key press, but if you look at the code, you have 2 local variables called key, one in each function.

I suspect you really want key to always have the last value that was read even in different functions, in which case get rid of the local var declarations of key in the functions and declare it in global scope at top ie above setup()

tried that didnt work. the purpose of the first key is to choose difficulty then convert the char keypad into a number thru parseInputKey() then store all random numbers into num*. Then the user tried to match these random numbers in num[] by using keypad then goes through parseInputKey() again for coverting char into a number.* the problem is i cant catch another user input from the keypad again. i already set key=aKeyPad.getKey() to pick up the user input but it just keep giving an empty value which is same as equal to NO_KEY. ```     while((key==aKeyPad.getKey()) && key == NO_KEY){  //just wait for user input after random num          } ```

while((key==aKeyPad.getKey())

Why are you COMPARING the value of key to the value returned by getKey? It looks to me like you want that to be an ASSIGNMENT.

PaulS: while((key==aKeyPad.getKey())

Why are you COMPARING the value of key to the value returned by getKey? It looks to me like you want that to be an ASSIGNMENT.

PaulS: while((key==aKeyPad.getKey())

Why are you COMPARING the value of key to the value returned by getKey? It looks to me like you want that to be an ASSIGNMENT.

it is used for waiting until user press the keypad again then get out of the while loop. this isn't really a problem but the problem is i cant catch any user input by the keypad and keep giving me empty value.

Despite your dismissive disregard of RogerClark's suggestion, he is absolutely on the money.

Trace through your play function. You declear a variable key without initialising it.

The next time you mention it is

while((key==aKeyPad.getKey()) && key == NO_KEY){

That's still just COMPARING the current contents of key (which you haven't even initialised) (as paulS has rightly pointed out)

When the user user finally pushes a key it will then move on to your next statement

player[ i ]=parseInputKey(key); // catch user input to compare

But key is STILL going to be holding 0 as you haven't included ANY code that assigns it a value.

Edit. Just to make this clear, the reason it breaks out of your while loop is NOT because key no longer = NO_KEY (key still holds zero). It's because the getKey() no longer returns the zero you're holding in key.

KenF: Despite your dismissive disregard of RogerClark's suggestion, he is absolutely on the money.

Trace through your play function. You declear a variable key without initialising it.

The next time you mention it is

while((key==aKeyPad.getKey()) && key == NO_KEY){

That's still just COMPARING the current contents of key (which you haven't even initialised) (as paulS has rightly pointed out)

When the user user finally pushes a key it will then move on to your next statement

player[ i ]=parseInputKey(key); // catch user input to compare

But key is STILL going to be holding 0 as you haven't included ANY code that assigns it a value.

Edit. Just to make this clear, the reason it breaks out of your while loop is NOT because key no longer = NO_KEY (key still holds zero). It's because the getKey() no longer returns the zero you're holding in key.

aww sometime i am stubborn. it was this code screw up my "key". it somehow flush out my key out. thx brother!

captainsource: aww sometime i am stubborn. it was this code screw up my "key". it somehow flush out my key out. thx brother!

You're welcome :)