-1

I'm trying to read the input from a user using keypad 4x4 and compare the input using a finite state machine as shown below.

When I come to case fourth my state machine does not go to Check case but to the default instead and then takes a key to go to CHECK immediately which makes the user press five times instead of 4.

while (1)
{
    key=get_key();
    if (key>=0 && key <=9){
        switch (password){
            case FIRST:
                if (key==7 && i==0)
                {
                    temp++; // increasing every time we enter correct number
                    password=SECOND;
                    HAL_Delay(300);
                    break;
                }
                HAL_Delay(300);
                i++; // To check if we have fed in wrong digit
                if(i==4) {
                    password=CHECK;
                }
                break;
//**********************************************************************************************************
            case SECOND:
                if (key==3 && temp==1){
                    temp++;
                    HAL_Delay(300);
                    password=THIRD;
                    break;
                }
                HAL_Delay(300);
                i++;
                if((i==3) || (i==2)) {
                    password=CHECK;
                }
                break;
//****************************************************************************************************
            case THIRD:
                if (key==9 && temp==2)
                {
                    temp++;
                    HAL_Delay(300);
                    password = FOURTH;
                    break;
                }
                HAL_Delay(300);
                i++;
                if((i==2) || (i==1)) {
                    password=CHECK;
                }
                break;
//*******************************************************************************************************
            case FOURTH:
                if (key==2 && temp==3)
                {
                    temp++;
                    password=CHECK;
                    break;
                }
                //HAL_Delay(300);
                i++;
                if(i==1) {
                    password=CHECK;
                }
                break;
//****************************************************************************************************
            case CHECK:
                if (temp==4){ // if temp has incresed to 4 that means that all the numbers entered are correct
                    HAL_GPIO_WritePin(Led_test_GPIO_Port,Led_test_Pin,1);
                    HAL_GPIO_WritePin(Led2_test_GPIO_Port,Led2_test_Pin,0);
                    password=IDLE_PASSWORD;
                }
                else if((i==4) || (i==3) || (i==2) || (i==1)) {
                    HAL_GPIO_WritePin(Led2_test_GPIO_Port,Led2_test_Pin,1);
                    HAL_GPIO_WritePin(Led_test_GPIO_Port,Led_test_Pin,0);
                    password=IDLE_PASSWORD;
                }
                break;
//******************************************************************************************************
            case IDLE_PASSWORD:
                temp=0;
                i=0;
                password = FIRST;
                break;
                default:
                password = FIRST;
                break;
        }
    }
}
nickb
  • 59,313
  • 13
  • 108
  • 143
  • youcan check if `temp == 4` before your `get_key()` or you can remove the `break` from the `FOURTH` case statment... i would have used the first solution – Omer Dagan Mar 21 '18 at 13:42
  • what do u mean by check temp == 4 ? – hello you Mar 21 '18 at 13:46
  • if i understand you correctly you need the 5th key press to actually check the entered password... in that case you can ignore this key press by `if (temp != 4) key=get_key();` it's a workaround but it should work - ofcourse you need to verify that you initialize and handle the `temp` variable correctly – Omer Dagan Mar 21 '18 at 13:58
  • If you look at your state machine, every transition from one state to another requires a call to `get_key()`. So IDLE->FIRST->SECOND->THIRD->FOURTH->CHECK requires five calls. @Dagan is suggesting that you should do the check as part of the FOURTH state so that you don't require another key press to get to CHECK. ISimilarly, you may want to move the code in the IDLE state to the beginning of the FIRST state,. – D Krueger Mar 21 '18 at 16:08
  • when i run this function now that has a case to check whether the password is correct or not it looks like it compares the first element and ignore the rest – hello you Mar 21 '18 at 23:12

1 Answers1

0
while (1)
{
    static uint8 Password[4] = {7, 3, 9, 2};
    static uint8 Guesses = 0;
    static uint8 Wrong = 0;

    /*Get the key*/
    key=get_key();

    /*If the key is not in range...*/
    if (key<0 || key >9)
    {
        /*Return early*/
        return;
    }

    /*Wait 300*/
    HAL_Delay(300);

    /*If the value at the Guess position is not equal to what they pressed...*/
    if (key != Password[Guesses])
    {
        /*Mark the input as wrong*/
        Wrong = 1
    }

    /*Increment Guesses for the next time*/
    Guesses++;

    /*After their fourth input...*/
    if (Guesses == 4)
    {
        /*Reet Guesses*/
        Guesses = 0;
        /*If they were wrong...*/
        if (Wrong == 1)
        {
            /*Reset Wrong*/
            Wrong = 0;
        }
        /*Otherwise if they were right...*/
        else
        {
            /*Do something*/
        }
    }
}

This is untested - debug a bit and it should work.

Watachiaieto
  • 417
  • 3
  • 10