#include <Keypad.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,20,4);
//declare buttons and led pins
const int buttonPin1 = 18;
const int buttonPin2 = 19;
const int ledPins[] = {2,3,4,5,6,7};
int pattern = 0; // variable to store LED pattern
int frequency = 200; // variable to store LED blinking frequency (in milliseconds)
int pot;
int num;
unsigned long holdingTime;
long previousHoldingTime;
unsigned long firstButtonPressTime;
byte buttonState;
byte previousButtonState = HIGH;
bool AdcFlag = false;
//define constants for the number of rows and columns on the keypad
const byte rows=4;
const byte columns=4;
char password[] = "1234";
String input;
static int pos=0; //initialize position counter. static is a storage class specifier, which means that it modifies the storage duration of the variable
char key;
//declare a 2-dimensional keymap array keys[rows][columns] that contains characters to be printed when a specific keypad button is pressed.
char keys[rows][columns]={
{'1','2','3','A'},
{'4','5','6','B'},
{'7','8','9','C'},
{'*','0','#','D'}
};
//specify the arduino connections to the keypad using two arrays. One for rows and one for columns
byte rowPins[rows]={25,27,29,31};
byte columnPins[columns]={33,35,37,39};
//create a keypad object that accepts 5 arguments
Keypad keypad = Keypad( makeKeymap(keys), rowPins, columnPins, rows, columns); //makeKeymap(keys) initializes internal keymap to be equal to the user defined keymap
void setup() {
lcd.begin(20,4);
lcd.init();
lcd.backlight();
Serial.begin(9600);
lcd.setCursor(0,0);//Set cursor to character 0 on line 0
lcd.print("Enter Password ");
lcd.setCursor(5,3); //Set cursor to character 0 on line 3
lcd.print("# - Delete");
for (int i = 0; i < 7; i++) {
pinMode(ledPins[i], OUTPUT);
}
pinMode(buttonPin1, INPUT_PULLUP);
pinMode(buttonPin2, INPUT_PULLUP);
Serial.begin(9600);
attachInterrupt(digitalPinToInterrupt(buttonPin1), checkButton1, CHANGE);
attachInterrupt(digitalPinToInterrupt(buttonPin2), checkButton2, CHANGE);
}
void checkKeypad(){
char key = keypad.getKey();
lcd.setCursor(0,1); //cursor is on character 0, line 1
lcd.print(key);
if (key == '#') {
if (input.length() > 0) {
input.remove(input.length() - 1); // Remove the last digit from the input string
lcd.setCursor(0,1);
lcd.print(" "); // Clear the display on the LCD
lcd.setCursor(0,1);
lcd.print(input); // Display the updated input string on the LCD
}
}
else{ // If any other key is pressed
static char input[6]; //initialize input string
// input += key; // Add the pressed digit to the input string
if (key != NO_KEY && pos < 5) { //if a key was pressed and input is not full
input[pos++] = key;
lcd.setCursor(pos, 1);
lcd.print("*");
}
else if (pos == 4) { //if input is complete
if (strcmp(input, password) == 0) { //if password is correct. The string compare strcmp() function is a standard C library function that is used to compare two strings.
lcd.clear();
lcd.print("Successful Login");
delay(500);
}
else { //if password is incorrect
lcd.clear(); //clear LCD
lcd.print("Wrong password!"); //display error message on LCD
delay(2000); //wait 2 seconds
lcd.clear(); //clear LCD
lcd.print("Enter password:"); //display prompt on LCD
pos = 0; //reset position counter
}
}
}
}
void checkButton1(){
buttonState = digitalRead(buttonPin1);
if (buttonState == LOW && previousButtonState == HIGH)
{
firstButtonPressTime = millis();
}
holdingTime = (millis() - firstButtonPressTime);
if (holdingTime > 50)
{
if (buttonState == HIGH && previousButtonState == LOW)
{
Serial.println("Button 1 pressed pattern changer");
pattern = (pattern + 1) % 5; // change pattern
frequency = 200; //reset frequency on pattern change
}
}
previousButtonState = buttonState;
}
void checkButton2(){
buttonState = digitalRead(buttonPin2);
if (buttonState == LOW && previousButtonState == HIGH && (millis() - firstButtonPressTime) > 200)
{
firstButtonPressTime = millis();
}
holdingTime = (millis() - firstButtonPressTime);
if (holdingTime > 100)
{
if (buttonState == HIGH && previousButtonState == LOW)
{
if (holdingTime <= 700)
{
Serial.println("short button press");
frequency += 100;
}
if (holdingTime > 700)
{
if(AdcFlag == true){
Serial.println("long button press");
AdcFlag = false; //long press to get out of ADC mode back to the patterns
}else{
Serial.println("long button press");
AdcFlag = true; //long press makes flag true so that void loop can enter adc isr
}
}
}
}
previousButtonState = buttonState;
previousHoldingTime = holdingTime;
}
void loop() {
checkKeypad(); // Call the checkKeypad() function for all other keys
if (AdcFlag == true){
longPress();
}else if (AdcFlag == false){
switch (pattern) {
case 0: // pattern 1
Serial.println("Patt 1");
for (int i = 0; i < 7; i++) {
digitalWrite(ledPins[i], HIGH);
delay(frequency);
digitalWrite(ledPins[i], LOW);
delay(frequency);
}
break;
case 1: // pattern 2
Serial.println("Patt 2");
for (int i = 6; i >= 0; i--) {
digitalWrite(ledPins[i], HIGH);
delay(frequency);
digitalWrite(ledPins[i], LOW);
delay(frequency);
}
break;
case 2: // pattern 3
Serial.println("Patt 3");
for (int i = 0; i < 7; i++) {
digitalWrite(ledPins[i], HIGH);
digitalWrite(ledPins[i+1], HIGH);
delay(frequency);
digitalWrite(ledPins[i], LOW);
digitalWrite(ledPins[i+1], LOW);
delay(frequency);
}
break;
case 3: // pattern 4
Serial.println("Patt 4");
for (int i = 6; i >= 0; i--) {
digitalWrite(ledPins[i], HIGH);
digitalWrite(ledPins[i-2], HIGH);
delay(frequency);
digitalWrite(ledPins[i], LOW);
digitalWrite(ledPins[i-2], LOW);
delay(frequency);
}
break;
case 4: // pattern 5
Serial.println("Patt 5");
pot = analogRead(A0);
num = map(pot, 0, 1023, 0, 255);
for(int i=2; i<10; i++){
analogWrite(i, num);
}
break;
}
}
}
void longPress(){
pot = analogRead(A0);
num = map(pot, 0, 1023, 0, 7);
switch(num){
case 0: //all OFF
for (int i = 0; i < 6; i++) {
digitalWrite(ledPins[i], LOW);
}
break;
case 1: //led 1
digitalWrite(ledPins[0], HIGH);
off();
break;
case 2: //led <2
for (int i = 0; i < 2; i++) {
digitalWrite(ledPins[i], HIGH);
}
off();
break;
case 3: //led <3
for (int i = 0; i < 3; i++) {
digitalWrite(ledPins[i], HIGH);
}
off();
break;
case 4: //led <4
for (int i = 0; i < 4; i++) {
digitalWrite(ledPins[i], HIGH);
}
off();
break;
case 5: //led <5
for (int i = 0; i < 5; i++) {
digitalWrite(ledPins[i], HIGH);
}
off();
break;
case 6: //led <6
for (int i = 0; i < 6; i++) {
digitalWrite(ledPins[i], HIGH);
}
off();
break;
case 7: //all ON
for (int i = 0; i < 7; i++) {
digitalWrite(ledPins[i], HIGH);
}
off();
break;
}
}
void off(){//TURN OFF LEDs BETWEEN CASES
digitalWrite(ledPins[0], LOW);
digitalWrite(ledPins[1], LOW);
digitalWrite(ledPins[2], LOW);
digitalWrite(ledPins[3], LOW);
digitalWrite(ledPins[4], LOW);
digitalWrite(ledPins[5], LOW);
digitalWrite(ledPins[6], LOW);
}