I am trying to make a program that accepts four digit password using a 3*4 keypad.
The program should start with flashing LED1 and when password 1 is entered it switches this LED and blinks LED2. If password 2 is entered it switches to LED3 and so on.
Here is the code:
#include <Keypad.h>
#include <TimedBlink.h>
#define Password_Length 5
TimedBlink led1(14);
TimedBlink led2(15);
TimedBlink led3(16);
TimedBlink led4(17);
const unsigned long PERIOD1 = 1000;
char buffers[4][4] = {{'1', '2', '3', '4'}, {'6', '5', '4', '3'}, {'9', '8', '7', '6'}, {'1', '2', '5', '6'}}; // this is how to initialise a 2d array
unsigned long previousMillis[5]; //[x] = number of leds
char Data[Password_Length]; // 6 is the number of chars it can hold + the null char = 7
byte data_count = 0;
bool Pass_is_good;
char customKey;
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] = {2, 3, 4, 5}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {6, 7, 8}; //connect to the column pinouts of the keypad
int ledservos[4] = {14, 15, 16, 17};
Keypad customKeypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS); //initialize an instance of class NewKeypad
void setup() {
pinMode(14, OUTPUT);
pinMode(15, OUTPUT);
pinMode(16, OUTPUT);
pinMode(17, OUTPUT);
led1.blink(150, 50); // On for 150ms, off for 50ms
led2.blink(150, 50);
led3.blink(150, 50); // On for 150ms, off for 50ms
led4.blink(150, 50);
Serial.begin(9600);
Serial.print("Enter Password");
Serial.println();
}
void loop() {
led1.blink();
led2.blink();
led3.blink();
led4.blink();
customKey = customKeypad.getKey();
if (customKey) {
// makes sure a key is actually pressed, equal to (customKey != NO_KEY)
Data[data_count] = customKey; // store char into data array
data_count++; // increment data array by 1 to store new char, also keep track of the number of chars entered
}
if (data_count == Password_Length - 1) {
// if the array index is equal to the number of expected chars, compare data to master
Serial.print("Password is ");
for (byte i = 0; i < Password_Length; i++)
Serial.print(Data[i]);
for (x = 0; x < 4; x++) { //this loop for number of passwords in the array
for (y = 0; y < 4; y ++) { //this loop for number of characters in each of the password array
if (strcmp(Data[y], buffers[x][y]) != 0) {
break;
}
}
if (y == 4) {
break;
}
}
if (x < 4) {
Serial.print(" Found at index ");
Serial.println(x);
switch (x) {
case 0:
led1.blinkOff();
break;
case 1:
led2.blinkOff();
break;
case 2:
led3.blinkOff();
break;
case 3:
led4.blinkOff();
break;
}
}
clearData();
}
}
void clearData() {
Serial.println();
while (data_count != 0) {
// This can be used for any array size,
Data[data_count--] = 0; //clear array for new data
}
}
void BlinkLed (int led, int interval, int arry) {
//(long) can be omitted if you dont plan to blink led for very long time I think
if (((long)millis() - previousMillis[arry]) >= interval) {
previousMillis[arry] = millis(); //stores the millis value in the selected array
digitalWrite(led, !digitalRead(led)); //changes led state
}
}
Now I can make the program, but all LEDs start blinking and switch off after the password is entered and I got stuck at this point.
Here is a link to the TimedBlink Library.
I have tried the millis() function to be used to blink LEDs in the next code:
#include <Keypad.h>
#include <Wire.h>
#define buzzer 13
#define greenled 20
#define redled 21
#define Password_Length 5
unsigned long previousMillisLED14 = 0;
unsigned long previousMillisLED15 = 0;
unsigned long previousMillisLED16 = 0;
unsigned long previousMillisLED17 = 0;
// different intervals for each LED
int intervalLED14 = 500;
int intervalLED15 = 600;
int intervalLED16 = 700;
int intervalLED17 = 800;
// each LED gets a state varaible
boolean LED14state = false; // the LED will turn ON in the first iteration of loop()
boolean LED15state = false; // need to seed the light to be OFF
boolean LED16state = false; // need to seed the light to be OFF
boolean LED17state = false; // need to seed the light to be OFF
const unsigned long PERIOD1 = 1000;
char buffers[4][4] = {{'1', '2', '3', '4'}, {'6', '5', '4', '3'}, {'9', '8', '7', '6'}, {'1', '2', '5', '6'}}; // this is how to initialise a 2d array
unsigned long previousMillis[5]; //[x] = number of leds
byte i, x, y;
char Data[Password_Length]; // 6 is the number of chars it can hold + the null char = 7
byte data_count = 0;
bool Pass_is_good;
char customKey;
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] = {2, 3, 4, 5}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {6, 7, 8}; //connect to the column pinouts of the keypad
int ledservos[4] = {14, 15, 16, 17};
Keypad customKeypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS); //initialize an instance of class NewKeypad
void setup() {
pinMode(14, OUTPUT);
pinMode(15, OUTPUT);
pinMode(16, OUTPUT);
pinMode(17, OUTPUT);
Serial.begin(9600);
pinMode(buzzer, OUTPUT);
pinMode(redled, OUTPUT);
pinMode(greenled, OUTPUT);
Serial.print("Enter Password");
Serial.println();
}
void loop() {
unsigned long currentMillis = millis();
if ((unsigned long)(currentMillis - previousMillisLED14) >= intervalLED14) {
LED14state = !LED14state;
digitalWrite(14, LED14state);
// save current time to pin 12's previousMillis
previousMillisLED14 = currentMillis;
}
customKey = customKeypad.getKey();
if (customKey) {
// makes sure a key is actually pressed, equal to (customKey != NO_KEY)
Data[data_count] = customKey; // store char into data array
data_count++; // increment data array by 1 to store new char, also keep track of the number of chars entered
}
if (data_count == Password_Length - 1) {
// if the array index is equal to the number of expected chars, compare data to master
Serial.print("Password is ");
for (byte i = 0; i < Password_Length; i++)
Serial.print(Data[i]);
for (x = 0; x < 4; x++) {
//this loop for number of passwords in the array
for (y = 0; y < 4; y ++) {
//this loop for number of characters in each of the password array
if (strcmp(Data[y], buffers[x][y]) != 0) {
break;
}
}
if (y == 4) {
break;
}
}
if (x < 4) {
Serial.print(" Found at index ");
Serial.println(x);
switch (x) {
case 0:
digitalWrite(14, LOW);
digitalWrite(16, LOW);
digitalWrite(17, LOW);
if ((unsigned long)(currentMillis - previousMillisLED15) >= intervalLED15) {
LED15state = !LED15state;
digitalWrite(15, LED15state);
// save current time to pin 12's previousMillis
previousMillisLED15 = currentMillis;
}
break;
case 1:
digitalWrite(15, LOW);
digitalWrite(14, LOW);
digitalWrite(17, LOW);
if ((unsigned long)(currentMillis - previousMillisLED16) >= intervalLED16) {
LED16state = !LED16state;
digitalWrite(16, LED15state);
// save current time to pin 12's previousMillis
previousMillisLED16 = currentMillis;
}
break;
case 2:
digitalWrite(15, LOW);
digitalWrite(14, LOW);
digitalWrite(16, LOW);
if ((unsigned long)(currentMillis - previousMillisLED17) >= intervalLED17) {
LED17state = !LED17state;
digitalWrite(17, LED17state);
// save current time to pin 12's previousMillis
previousMillisLED17 = currentMillis;
}
break;
case 3:
digitalWrite(15, LOW);
digitalWrite(14, LOW);
digitalWrite(16, LOW);
digitalWrite(17, LOW);
break;
}
}
clearData();
}
}
void clearData() {
Serial.println();
while (data_count != 0) {
// This can be used for any array size,
Data[data_count--] = 0; //clear array for new data
}
}
But it blinks the first LED only, then each of the following LEDs according to the condition got permanent on. I have tried the solution that Adafruit suggested, to use a class in code but unfortunately I got the same result as the previous code.
Here is the code:
#include <Keypad.h>
#include <Wire.h>
class Flasher {
// Class Member Variables
// These are initialized at startup
int ledPin; // the number of the LED pin
long OnTime; // milliseconds of on-time
long OffTime; // milliseconds of off-time
// These maintain the current state
int ledState; // ledState used to set the LED
unsigned long previousMillis; // will store last time LED was updated
// Constructor - creates a Flasher
// and initializes the member variables and state
public:
Flasher(int pin, long on, long off) {
ledPin = pin;
pinMode(ledPin, OUTPUT);
OnTime = on;
OffTime = off;
ledState = LOW;
previousMillis = 0;
}
void Update() {
// check to see if it's time to change the state of the LED
unsigned long currentMillis = millis();
if ((ledState == HIGH) && (currentMillis - previousMillis >= OnTime)) {
ledState = LOW; // Turn it off
previousMillis = currentMillis; // Remember the time
digitalWrite(ledPin, ledState); // Update the actual LED
} else if ((ledState == LOW) && (currentMillis - previousMillis >= OffTime)) {
ledState = HIGH; // turn it on
previousMillis = currentMillis; // Remember the time
digitalWrite(ledPin, ledState); // Update the actual LED
}
}
};
Flasher led1(14, 100, 400);
Flasher led2(15, 350, 350);
Flasher led3(16, 100, 400);
Flasher led4(17, 350, 350);
#define buzzer 13
#define greenled 20
#define redled 21
#define Password_Length 5
char buffers[4][4] = {{'1', '2', '3', '4'}, {'6', '5', '4', '3'}, {'9', '8', '7', '6'}, {'1', '2', '5', '6'}}; // this is how to initialise a 2d array
unsigned long previousMillis[5]; //[x] = number of leds
byte i, x, y;
char Data[Password_Length]; // 6 is the number of chars it can hold + the null char = 7
byte data_count = 0;
bool Pass_is_good;
char customKey;
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] = {2, 3, 4, 5}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {6, 7, 8}; //connect to the column pinouts of the keypad
int ledservos[4] = {14, 15, 16, 17};
Keypad customKeypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS); //initialize an instance of class NewKeypad
void setup() {
Serial.begin(9600);
pinMode(buzzer, OUTPUT);
pinMode(redled, OUTPUT);
pinMode(greenled, OUTPUT);
Serial.print("Enter Password");
Serial.println();
}
void loop() {
led1.Update();
customKey = customKeypad.getKey();
if (customKey) {
// makes sure a key is actually pressed, equal to (customKey != NO_KEY)
Data[data_count] = customKey; // store char into data array
data_count++; // increment data array by 1 to store new char, also keep track of the number of chars entered
}
if (data_count == Password_Length - 1) {
// if the array index is equal to the number of expected chars, compare data to master
Serial.print("Password is ");
for (byte i = 0; i < Password_Length; i++)
Serial.print(Data[i]);
for (x = 0; x < 4; x++) {
//this loop for number of passwords in the array
for (y = 0; y < 4; y ++) {
//this loop for number of characters in each of the password array
if (strcmp(Data[y], buffers[x][y]) != 0) {
break;
}
}
if (y == 4) {
break;
}
}
if (x < 4) {
Serial.print(" Found at index ");
Serial.println(x);
switch (x) {
case 0:
led2.Update();
digitalWrite(14, LOW);
digitalWrite(16, LOW);
digitalWrite(17, LOW);
break;
case 1:
led3.Update();
digitalWrite(15, LOW);
digitalWrite(14, LOW);
digitalWrite(17, LOW);
break;
case 2:
led4.Update();
digitalWrite(15, LOW);
digitalWrite(14, LOW);
digitalWrite(16, LOW);
break;
case 3:
digitalWrite(15, LOW);
digitalWrite(14, LOW);
digitalWrite(16, LOW);
digitalWrite(17, LOW);
break;
}
}
clearData();
}
}
void clearData() {
Serial.println();
while (data_count != 0) {
// This can be used for any array size,
Data[data_count--] = 0; //clear array for new data
}
}
Any idea why is this happening?