Versione aggiornata della cassaforte con aggiunta del modulo ds1307 (per la gestione del tempo) e l'aggiunta del relay.
Codice:
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <Keypad.h>
#include <RTClib.h>
#include <Adafruit_NeoPixel.h>
#include <EEPROM.h>
#define PIN_RING 11
#define NUM_PIXELS 16
int state = 0;
int menuState = 0;
int limit = 5;
int limitSave = limit;
LiquidCrystal_I2C lcd(0x27, 16, 2);
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] = {2, 3, 4, 5};
byte colPins[COLS] = {6, 7, 8, 9};
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
String inputPIN = "";
#define DEFAULT_PIN "1234"
String storedPIN = DEFAULT_PIN;
int menuIndex = 0;
int menuText = 1;
String newPIN = "";
bool confirmPIN = false;
const int EEPROM_ADDRESS = 0;
unsigned long previousMillisLimit = 0;
const long intervalLimit = 1000;
bool US = true;
bool MP = true;
bool MI = true;
bool LTDP = true;
bool CLTD = true;
bool fLockedt = true;
bool openedState = true;
bool ST = true;
bool move = false;
RTC_DS1307 rtc;
Adafruit_NeoPixel ring = Adafruit_NeoPixel(NUM_PIXELS, PIN_RING, NEO_GRB + NEO_KHZ800);
#define PIR 13
#define BUZZER A3
#define RELAY 12
#define RED A0
#define GREEN A1
#define BLUE A2
void setup() {
lcd.init();
lcd.backlight();
lcd.setCursor(0, 0);
Serial.begin(9600);
if (!rtc.begin()) {
lcd.setCursor(0, 1);
lcd.print("RTC non trovato");
while (1);
}
if (!rtc.isrunning()) {
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
}
ring.begin();
ring.show();
pinMode(PIR, INPUT);
pinMode(BUZZER, OUTPUT);
pinMode(RED, OUTPUT);
pinMode(GREEN, OUTPUT);
pinMode(BLUE, OUTPUT);
digitalWrite(RED, HIGH);
intro();
homeLock();
state = 1;
}
void loop() {
switch (state) {
case 1:
lockState();
break;
case 2:
unlockState();
break;
case 3:
menuPIN();
break;
case 4:
menuOptions();
break;
case 5:
openState();
break;
case 6:
secureState();
break;
}
}
void lockState() {
char key = keypad.getKey();
if (key) {
if (key == '#') {
if (storedPIN == inputPIN) {
lcd.setCursor(5, 1);
tone(BUZZER, 1000, 500);
state = 2;
US = true;
unlockState();
} else {
lcd.setCursor(5, 1);
lcd.print("PIN errato");
delay(1000);
inputPIN = "";
lcd.setCursor(4, 1);
lcd.print(" ");
lcd.setCursor(5, 1);
}
inputPIN = "";
} else if (key == '*') {
inputPIN = "";
lcd.setCursor(4, 1);
lcd.print(" ");
} else {
inputPIN += key;
lcd.setCursor(5 + inputPIN.length() - 1, 1);
lcd.print('*');
tone(BUZZER, 500, 100);
Serial.println(inputPIN);
}
}
}
void unlockState() {
digitalWrite(RED, LOW);
digitalWrite(GREEN, HIGH);
if (US == true) {
lcd.clear();
US = false;
}
lcd.noBlink();
lcd.noCursor();
showTime();
showDate(3);
char key = keypad.getKey();
if (key) {
if (key == 'D') {
state = 3;
} else if (key == '*') {
openState();
state = 5;
}
}
}
void intro() {
Serial.print("1");
lcd.setCursor(3, 0);
lcd.print("CodeLock");
lcd.setCursor(0, 1);
for (int i = 0; i < 16; i++) {
lcd.print("*");
delay(80);
}
}
void homeLock() {
lcd.clear();
lcd.setCursor(2, 0);
lcd.print("--SECURED--");
lcd.setCursor(0, 1);
lcd.print("PIN: ");
lcd.cursor();
lcd.blink();
state = 1;
}
void showDate(int timeCursor) {
DateTime now = rtc.now();
lcd.setCursor(timeCursor, 1);
lcd.print(now.year());
lcd.print('/');
if (now.month() < 10) lcd.print('0');
lcd.print(now.month());
lcd.print('/');
if (now.day() < 10) lcd.print('0');
lcd.print(now.day());
}
void showTime() {
DateTime now = rtc.now();
lcd.setCursor(4, 0);
if (now.hour() < 10) lcd.print('0');
lcd.print(now.hour());
lcd.print(':');
if (now.minute() < 10) lcd.print('0');
lcd.print(now.minute());
lcd.print(':');
if (now.second() < 10) lcd.print('0');
lcd.print(now.second());
}
void menuPIN() {
if (MP == true) {
digitalWrite(RED, HIGH);
digitalWrite(GREEN, LOW);
MP = false;
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Menu LOCKED!");
lcd.setCursor(0, 1);
lcd.print("PIN: ");
}
char key = keypad.getKey();
if (key) {
if (key == '#') {
if (storedPIN == inputPIN) {
lcd.setCursor(5, 1);
tone(BUZZER, 1000, 500);
state = 4;
MP = true;
menuOptions();
} else {
lcd.setCursor(5, 1);
lcd.print("PIN errato");
delay(1000);
inputPIN = "";
lcd.setCursor(4, 1);
lcd.print(" ");
lcd.setCursor(5, 1);
}
inputPIN = "";
} else if (key == '*') {
inputPIN = "";
lcd.setCursor(4, 1);
lcd.print(" ");
} else {
inputPIN += key;
lcd.setCursor(5 + inputPIN.length() - 1, 1);
lcd.print('*');
tone(BUZZER, 500, 100);
Serial.println(inputPIN);
}
}
}
void menuOptions() {
char key = keypad.getKey();
digitalWrite(RED, LOW);
digitalWrite(GREEN, HIGH);
if (key) {
if (key == '#') {
menuIndex = menuText;
}
}
switch (menuIndex) {
case 1:
changeLimit();
break;
case 2:
changePIN();
break;
case 3:
changeDate();
break;
case 4:
changeTime();
break;
}
if (menuText == 1) {
if (MI == true) {
MI = false;
lcd.clear();
lcd.setCursor(0, 1);
lcd.print("Cambia limite");
}
if (key) {
if (key == 'A') {
menuText = 4;
MI = true;
} else if (key == 'B') {
menuText = 2;
MI = true;
} else if (key == '#') {
menuIndex = 1;
CLTD = true;
}
}
} else if (menuText == 2) {
if (MI == true) {
MI = false;
lcd.clear();
lcd.setCursor(0, 1);
lcd.print("Cambia PIN");
}
if (key) {
if (key == 'A') {
menuText = 1;
MI = true;
} else if (key == 'B') {
menuText = 3;
MI = true;
} else if (key == '#') {
CLTD = true;
menuIndex = 2;
}
}
} else if (menuText == 3) {
if (MI == true) {
MI = false;
lcd.clear();
lcd.setCursor(0, 1);
lcd.print("Cambia data");
}
if (key) {
if (key == 'A') {
menuText = 2;
MI = true;
} else if (key == 'B') {
menuText = 4;
MI = true;
} else if (key == '#') {
CLTD = true;
menuIndex = 3;
}
}
} else if (menuText == 4) {
if (MI == true) {
MI = false;
lcd.clear();
lcd.setCursor(0, 1);
lcd.print("Cambia ora");
}
if (key) {
if (key == 'A') {
menuText = 3;
MI = true;
} else if (key == 'B') {
menuText = 1;
MI = true;
} else if (key == '#') {
CLTD = true;
menuIndex = 4;
}
}
}
}
void changeLimit() {
if (CLTD == true) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Vecchio Limite:");
lcd.setCursor(5, 1);
lcd.print(limit);
delay(1000);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Nuovo limite:");
CLTD = false;
}
char key = keypad.getKey();
if (key) {
if (key == '*') {
limitSave = limit;
lcd.clear();
lcd.setCursor(0, 1);
lcd.print("Salvato");
delay(500);
EEPROM.put(EEPROM_ADDRESS, limitSave);
lcd.clear();
menuIndex = 0;
} else if (key == '#') {
limit = 0;
lcd.clear();
lcd.setCursor(0, 1);
lcd.print("Annullato");
delay(500);
lcd.clear();
menuIndex = 0;
} else {
limit = limit * 10 + (key - '0');
lcd.setCursor(5, 1);
lcd.print(limit);
}
}
}
void changePIN() {
if (CLTD == true) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Nuovo PIN:");
CLTD = false;
}
char key = keypad.getKey();
if (key) {
if (key == '*') {
if (confirmPIN) {
storedPIN = newPIN;
newPIN = "";
confirmPIN = false;
lcd.clear();
lcd.setCursor(0, 1);
lcd.print("PIN Salvato");
delay(500);
lcd.clear();
menuIndex = 0;
} else {
newPIN = "";
confirmPIN = true;
lcd.setCursor(0, 1);
lcd.print("Conferma PIN:");
}
} else if (key == '#') {
newPIN = "";
confirmPIN = false;
lcd.clear();
lcd.setCursor(0, 1);
lcd.print("Annullato");
delay(500);
lcd.clear();
menuIndex = 0;
} else {
newPIN += key;
lcd.setCursor(newPIN.length() - 1, 1);
lcd.print('*');
}
}
}
void changeDate() {
DateTime now = rtc.now();
if (CLTD == true) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Vecchia Data:");
showDate(5);
delay(2000);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Nuova Data:");
CLTD = false;
}
static int datePart = 0;
static int year = now.year();
static int month = now.month();
static int day = now.day();
char key = keypad.getKey();
if (key) {
if (key == '*') {
if (datePart == 2) {
rtc.adjust(DateTime(year, month, day, now.hour(), now.minute(), now.second()));
lcd.setCursor(0, 1);
lcd.print("Data Salvata");
delay(500);
lcd.clear();
menuIndex = 0;
datePart = 0;
} else {
datePart++;
}
} else if (key == '#') {
lcd.clear();
lcd.setCursor(0, 1);
lcd.print("Annullato");
delay(500);
lcd.clear();
menuIndex = 0;
datePart = 0;
} else {
int num = key - '0';
if (datePart == 0) {
year = year * 10 + num;
lcd.setCursor(5 + (year > 1000 ? 4 : year > 100 ? 3 : year > 10 ? 2 : 1), 1);
lcd.print(year);
} else if (datePart == 1) {
month = month * 10 + num;
lcd.setCursor(7, 1);
lcd.print('/');
lcd.print(month);
} else if (datePart == 2) {
day = day * 10 + num;
lcd.setCursor(10, 1);
lcd.print('/');
lcd.print(day);
}
}
}
}
void changeTime() {
DateTime now = rtc.now();
if (CLTD == true) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Vecchia Ora:");
showTime();
delay(2000);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Nuova Ora:");
CLTD = false;
}
static int timePart = 0;
static int hour = now.hour();
static int minute = now.minute();
static int second = now.second();
char key = keypad.getKey();
if (key) {
if (key == '*') {
if (timePart == 2) {
rtc.adjust(DateTime(now.year(), now.month(), now.day(), hour, minute, second));
lcd.setCursor(0, 1);
lcd.print("Ora Salvata");
delay(500);
lcd.clear();
menuIndex = 0;
timePart = 0;
} else {
timePart++;
}
} else if (key == '#') {
lcd.clear();
lcd.setCursor(0, 1);
lcd.print("Annullato");
delay(500);
lcd.clear();
menuIndex = 0;
timePart = 0;
} else {
int num = key - '0';
if (timePart == 0) {
hour = hour * 10 + num;
lcd.setCursor(5, 1);
lcd.print(hour);
} else if (timePart == 1) {
minute = minute * 10 + num;
lcd.setCursor(7, 1);
lcd.print(':');
lcd.print(minute);
} else if (timePart == 2) {
second = second * 10 + num;
lcd.setCursor(10, 1);
lcd.print(':');
lcd.print(second);
}
}
}
}
void openState() {
if (openedState == true) {
openedState = false;
digitalWrite(RELAY, HIGH);
lcd.clear();
lcd.setCursor(3, 0);
lcd.print("--APERTA--");
lcd.setCursor(0, 1);
lcd.print("Aperto da");
showDate(9);
delay(2000);
}
unsigned long currentMillisLimit = millis();
if (currentMillisLimit - previousMillisLimit >= intervalLimit) {
previousMillisLimit = currentMillisLimit;
limit--;
lcd.setCursor(12, 1);
lcd.print(limit);
if (limit <= 0) {
limit = limitSave;
previousMillisLimit = 0;
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("--CHIUSA--");
delay(1000);
digitalWrite(RELAY, LOW);
homeLock();
openedState = true;
state = 1;
}
}
char key = keypad.getKey();
if (key) {
if (key == '*') {
limit = limitSave;
previousMillisLimit = 0;
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("--CHIUSA--");
delay(1000);
digitalWrite(RELAY, LOW);
homeLock();
openedState = true;
state = 1;
}
}
}
void secureState() {
digitalWrite(RED, HIGH);
digitalWrite(GREEN, LOW);
lcd.clear();
lcd.setCursor(2, 0);
lcd.print("--CHIUSA--");
lcd.setCursor(0, 1);
lcd.print("PIN: ");
lcd.cursor();
lcd.blink();
state = 1;
}