Hello! I am making program that at specific condition executes do while loop and starts count down every second using millis function. In parallel it reads pressed keypad buttons. If correct password is entered, while loop ends, if not then do some other stuff. The code example works good first time but after few button press cycles program holds for a while and then show 3 or more cases at the same time. Some times even all 10 cases at same time.
I would be appreciated if someone with his experienced eye take a look at my code. I guess im doing something wrong with millis function. Also the keypad library uses this millis. Does that creates some interrupts?
//Programm which at specific condition do cycle that counts from 10 to 0 and reads pressed keypad buttons in parallel.
#include <Password.h>
#include <Keypad.h>
Password password = Password( "0000" ); //Password
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] = { 5,4,3,2 };
byte colPins[COLS] = { 8,7,6 };
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );
const int LED = 13;
const int Button = 9;
static unsigned long lastMillis = 0; // holds the last read millis()
unsigned long thisMillis;
unsigned long deltaMillis;
static int timer_1 = 0; // a repeating timer
#define TIMER_INTERVAL_1 1000 //1 second interval at which decrements loopcounter
boolean ledState = false;
boolean DoWhile = false;
boolean Button_STATE;
int loopCount = 11; //how many seconds will have to enter correct password
void setup()
{
timer_1 = TIMER_INTERVAL_1;
Serial.begin(9600);
pinMode(LED, OUTPUT);
pinMode(Button, INPUT);
keypad.addEventListener(keypadEvent);
Button_STATE = digitalRead(Button); //Reading start status of button
Serial.println("PIN LOCK");
Serial.println("Enter PASSWORD");
lastMillis = millis(); // do this last in setup
}
void loop() {
int val = digitalRead(Button);
if (val != Button_STATE) { //Button state has changed
if (val == HIGH) { //Button state is HIGH
DoWhile = true; //starts DoWhile loop
Event(); //Calls event function
}
Button_STATE = val; //Saves last button value
}
}
void Event()
{
do {
keypad.getKey();
// set millisTick at the top of each loop if and only if millis() has changed
deltaMillis = 0; // clear last result
thisMillis = millis();
// do this just once to prevent getting different answers from multiple calls to millis()
if (thisMillis != lastMillis) {
// we have ticked over
// calculate how many millis have gone past
deltaMillis = thisMillis-lastMillis;
lastMillis = thisMillis;
}
// handle repeating timer
// repeat this code for each timer you need to handle
timer_1 -= deltaMillis;
if (timer_1 <= 0) {
// reset timer since this is a repeating timer
timer_1 += TIMER_INTERVAL_1; //this prevents the delay accumulating if we miss a mS or two
digitalWrite(LED, HIGH);
ledState = true;
loopCount = loopCount - 1; //Every second decrements loop counter by 1
switch (loopCount)
{
case 10: Serial.println("10"); break;
case 9: Serial.println("9"); break;
case 8: Serial.println("8"); break;
case 7: Serial.println("7"); break;
case 6: Serial.println("6"); break;
case 5: Serial.println("5"); break;
case 4: Serial.println("4"); break;
case 3: Serial.println("3"); break;
case 2: Serial.println("2"); break;
case 1: Serial.println("1"); break;
case 0: Serial.println("0"); break;
}
if (ledState) {
if (thisMillis % 2000 == 0) { //Turns off LED every second. 1 second ON, 1 second OFF
digitalWrite(LED, LOW);
ledState = false;
}
}
}
} //do close
while (loopCount >= 0 && DoWhile);
digitalWrite(LED, LOW);
loopCount = 11;
} //Event close
void keypadEvent(KeypadEvent eKey){
switch (keypad.getState()){
case PRESSED:
switch (eKey){
case '#': checkPassword(); break;
case '*': password.reset(); break;
default: password.append(eKey);
}
}
}
//Code for checking password
void checkPassword(){
if (password.evaluate())
{
Serial.println("\nVALID PASSWORD ");
DoWhile = false; //ENDS DoWhile loop, since password is correct
password.reset();
}
else
{
Serial.println("\nINVALID PASSWORD ");
password.reset();
delay(100);
}
}