#include <LiquidCrystal.h>
#include <Keypad.h>
#include <Servo.h>
#include <Arduino.h>
#include <EEPROM.h>
/* meccanismo di blocco */
#define PIN_SERVO 7
#define POS_BLOCCATO 20
#define POS_SBLOCCATO 90
Servo servo;
/* Display */
LiquidCrystal lcd(13, 12, 11, 10, 9, 8);
/* tastierino */
const byte RIGHE_TASTIERA = 4;
const byte COLONNE_TASTIERA = 4;
byte pinRighe[RIGHE_TASTIERA] = {5, 4, 3, 2};
byte pinColonne[COLONNE_TASTIERA] = {A3, A2, A1, A0};
char tasti[RIGHE_TASTIERA][COLONNE_TASTIERA] = {
{'1', '2', '3', 'A'},
{'4', '5', '6', 'B'},
{'7', '8', '9', 'C'},
{'*', '0', '#', 'D'}
};
Keypad tastiera = Keypad(makeKeymap(tasti), pinRighe, pinColonne, RIGHE_TASTIERA, COLONNE_TASTIERA);
#define I_B 0
#define I_L_C 1
#define I_C 2
#define V_VUOTO 0xff
#define S_APERTO (char)0
#define S_CHIUSO (char)1
class safe {
private:
bool bloccoAttivo;
public:
safe() {
this->bloccoAttivo = EEPROM.read(I_B) == S_CHIUSO;
}
void blocca() {
this->impostaBlocco(true);
}
bool statoBlocco() {
return this->bloccoAttivo;
}
bool PinPresente() {
auto lunghezzaPin = EEPROM.read(I_L_C);
return lunghezzaPin != V_VUOTO;
}
void impostaPin(String nuovoPin) {
EEPROM.write(I_L_C, nuovoPin.length());
for (byte i = 0; i < nuovoPin.length(); i++) {
EEPROM.write(I_C + i, nuovoPin[i]);
}
}
bool sblocca(String Pin) {
auto lunghezzaPin = EEPROM.read(I_L_C);
if (lunghezzaPin == V_VUOTO) {
// Non c'era alcun Pin, quindi lo sblocco avviene sempre
this->impostaBlocco(false);
return true;
}
if (Pin.length() != lunghezzaPin) {
return false;
}
for (byte i = 0; i < Pin.length(); i++) {
auto cifra = EEPROM.read(I_C + i);
if (cifra != Pin[i]) {
return false;
}
}
this->impostaBlocco(false);
return true;
}
void impostaBlocco(bool attivo) {
this->bloccoAttivo = attivo;
EEPROM.write(I_B, attivo ? S_CHIUSO : S_APERTO);
}
};
safe safe;
void blocca() {
servo.write(POS_BLOCCATO);
safe.blocca();
}
void sblocca() {
servo.write(POS_SBLOCCATO);
}
void restart_lobby() {
lcd.setCursor(4, 0);
lcd.print("Benvenuto!");
delay(1000);
lcd.setCursor(0, 2);
String messaggio = "Cassaforte EHF";
for (byte i = 0; i < messaggio.length(); i++) {
lcd.print(messaggio[i]);
delay(100);
}
delay(500);
}
String inserisciPin() {
lcd.setCursor(5, 1);
lcd.print("[____]");
lcd.setCursor(6, 1);
String risultato = "";
while (risultato.length() < 4) {
char tasto = tastiera.getKey();
if (tasto >= '0' && tasto <= '9') {
lcd.print('*');
risultato += tasto;
}
}
return risultato;
}
void disp_wait(int delayMillis) {
lcd.setCursor(2, 1);
lcd.print("[..........]");
lcd.setCursor(3, 1);
for (byte i = 0; i < 10; i++) {
delay(delayMillis);
lcd.print("=");
}
}
bool new_Pin() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(" New pin: ");
String nuovoPin = inserisciPin();
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Conferma");
String confermaPin = inserisciPin();
if (nuovoPin.equals(confermaPin)) {
safe.impostaPin(nuovoPin);
return true;
} else {
lcd.clear();
lcd.setCursor(1, 0);
lcd.print("Errore!");
lcd.setCursor(0, 1);
lcd.print("Sblocco");
delay(2000);
return false;
}
}
void unlock_text() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Sbloccato!");
delay(1000);
}
void unlock_safe() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Sbloccato!");
bool nuovoPinNecessario = true;
if (safe.PinPresente()) {
lcd.setCursor(0, 1);
lcd.print("New code");
nuovoPinNecessario = false;
}
auto tasto = tastiera.getKey();
while (tasto != 'A' && tasto != '#') {
tasto = tastiera.getKey();
}
bool ready_lock = true;
if (tasto == 'A' || nuovoPinNecessario) {
ready_lock = new_Pin();
}
if (ready_lock) {
lcd.clear();
lcd.setCursor(5, 0);
lcd.print("Bloccato!");
safe.blocca();
blocca();
disp_wait(100);
}
}
void logic_safelock() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Bloccato!");
String PinUtente = inserisciPin();
bool sbloccatoConSuccesso = safe.sblocca(PinUtente);
disp_wait(200);
if (sbloccatoConSuccesso) {
unlock_text();
sblocca();
} else {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Errore");
disp_wait(1000);
}
}
void setup() {
lcd.begin(16, 2);
servo.attach(PIN_SERVO);
/* verifica EEPROM */
Serial.begin(115200);
if (safe.statoBlocco()) {
blocca();
} else {
sblocca();
}
restart_lobby();
}
void loop() {
if (safe.statoBlocco()) {
logic_safelock();
} else {
unlock_safe();
}
}
uno:A5.2
uno:A4.2
uno:AREF
uno:GND.1
uno:13
uno:12
uno:11
uno:10
uno:9
uno:8
uno:7
uno:6
uno:5
uno:4
uno:3
uno:2
uno:1
uno:0
uno:IOREF
uno:RESET
uno:3.3V
uno:5V
uno:GND.2
uno:GND.3
uno:VIN
uno:A0
uno:A1
uno:A2
uno:A3
uno:A4
uno:A5
lcd1:VSS
lcd1:VDD
lcd1:V0
lcd1:RS
lcd1:RW
lcd1:E
lcd1:D0
lcd1:D1
lcd1:D2
lcd1:D3
lcd1:D4
lcd1:D5
lcd1:D6
lcd1:D7
lcd1:A
lcd1:K
servo1:GND
servo1:V+
servo1:PWM
r1:1
r1:2
keypad1:R1
keypad1:R2
keypad1:R3
keypad1:R4
keypad1:C1
keypad1:C2
keypad1:C3
keypad1:C4