How to make program restart after going through if statement

Hello,

I am trying to write a program that turns a door lock after a password is entered in a keypad. The program works the first time I run it through; if I type in the wrong password I get the “denied” message and when I type in the correct password I get the “Accepted” message and my servo turns. However, if I type in the correct password again, nothing happens. I want this program to run continuously so that every time I type in the right password, the servo turns. I’m fairly new to Arduino so this is probably very simple to fix but I’m not really sure how to do it. My code is below; any suggestions are welcome! :slight_smile:

Thanks,
Adam

#include <Password.h>
#include <Keypad.h>
#include <Servo.h>


Servo myservo;
Password password = Password( "1738" );

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

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

void setup(){
  Serial.begin(9600);
  Serial.write(254);
  Serial.write(0x01);
  delay(200); 
  pinMode(11, OUTPUT);
  pinMode(12, OUTPUT);
  myservo.attach(13);
  myservo.write(0);
  keypad.addEventListener(keypadEvent);
  }

void loop(){
  keypad.getKey();
  }
 
  void keypadEvent(KeypadEvent eKey){
  switch (keypad.getState()){
  case PRESSED:
  
  Serial.print("Enter:");
  Serial.println(eKey);
  delay(10);
  
  
  Serial.write(254);
  
  switch (eKey){
    case '*': checkPassword(); delay(1); break;
    
    case '#': password.reset(); delay(1); break;
    
     default: password.append(eKey); delay(1);
}
}
}
void checkPassword(){
  if (run == true){
    if (password.evaluate()){
          
        Serial.println("Accepted");
        Serial.write(254);delay(10);
        myservo.write(360);
        digitalWrite(10, HIGH);
        delay(2500);
        myservo.detach();
        digitalWrite(10, LOW);
        digitalWrite(2, HIGH);
          
    }else{
        Serial.println("Denied");
        Serial.write(254);delay(10);
        myservo.write(0);
        digitalWrite(11, HIGH);
        delay(2500);
        digitalWrite(11, LOW);
      
  }
  }
}

if (run == true)

runis not defined anywhere in your posted parts.

Seems all the interesting work is done in password and keypad libraries... So the problems might be there, too. (Or the way you use them, of course)

Oh, sorry about that - I was messing around earlier trying to get it to work and I left that on accident. The code should be:

#include <Password.h>
#include <Keypad.h>
#include <Servo.h>


Servo myservo;
Password password = Password( "1738" );

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

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

void setup(){
  Serial.begin(9600);
  Serial.write(254);
  Serial.write(0x01);
  delay(200); 
  pinMode(11, OUTPUT);
  pinMode(12, OUTPUT);
  myservo.attach(13);
  myservo.write(0);
  keypad.addEventListener(keypadEvent);
  }

void loop(){
  keypad.getKey();
  }
  void keypadEvent(KeypadEvent eKey){
  switch (keypad.getState()){
  case PRESSED:
  
  Serial.print("Enter:");
  Serial.println(eKey);
  delay(10);
  
  
  Serial.write(254);
  
  switch (eKey){
    case '*': checkPassword(); delay(1); break;
    
    case '#': password.reset(); delay(1); break;
    
     default: password.append(eKey); delay(1);
}
}
}
void checkPassword(){
    if (password.evaluate()){
          
        Serial.println("Accepted");
        Serial.write(254);delay(10);
        myservo.write(360);
        digitalWrite(10, HIGH);
        delay(2500);
        myservo.detach();
        digitalWrite(10, LOW);
        digitalWrite(2, HIGH);
          
    }else{
        Serial.println("Denied");
        Serial.write(254);delay(10);
        myservo.write(0);
        digitalWrite(11, HIGH);
        delay(2500);
        digitalWrite(11, LOW);
      
  }
  }

I very well could be using the password library incorrectly, but I got several chunks of this code from someone else and I’m not 100% sure how some of it works.

  • Do the Serial.print test outputs continue properly?
  • When you see "Enter: * " it should be followed either by "Accepted" od "Denied" ?

If "nothing happens" you must look more carefully. ( Is the power led still on ? ;) ) Serial.print() is your friend.

Why does all your code happen in keypadEvent handler. Are there any restrictions what one can do there?

The Serial.print outputs continue properly. i.e. I can get the servo to turn, then I can keep punching in numbers and get "Accepted" or "Denied" but the servo does nothing.

I don't know what you meant by "all your code" but the code in the keypadEvent is

  void keypadEvent(KeypadEvent eKey){
  switch (keypad.getState()){
  case PRESSED:
  
  Serial.print("Enter:");
  Serial.println(eKey);
  delay(10);
  
  
  Serial.write(254);
  
  switch (eKey){
    case '*': checkPassword(); delay(1); break;
    
    case '#': password.reset(); delay(1); break;
    
     default: password.append(eKey); delay(1);
}
}
}

adambowker98:
I don’t know what you meant by “all your code”

He means exactly what it says. Post the complete code for this project so that if one of us were to try to help troubleshoot it we’ve got the entire thing we could compile and test.

The complete code was posted already, but here it is again

#include <Password.h>
#include <Keypad.h>
#include <Servo.h>


Servo my servo;
Password password = Password( "1738" );

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

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

void setup(){
  Serial.begin(9600);
  Serial.write(254);
  Serial.write(0x01);
  delay(200); 
  pinMode(11, OUTPUT);
  pinMode(12, OUTPUT);
  myservo.attach(13);
  myservo.write(0);
  keypad.addEventListener(keypadEvent);
  }

void loop(){
  keypad.getKey();
  }
  void keypadEvent(KeypadEvent eKey){
  switch (keypad.getState()){
  case PRESSED:
  
  Serial.print("Enter:");
  Serial.println(eKey);
  delay(10);
  
  
  Serial.write(254);
  
  switch (eKey){
    case '*': checkPassword(); delay(1); break;
    
    case '#': password.reset(); delay(1); break;
    
     default: password.append(eKey); delay(1);
}
}
}
void checkPassword(){
    if (password.evaluate()){
          
        Serial.println("Accepted");
        Serial.write(254);delay(10);
        myservo.write(360);
        digitalWrite(10, HIGH);
        password.reset();
        delay(2500);
        digitalWrite(10, LOW);
          
    }else{
        Serial.println("Denied");
        Serial.write(254);delay(10);
        myservo.write(0);
        digitalWrite(11, HIGH);
        password.reset();
        delay(2500);
        digitalWrite(11, LOW);
      
  }
  }

That code does not compile. I stopped looking after I found this

Servo my servo;

The way your code is written the servo only moves if the password is accepted or if it is denied.

If the servo has moved because the password was accepted then it will not have any reason to move if you enter the correct password a second time.

Is that the problem you are experiencing?

I don't see any code to close the lock apart from entering an incorrect password.

...R