286 lines
6.7 KiB
C++
286 lines
6.7 KiB
C++
#include <LiquidCrystal_I2C.h>
|
|
LiquidCrystal_I2C lcd(0x20,16,2);
|
|
|
|
#include <Keypad.h>
|
|
const byte numRows = 4;
|
|
const byte numCols = 4;
|
|
char keymap[numRows][numCols] = {
|
|
{'1', '2', '3', 'A'},
|
|
{'4', '5', '6', 'B'},
|
|
{'7', '8', '9', 'C'},
|
|
{'*', '0', '#', 'D'}
|
|
};
|
|
// keypad pins
|
|
byte rowPins[numRows] = {13, 12, 11, 10};
|
|
byte colPins[numCols] = {9, 8, 7, 6};
|
|
Keypad keypad = Keypad(makeKeymap(keymap), rowPins, colPins, numRows, numCols);
|
|
|
|
#include <Servo.h>
|
|
Servo servo;
|
|
|
|
// led pins
|
|
const int greenLed = 1;
|
|
const int ledArray[6] = {2, 3, 4, 5, 6, 7};
|
|
const int redLed = 8;
|
|
|
|
// pins
|
|
const int registerInput = 1;
|
|
const int outputRegister = 2;
|
|
const int shiftRegister = 3;
|
|
const int piezo = 4;
|
|
const int servoPin = 5;
|
|
|
|
// variables
|
|
bool locked = true;
|
|
bool showPassword = false;
|
|
bool alarmed = false;
|
|
int attempts = 5;
|
|
String password = "";
|
|
String masterkey = "";
|
|
char key;
|
|
|
|
void setup() {
|
|
lcd.init();
|
|
lcd.clear();
|
|
lcd.backlight();
|
|
pinMode(registerInput, OUTPUT);
|
|
pinMode(outputRegister, OUTPUT);
|
|
pinMode(shiftRegister, OUTPUT);
|
|
pinMode(piezo, OUTPUT);
|
|
servo.write(0);
|
|
servo.attach(servoPin);
|
|
}
|
|
|
|
void loop() {
|
|
if (alarmed) {
|
|
lcd.clear();
|
|
lcd.print("Enter masterkey:");
|
|
alarmedLoop();
|
|
} else if (locked) {
|
|
ledMode(greenLed, LOW);
|
|
ledMode(redLed, HIGH);
|
|
lcd.clear();
|
|
lcd.print("Enter password:");
|
|
lockedLoop();
|
|
} else {
|
|
ledMode(redLed, LOW);
|
|
ledMode(greenLed, HIGH);
|
|
lcd.clear();
|
|
lcd.print("Press A to lock");
|
|
unlockedLoop();
|
|
}
|
|
}
|
|
|
|
void lockedLoop() {
|
|
while (locked) {
|
|
key = keypad.getKey();
|
|
if (key != NO_KEY) {
|
|
if (key >= '0' && key <= '9') {
|
|
if (password.length() <= 16) {
|
|
buzz();
|
|
password += key;
|
|
} else {
|
|
error();
|
|
}
|
|
}
|
|
if (key == '*') {
|
|
buzz();
|
|
password = "";
|
|
}
|
|
if (key == '#') {
|
|
buzz();
|
|
password = password.substring(0, password.length() - 1);
|
|
}
|
|
if (key == 'A') {
|
|
checkPassword();
|
|
}
|
|
if (key == 'D') {
|
|
buzz();
|
|
showPassword = !showPassword;
|
|
}
|
|
clearLine(1, 0);
|
|
if (showPassword) {
|
|
lcd.print(password);
|
|
} else {
|
|
for (int i = 0; i < password.length(); i++) {
|
|
lcd.print('*');
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void unlockedLoop() {
|
|
Serial.println("unlockedLoop");
|
|
while (!locked) {
|
|
key = keypad.getKey();
|
|
if (key != NO_KEY && key == 'A') {
|
|
lock();
|
|
locked = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
void alarmedLoop() {
|
|
while (alarmed) {
|
|
alarm(500, 200);
|
|
key = keypad.getKey();
|
|
if (key != NO_KEY) {
|
|
if (key >= '0' && key <= '9') {
|
|
if (masterkey.length() < 16) {
|
|
buzz();
|
|
masterkey += key;
|
|
} else {
|
|
error();
|
|
}
|
|
}
|
|
if (key == '*') {
|
|
buzz();
|
|
masterkey = "";
|
|
}
|
|
if (key == '#') {
|
|
buzz();
|
|
masterkey = masterkey.substring(0, masterkey.length() - 1);
|
|
}
|
|
if (key == 'A') {
|
|
checkMasterkey();
|
|
}
|
|
if (key == 'D') {
|
|
buzz();
|
|
showPassword = !showPassword;
|
|
}
|
|
clearLine(1, 0);
|
|
if (showPassword) {
|
|
lcd.print(masterkey);
|
|
} else {
|
|
for (int i = 0; i < masterkey.length(); i++) {
|
|
lcd.print('*');
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void checkPassword() {
|
|
if (password == "1258") {
|
|
locked = false;
|
|
password = "";
|
|
attempts = 5;
|
|
unlock();
|
|
} else {
|
|
attempts--;
|
|
if (attempts != 0) {
|
|
error();
|
|
lcd.clear();
|
|
lcd.print("Wrong password!");
|
|
delay(1000);
|
|
lcd.clear();
|
|
lcd.print("Remaining");
|
|
lcd.setCursor(0, 1);
|
|
lcd.print("attempts: ");
|
|
lcd.print(attempts);
|
|
delay(1000);
|
|
lcd.clear();
|
|
lcd.print("Enter password:");
|
|
} else {
|
|
alarmed = true;
|
|
locked = false;
|
|
password = "";
|
|
}
|
|
}
|
|
}
|
|
|
|
void checkMasterkey() {
|
|
if (masterkey == "7852") {
|
|
alarmed = false;
|
|
locked = true;
|
|
masterkey = "";
|
|
attempts = 5;
|
|
noTone(piezo);
|
|
} else {
|
|
lcd.clear();
|
|
lcd.print("Wrong masterkey!");
|
|
delay(1000);
|
|
lcd.clear();
|
|
lcd.print("Enter masterkey:");
|
|
}
|
|
}
|
|
|
|
void unlock() {
|
|
tone(piezo, 1000, 1000);
|
|
digitalWrite(redLed, LOW);
|
|
digitalWrite(greenLed, HIGH);
|
|
lcd.clear();
|
|
lcd.setCursor(4, 0);
|
|
lcd.print("Unlocked");
|
|
servo.write(90);
|
|
delay(1000);
|
|
}
|
|
|
|
void lock() {
|
|
tone(piezo, 1000, 1000);
|
|
digitalWrite(greenLed, LOW);
|
|
digitalWrite(redLed, HIGH);
|
|
lcd.clear();
|
|
lcd.setCursor(5, 0);
|
|
lcd.print("Locked");
|
|
servo.write(0);
|
|
delay(1000);
|
|
}
|
|
|
|
void alarm(int hertz, int timing) { //CHATGPT for the millis and led algorithm
|
|
static unsigned long previousMillis = 0;
|
|
static bool state = false;
|
|
static int ledIndex = 0;
|
|
static bool directionForward = true;
|
|
unsigned long currentMillis = millis();
|
|
if (currentMillis - previousMillis >= timing) {
|
|
previousMillis = currentMillis;
|
|
if (state) {
|
|
tone(piezo, hertz + 100);
|
|
} else {
|
|
tone(piezo, hertz - 100);
|
|
}
|
|
state = !state;
|
|
for (int i = 0; i < 6; i++) {
|
|
ledMode(ledArray[i], LOW);
|
|
}
|
|
ledMode(ledArray[ledIndex], HIGH);
|
|
if (directionForward) {
|
|
ledIndex++;
|
|
if (ledIndex >= 6) {
|
|
directionForward = false;
|
|
}
|
|
} else {
|
|
ledIndex--;
|
|
if (ledIndex < 0) {
|
|
directionForward = true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void ledMode(int ledNumber, bool state) { //CHATGPT for shift register
|
|
digitalWrite(outputRegister, LOW);
|
|
byte data = 0;
|
|
if (ledNumber >= 1 && ledNumber <= 8) {
|
|
data = state ? (1 << (ledNumber - 1)) : 0;
|
|
}
|
|
shiftOut(registerInput, shiftRegister, MSBFIRST, data);
|
|
digitalWrite(outputRegister, HIGH);
|
|
}
|
|
|
|
void clearLine(int l, int c) {
|
|
lcd.setCursor(0, l);
|
|
lcd.print(" ");
|
|
lcd.setCursor(c, l);
|
|
}
|
|
|
|
void buzz() {
|
|
tone(piezo, 1000, 100);
|
|
}
|
|
|
|
void error() {
|
|
tone(piezo, 500, 500);
|
|
}
|