Problem with switch case

You may want to add the option where the password times out after a period of time if no button has been pressed.

.

larryd, Can you have a look over my code. I've got it working the way I want it to, but only if I do things in the order they are supposed to happen. As soon as an incorrect password is entered the PW variable starts storing random numbers that don't get cleared. This is slightly baffling because at every stage in the code the PW variable is supposed to get set to zero, but that aint happening.

Can you spot anything?

#include <Keypad.h>
#include <EEPROMex.h>

const byte ROWS = 4; //four rows
const byte COLS = 3; //three columns
char keys[ROWS][COLS] =
{
  {'1', '2', '3'},
  {'4', '5', '6'},
  {'7', '8', '9'},
  {'*', '0', '#'}
};

byte rowPins[ROWS] = {A0, A1, A2, A3}; //connect to the row pinouts of the keypad

byte colPins[COLS] = {4, 3, 2}; //connect to the column pinouts of the keypad

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

const byte relayOne = 8;
const byte relayTwo  = 9;

//Target password
unsigned int masterPassWord = 1234;
unsigned int PassWord;
unsigned int newPassWord;

int address;

//Password number entered
unsigned int PW;

bool PWokay = false;
bool masterPWokay = false;

void setup()
{
  Serial.begin(9600);
  pinMode(relayOne, OUTPUT);
  pinMode(relayTwo,  OUTPUT);
  digitalWrite(relayOne, HIGH);      
  digitalWrite(relayTwo,  HIGH);    
  keypad.addEventListener(keypadEvent); //Add an event listener for this keypad
  newPassWord = EEPROM.readInt(address);
  if(newPassWord > 0){
    PassWord = newPassWord;
  }
  else{
    PassWord = masterPassWord;
  }
  Serial.println(masterPassWord);
  Serial.println(PassWord);
  Serial.println("Enter password");
}

void loop()
{
  char key = keypad.getKey();
  if (key)
  {
    Serial.print(key);

    //check for a valid password
    if ((key == '*' || key == '#') && (PWokay == false || masterPWokay == false))
    {
      if (PW == PassWord || PW == masterPassWord)
      {
        if(PW == masterPassWord){
          masterPWokay = true;
          Serial.println("Master password is ok");
        }
        else{
          PWokay = true;
          Serial.println("");
          Serial.println("Password is okay.");
        } 
      }

      else
      {
        masterPassWord = false;
        PWokay = false;
        PW = 0;
        Serial.println("");
        Serial.println("Password is bad.");
        Serial.println("Enter password");
      }
    }

    //assemble the password number
    if (PWokay == false || masterPWokay == false && key >= '0' && key <= '9')
    {
       PW = PW * 10 + (key - '0');
    }
    Serial.print("  ");
    Serial.println(PW);
  }
} 

void keypadEvent(KeypadEvent key)
{
  switch (keypad.getState())
  {
    case RELEASED:
      {
        switch (key)
        {
          //only if there is a valid password
          case '*':
            if (PWokay == true)
            {
              {
                //relayOne OFF
                digitalWrite(relayOne, HIGH);
                masterPWokay = false;
                PWokay = false;
                PW = 0;
              }
            }
            if (masterPWokay == true)
            {
              {
                masterPWokay = false;
                PWokay = false;
                PW = 0;
              }
            }
            break;

          //only if there is a valid password
          case '#':
            if (PWokay == true)
            {
              {
                //relayTwo OFF
                digitalWrite(relayTwo, HIGH);
                masterPWokay = false;
                PWokay = false;
                PW = 0;
              }
            }
            break;
        } //END of switch (key)
      }
      break; //END of RELEASED

    //*********************
    case HOLD:
      {
        switch (key)
        {
          //***************
          //only if there is a valid password
          case '*':
            if (PWokay == true)
            {
              {
                //relayTwo ON
                digitalWrite(relayOne, LOW);
              }
            }
            
            if (masterPWokay == true)
            {
              {
                Serial.print("Enter new password: ");
                unsigned long passWorddelay = millis();
                while(millis() - passWorddelay < 6000)
                {
                  char key = keypad.getKey();
                  if (key)
                  {
                    Serial.print(key);

                    if (key == '*')
                    {
                      EEPROM.writeInt(address,PW);
                      newPassWord = EEPROM.readInt(address);
                      PassWord = newPassWord;
                      Serial.print("New password: ");
                      Serial.println(newPassWord);
                      Serial.print("New password confirmed as: ");
                      Serial.println(PassWord);
                    }

                    //assemble the password number
                    if (masterPWokay == false && key >= '0' && key <= '9')
                    {
                      PW = PW * 10 + (key - '0');
                    }
                  }
                }
                masterPWokay = false;
                PWokay = false;
                PW = 0;
              }
            }
            break;

          //***************
          //only if there is a valid password
          case '#':
            if (PWokay == true)
            {
              {
                //relayTwo ON
                digitalWrite(relayTwo, LOW);
              }
            }
            break;
        } //END of switch (key)
      }
      break; //END of HOLD

  } //END of switch (keypad.getState())

} //END of    k e y p a d E v e n  t ( )

