#include <Keypad.h>
#include <LiquidCrystal.h>
#define TONE_USE_INT
#define TONE_PITCH 440
#include <TonePitch.h>
#include "song.h"
const byte ROWS = 4;
const byte COLS = 4;
char keys[ROWS][COLS] = {
{'1','2','3','A'},
{'4','5','6','B'},
{'7','8','9','C'},
{'*','0','#','D'}
};
byte rowPins[ROWS] = {6, 7, 8, 9};
byte colPins[COLS] = {2, 3, 4, 5};
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
int rs = A0, e = A1, d4 = A2, d5 = A3, d6 = A4, d7 = A5;
LiquidCrystal lcd(rs, e, d4, d5, d6, d7);
int buzzer = 13;
int numLED = 3;
int LED[] = {10, 11, 12};
const String defaultPassword = "1234";
const int maxAttempts = 3;
String username;
String password;
int attempts = 0;
unsigned long warningTimer = 0;
const unsigned long warningDuration = 5000;
void setup() {
Serial.begin(9600);
lcd.begin(16, 2);
for (int i = 0; i<3; i++){
pinMode(LED[i], OUTPUT);
}
WelcomeScreen();
}
void loop() {
EnterPin();
}
void center(String message, int lcdRow, bool animate){
int cursorPos;
cursorPos = 7 - (message.length() - 1) / 2;
lcd.setCursor(cursorPos, lcdRow);
if (animate == true) {
animation(message);
} else {
lcd.print(message);
}
}
void animation(String message){
for (byte i = 0; i < message.length(); i++) {
lcd.print(message[i]);
delay(200/5);
}
}
void WelcomeScreen(){
center("Enter Username:", 0, true);
while (Serial.available() == 0) {}
username = Serial.readString();
lcd.clear();
center("Welcome!", 0, false); center(username, 1, true);
delay(2000);
}
void EnterPin(){
lcd.clear();
center("Enter PIN:", 0, true);
password = "";
lcd.setCursor(6, 1);
while (password.length() < 4) {
char key = keypad.getKey();
if (key) {
playNoteForKey(key);
lightUpLEDs(password.length() + 1);
lcd.setCursor(password.length(), 1);
lcd.print('*');
password += key;
}
}
checkPassword();
}
void lightUpLEDs(int num) {
for (int i = 0; i < num; i++) {
digitalWrite(LED[i], HIGH);
}
for (int i = num; i < numLED; i++) {
digitalWrite(LED[i], LOW);
}
}
void leftToRight(){
low();
for(int i = 0; i < numLED; i++){
digitalWrite(LED[i], HIGH);
delay(250);
}
low();
}
void rightToLeft(){
low();
for(int i = 0; i < numLED; i++){
digitalWrite(LED[2-i], HIGH);
delay(250);
}
low();
}
void low() {
for (int i = 0; i < numLED; i++) {
digitalWrite(LED[i], LOW);
}
}
void checkPassword(){
if (password == defaultPassword) {
lcd.clear();
center("ACCESS GRANTED", 0, true);
leftToRight();
song();
delay(1000);
low();
lcd.clear();
attempts = 0;
warningTimer = 0;
} else {
attempts++;
lcd.clear();
center("ACCESS DENIED", 0, true);
String current = String(attempts) + " Attempts";
center(current, 1, false);
rightToLeft();
incorrect();
delay(1000);
lcd.clear();
if (attempts >= maxAttempts) {
lcd.setCursor(0, 0);
center("WARNING!!!", 0, true);
siren();
attempts = 0;
warningTimer = 0;
}
low();
}
}
void playNoteForKey(char key) {
int note;
if (key == '#') {
note = NOTE_C7;
} else {
note = NOTE_C6;
}
tone(buzzer, note);
delay(50);
noTone(buzzer);
}
void siren() {
unsigned long startTime = millis();
while (millis() - startTime < warningDuration) {
for (int hz = 440; hz < 1000; hz += 25) {
tone(buzzer, hz, 50);
delay(15);
digitalWrite(LED[0], LOW);
digitalWrite(LED[2], HIGH);
}
// Whoop down
for (int hz = 1000; hz > 440; hz -= 25) {
tone(buzzer, hz, 50);
delay(15);
digitalWrite(LED[0], HIGH);
digitalWrite(LED[2], LOW);
}
}
noTone(buzzer);
}
void song(){
low();
int tempo1 = 170;
int wholenote1 = (60000 * 4) / tempo1;
int divider = 0, noteDuration = 0;
for (int thisNote = 0; thisNote < sizeof(notes) / sizeof(notes[0]); thisNote = thisNote + 2) {
divider = notes[thisNote + 1];
if (divider > 0) {
noteDuration = (wholenote1) / divider;
}
tone(buzzer, notes[thisNote], noteDuration * 0.9);
digitalWrite(LED[thisNote/2 % 3], HIGH);
delay(noteDuration);
digitalWrite(LED[thisNote/2 % 3], LOW);
noTone(buzzer);
}
}
void incorrect() {
// Whoop up
for (int hz = 440; hz < 1000; hz += 25) {
tone(buzzer, hz, 50);
delay(5);
}
loopF(0, 3, 20);
loopR(3, 0, 20);
// Whoop down
for (int hz = 1000; hz > 440; hz -= 25) {
tone(buzzer, hz, 50);
delay(5);
}
}
void loopF(int spin, int epin, int time) {
for (int i = spin; i <= epin; i++) {
digitalWrite(LED[i], HIGH);
delay(time);
low();
if (spin == epin) {
spin = 0;
epin = 3;
}
}
}
void loopR(int epin, int spin, int time) {
for (int i = epin; i >= spin; i--) {
digitalWrite(LED[i], HIGH);
delay(time);
low();
if (spin == epin) {
spin = 0;
epin = 3;
}
}
}