void(* ku_reset) (void) = 0;
#include <LiquidCrystal_I2C.h>
#include <Keypad.h>
#include <EEPROM.h>
#include "SafeState.h"
LiquidCrystal_I2C lcd(0x27,16,2);
#define EEPROM_ADDR_LOCKED 0
#define EEPROM_ADDR_CODE_LEN 1
#define EEPROM_ADDR_CODE 2
#define EEPROM_EMPTY 0xff
#define tombol_reset 12
#define buzzer A0
#define led A1
const byte KEYPAD_ROWS = 4;
const byte KEYPAD_COLS = 4;
byte rowPins[KEYPAD_ROWS] = {9, 8, 7, 6};
byte colPins[KEYPAD_COLS] = {5, 4, 3, 2};
char keys[KEYPAD_ROWS][KEYPAD_COLS] = {
{'1', '2', '3', 'A'},
{'4', '5', '6', 'B'},
{'7', '8', '9', 'C'},
{'*', '0', '#', 'D'}
};
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, KEYPAD_ROWS, KEYPAD_COLS);
SafeState safeState;
int pos,menit,detik;
String message;
char buff[33];
bool flag,flag_password,newCodeNeeded;
long int timer;
void lock() {
safeState.lock();
}
void unlock() {
}
void showStartupMessage() {
lcd.setCursor(0, 0); lcd.print("BOMB SIMULATION!");
delay(500);
lcd.setCursor(0, 1);
message = "=CS-GO2 C4 BOMB=";
for (byte i = 0; i < message.length(); i++) {
lcd.print(message[i]);
delay(100);
}
delay(1500);
}
// Proses Timer berjalan di sini
String inputSecretCode() {
lcd.setCursor(8, 1); lcd.print("[______]");
lcd.setCursor(9, 1); pos=0;
String result = "";
if(flag) {
timer = millis();
}
while(result.length() < 6) {
if(flag) {
if(millis() - timer > 1000) {
if(detik>0) detik--;
else {
if(menit>0) {
menit--;
detik=59;
}
}
timer = millis();
}
if(detik%2==0) sprintf(buff,"[%02d:%02d]",menit,detik);
else sprintf(buff,"[%02d %02d]",menit,detik);
lcd.setCursor(0,1); lcd.print(buff);
if(menit>1) {
if(detik%15==0) {
digitalWrite(buzzer,HIGH); digitalWrite(led,HIGH); delay(300);
digitalWrite(buzzer,LOW); digitalWrite(led,LOW); delay(750);
}
}
else if(menit==1) {
if(detik%5==0) {
digitalWrite(buzzer,HIGH); digitalWrite(led,HIGH); delay(300);
digitalWrite(buzzer,LOW); digitalWrite(led,LOW); delay(750);
}
}
else {
if(detik>40) {
if(detik%2==0) { digitalWrite(buzzer,HIGH); digitalWrite(led,HIGH); }
else { digitalWrite(buzzer,LOW); digitalWrite(led,LOW); }
}
else if(detik>10) {
digitalWrite(buzzer,HIGH); digitalWrite(led,HIGH); delay(500);
digitalWrite(buzzer,LOW); digitalWrite(led,LOW); delay(500);
}
else if(detik>0) {
digitalWrite(buzzer,HIGH); digitalWrite(led,HIGH); delay(100);
digitalWrite(buzzer,LOW); digitalWrite(led,LOW); delay(100);
}
else {
lcd.setCursor(0,0); lcd.print(" BOMB EXPLODED! ");
lcd.setCursor(0,1); lcd.print(" TERRORIST WIN! ");
EEPROM.write(1,0xff);
EEPROM.write(0,0);
while(1) {
digitalWrite(buzzer,HIGH);
digitalWrite(led,HIGH); delay(100);
digitalWrite(led,LOW); delay(100);
}
}
}
}
char key = keypad.getKey();
if(key >= '0' && key <= '9') {
Serial.print(key);
lcd.setCursor(9+pos, 1); lcd.print('*');
result += key;
pos++;
}
// Tombol reset Password
if(digitalRead(tombol_reset)==LOW) {
EEPROM.write(1,0xff);
EEPROM.write(0,0);
ku_reset();
}
}
return result;
}
void showWaitScreen(int delayMillis) {
lcd.setCursor(0, 1); lcd.print("[..............]");
lcd.setCursor(1, 1);
for (byte i = 0; i < 14; i++) {
delay(delayMillis);
lcd.print("#");
}
delay(200);
}
bool setNewCode() {
lcd.clear();
lcd.setCursor(0, 0); lcd.print("Activation Code:");
String newCode = inputSecretCode();
lcd.clear();
lcd.setCursor(0, 0); lcd.print("Confirm ActCode:");
String confirmCode = inputSecretCode();
if(newCode.equals(confirmCode)) {
safeState.setCode(newCode);
return true;
} else {
lcd.clear();
lcd.setCursor(1, 0); lcd.print("Code mismatch");
lcd.setCursor(0, 1); lcd.print("Safe not locked!");
delay(2000);
return false;
}
}
bool cekActivateCode() {
lcd.clear();
lcd.setCursor(0, 0); lcd.print(":BOMB ActivCODE:");
sprintf(buff,"[%02d:%02d]",menit,detik);
lcd.setCursor(0, 1); lcd.print(buff);
String confirmCode = inputSecretCode();
bool unlockedSuccessfully = safeState.unlock(confirmCode);
showWaitScreen(50);
if(unlockedSuccessfully) {
lcd.setCursor(0, 1); lcd.print("=Code Verified!=");
delay(1000);
return true;
} else {
lcd.setCursor(0, 1); lcd.print("WRONG ActivCODE!");
menit++;
delay(2000);
return false;
}
}
void showUnlockMessage() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.write(2); lcd.print("=BOMB DEFUSED="); lcd.write(2);
lcd.setCursor(0, 1); lcd.print("COUNTER TRRS WIN");
digitalWrite(buzzer,LOW); digitalWrite(led,LOW);
flag=0;
delay(5000);
}
void safeUnlockedLogic() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.write(2); lcd.print(" #to Activate "); lcd.write(2);
auto key = keypad.getKey();
while(key != 'A' && key != '#') {
key = keypad.getKey();
lcd.setCursor(0, 1);
message = "=CS-GO2 C4 BOMB=";
for(byte i = 0; i < message.length(); i++) {
lcd.print(message[i]);
delay(30);
}
key = keypad.getKey();
lcd.setCursor(0, 1);
for(byte i = 0; i < message.length(); i++) {
lcd.print("*");
delay(30);
}
}
bool readyToLock = true;
readyToLock = cekActivateCode();
if(readyToLock) {
lcd.clear();
lcd.setCursor(5, 0);
lcd.write(2); lcd.print(" "); lcd.write(126); lcd.print(" "); lcd.write(2);
safeState.lock();
showWaitScreen(50);
}
}
void safeLockedLogic() {
lcd.clear();
lcd.setCursor(0, 0); lcd.print("BOMB HB PLANTED!");
flag=1;
String userCode = inputSecretCode();
bool unlockedSuccessfully = safeState.unlock(userCode);
showWaitScreen(100);
if(unlockedSuccessfully) {
showUnlockMessage();
unlock();
} else {
lcd.clear();
lcd.setCursor(0, 0); lcd.print("Access Denied!");
showWaitScreen(100);
}
}
byte iconLocked[8] = {0b01110,0b10001,0b10001,0b11111,0b11011,0b11011,0b11111};
byte iconUnlocked[8] = {0b01110,0b10000,0b10000,0b11111,0b11011,0b11011,0b11111};
void setup() {
lcd.backlight(); lcd.init();
lcd.createChar(1,iconLocked);
lcd.createChar(2,iconUnlocked);
pinMode(tombol_reset, INPUT_PULLUP);
pinMode(buzzer,OUTPUT);
pinMode(led,OUTPUT);
/* Make sure the physical lock is sync with the EEPROM state */
Serial.begin(115200);
newCodeNeeded = true;
if(safeState.hasCode()) {
lcd.setCursor(0, 1); lcd.print(" A = New Code ");
newCodeNeeded = false;
delay(2000);
}
else setNewCode();
showStartupMessage();
menit = 1;
detik = 0;
}
void loop() {
if(safeState.locked()) {
safeLockedLogic();
} else {
safeUnlockedLogic();
}
}