If anyone else can spot what the problem is please let me know?

Cheers.

Ok finally got the sketch working the way I want. It may not be the best solution, but it works. I do a software reset if the master password is entered, then add new password within setup while loop. Doing this seems to have cleared up the random bugs I was getting.

Here is the code if anyone is interested:

#include <Keypad.h>
#include <EEPROMex.h>

const byte ROWS = 4; //four rows
const byte COLS = 3; //three columns
char keys[ROWS][COLS] =
{
  {'1', '2', '3'},
  {'4', '5', '6'},
  {'7', '8', '9'},
  {'*', '0', '#'}
};

byte rowPins[ROWS] = {A0, A1, A2, A3}; //connect to the row pinouts of the keypad

byte colPins[COLS] = {4, 3, 2}; //connect to the column pinouts of the keypad

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

const byte relayOne = 8;
const byte relayTwo  = 9;

//Target password
unsigned int masterPassWord = 1234;
unsigned int PassWord;
unsigned int newPassWord;

//Password number entered
unsigned int PW;

bool PWokay = false;
bool masterPWokay = false;

int address;

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

  unsigned long passWorddelay = millis();
  while(millis() - passWorddelay < 10000)
  {
    char key = keypad.getKey();
    if (key)
    {
      Serial.print(key);

      if (key == '*')
      {
        EEPROM.writeInt(address,PW);
        newPassWord = EEPROM.readInt(address);
        PassWord = newPassWord;
        Serial.print("New password: ");
        Serial.println(newPassWord);
        Serial.print("New password confirmed as: ");
        Serial.println(PassWord);
      }

      //assemble the password number
      if (masterPWokay == false && key >= '0' && key <= '9')
      {
        PW = PW * 10 + (key - '0');
      }
    }
  }
  PWokay = false;
  masterPWokay = false;
  PW = 0;
  
  pinMode(relayOne, OUTPUT);
  pinMode(relayTwo,  OUTPUT);
  digitalWrite(relayOne, HIGH);      
  digitalWrite(relayTwo,  HIGH);    
  keypad.addEventListener(keypadEvent); //Add an event listener for this keypad
  newPassWord = EEPROM.readInt(address);
  if(newPassWord > 0){
    PassWord = newPassWord;
  }
  Serial.println("Enter password");
}

void loop()
{
  char key = keypad.getKey();
  if (key)
  {
    Serial.print(key);

    //check for a valid password
    if ((key == '*' || key == '#') && PWokay == false)
    {
      if (PW == PassWord || PW == masterPassWord)
      {
        if(PW == masterPassWord){
          masterPWokay = true;
          Serial.println("Master password ok");
        }
        else{
          PWokay = true;
          Serial.println("");
          Serial.println("Password is okay.");
        }
      }

      else
      {
        PWokay = false;
        masterPWokay = false;
        PW = 0;
        Serial.println("");
        Serial.println("Password is bad.");
        Serial.println("Enter password");
      }
    }

    //assemble the password number
    if (PWokay == false && key >= '0' && key <= '9')
    {
       PW = PW * 10 + (key - '0');
    }
  }
} 

void keypadEvent(KeypadEvent key)
{
  switch (keypad.getState())
  {
    case RELEASED:
      {
        switch (key)
        {
          //only if there is a valid password
          case '*':
            if (PWokay == true)
            {
              {
                //relayOne OFF
                digitalWrite(relayOne, HIGH);
                masterPWokay = false;
                PWokay = false;
                PW = 0;
              }
            }
            if (masterPWokay == true)
            {
              {
                software_Reset();
              }
            }
            break;

          //only if there is a valid password
          case '#':
            if (PWokay == true)
            {
              {
                //relayTwo OFF
                digitalWrite(relayTwo, HIGH);
                masterPWokay = false;
                PWokay = false;
                PW = 0;
              }
            }
            if (masterPWokay == true)
            {
              {
                masterPWokay = false;
                PWokay = false;
                PW = 0;
              }
            }
            break;
        } //END of switch (key)
      }
      break; //END of RELEASED

    //*********************
    case HOLD:
      {
        switch (key)
        {
          //***************
          //only if there is a valid password
          case '*':
            if (PWokay == true)
            {
              {
                //relayTwo ON
                digitalWrite(relayOne, LOW);
              }
            }
            break;

          //***************
          //only if there is a valid password
          case '#':
            if (PWokay == true)
            {
              {
                //relayTwo ON
                digitalWrite(relayTwo, LOW);
              }
            }
            break;

        } //END of switch (key)
      }
      break; //END of HOLD

  } //END of switch (keypad.getState())

} //END of    k e y p a d E v e n  t ( )

void software_Reset() // Restarts program from beginning but does not reset the peripherals and registers
{
  asm volatile ("  jmp 0");  
}

Cheers.