#include <TM1637.h>
#include <LiquidCrystal_I2C.h>
#include <Keypad.h>
enum STAGE{
INIT,
SETTIME,
READY,
COUNTDOWN,
DEACTIVATE
};
STAGE stage = INIT;
int CLK = 12;
int DIO = 11;
int buzzer = 9;
int relay = 10;
int redled = A1;
int yellowled = A2;
int greenled = A3;
int Minutes = 00;
int Seconds = 00;
int trycount = 0;
int keycount = 0;
int i = 0;
int keytone_interval = 50;
int count_interval;
uint16_t pre_timestamp;
const byte ROWS = 4;
const byte COLS = 3;
char keys[ROWS][COLS] = {
{'1', '2', '3'},
{'4', '5', '6'},
{'7', '8', '9'},
{'*', '0', '#'}
};
byte rowPins[ROWS] = {7, 2, 3, 5}; //7,2,3,5 for Black 4x3 keypad
byte colPins[COLS] = {6, 8, 4}; //6,8,4 for Black 4x3 Keypad
char password[7] = "7355608";
char entered[7] = "";
char strTime[4] = "0500";
char tpos = 0;
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
LiquidCrystal_I2C lcd(0x27, 16, 2);
TM1637 tm(CLK, DIO);
char bCount = 0;
void setup() {
tm.init();
tm.set(2);
tm.point(1);
pinMode(buzzer, OUTPUT);
pinMode(relay, OUTPUT);
pinMode(redled, OUTPUT);
pinMode(yellowled, OUTPUT);
pinMode(greenled, OUTPUT);
lcd.init();
lcd.backlight();
digitalWrite(redled,HIGH);
digitalWrite(yellowled,HIGH);
digitalWrite(greenled,HIGH);
digitalWrite(buzzer,LOW);
tone(buzzer, 2000);
delay(keytone_interval*3);
digitalWrite(redled,LOW);
digitalWrite(yellowled,LOW);
digitalWrite(greenled,LOW);
digitalWrite(buzzer,HIGH);
noTone(buzzer);
lcd.clear();
lcd.print("Enter code:");
lcd.blink();
lcd.setCursor(0, 1);
lcd.print(' ');
strTime[0] = '0';
strTime[1] = '0';
strTime[2] = '0';
strTime[3] = '0';
Minutes = 0;
Seconds = 0;
updateTM();
}
int intv_count = 0;
int multipuls = 1;
void loop() {
uint16_t timestamp = millis();
char armcode = keypad.getKey();
if(bCount!=0){
timestamp = millis();
if(timestamp - pre_timestamp > count_interval){
digitalWrite(redled,HIGH);
tone(buzzer, 2000);
delay(keytone_interval);
digitalWrite(redled,LOW);
noTone(buzzer);
intv_count++;
if(intv_count % multipuls == 0) Seconds--;
if(Seconds<0){
Seconds = 59;
Minutes--;
if(Minutes <0){
OnExplode();
}
if(Minutes == 0){
multipuls = 2;
count_interval = 500 - keytone_interval;
}
}
if(Minutes == 0 && Seconds == 3)digitalWrite(relay,HIGH);
strTime[0] = Minutes/10 + 0x30;
strTime[1] = Minutes%10 + 0x30;
strTime[2] = Seconds/10 + 0x30;
strTime[3] = Seconds%10 + 0x30;
updateTM();
pre_timestamp = timestamp;
}
}
if (armcode != NO_KEY)
{
digitalWrite(yellowled,HIGH);
tone(buzzer, 2000);
delay(keytone_interval);
digitalWrite(yellowled,LOW);
noTone(buzzer);
switch(stage){
case INIT:
switch(armcode){
case '*':
//case '#'|'*':
stage = SETTIME;
tpos = 0;
strTime[0] = '0';
strTime[1] = '0';
strTime[2] = '0';
strTime[3] = '0';
Minutes = 0;
Seconds = 0;
updateTM();
lcd.clear();
lcd.print("Set timer:");
break;
default:
if(armcode>=0x30 && armcode < 0x3a){
entered[keycount] = armcode;
keycount++;
lcd.setCursor(keycount, 1);
lcd.print(armcode);
lcd.blink();
if(keycount==7){
//if (entered[0] == password[0] && entered[1] == password[1] && entered[2] == password[2] && entered[3] == password[3]){
if(validateCode()==1){
stage = READY;
delay(500);
keycount = 0;
lcd.noBlink();
lcd.clear();
lcd.print("press '#' ");
lcd.setCursor(4, 1);
lcd.print("to activate.");
}else{
delay(500);
keycount = 0;
lcd.noBlink();
lcd.clear();
lcd.print("Incorrect code");
delay(1000);
lcd.clear();
lcd.print("Enter code:");
lcd.blink();
lcd.setCursor(0, 1);
lcd.print(' ');
}
}
}
break;
}
break;
case SETTIME:
switch(armcode){
case '*':
case '#':
for(i=0;i<3;i++){
digitalWrite(redled,HIGH);
digitalWrite(yellowled,HIGH);
digitalWrite(greenled,HIGH);
delay(200);
digitalWrite(redled,LOW);
digitalWrite(yellowled,LOW);
digitalWrite(greenled,LOW);
delay(200);
}
stage = INIT;
keycount = 0;
lcd.clear();
lcd.print("Enter code:");
lcd.blink();
lcd.setCursor(0, 1);
lcd.print(' ');
break;
default:
if(tpos == 0 || tpos == 2){
if((armcode-0x30)<6){
strTime[tpos] = armcode;
tpos++;
}
}else{
strTime[tpos] = armcode;
tpos++;
}
updateTM();
if(tpos>3)tpos = 0;
break;
}
break;
case READY:
if(armcode == '#'){
stage = COUNTDOWN;
lcd.clear();
lcd.print("Activated.");
bCount = 1;
intv_count = 0;
trycount = 0;
count_interval = 1000 - keytone_interval;
Minutes = (strTime[0] - 0x30)*10+(strTime[1] - 0x30);
Seconds = (strTime[2] - 0x30)*10+(strTime[3] - 0x30);
}
break;
case COUNTDOWN:
if(armcode == '*'){
stage = DEACTIVATE;
keycount = 0;
lcd.clear();
lcd.print("Enter code:");
lcd.blink();
lcd.setCursor(0, 1);
lcd.print(' '); }
break;
case DEACTIVATE:
entered[keycount] = armcode;
keycount++;
lcd.setCursor(keycount, 1);
lcd.print(armcode);
lcd.blink();
if(keycount==7){
// correct code ... deactivated...
//if (entered[0] == password[0] && entered[1] == password[1] && entered[2] == password[2] && entered[3] == password[3]){
if(validateCode()==1){
delay(800);
lcd.clear();
lcd.print("Completed");
lcd.setCursor(4, 1);
lcd.noBlink();
bCount = 0;
for(i=0;i<3;i++){
digitalWrite(greenled,HIGH);
tone(buzzer, 2000);
delay(50);
if(i<2) digitalWrite(greenled,LOW);
noTone(buzzer);
delay(900);
}
digitalWrite(greenled,HIGH);
delay(1000);
digitalWrite(greenled,LOW);
stage = INIT;
keycount = 0;
lcd.clear();
lcd.print("Enter code:");
lcd.blink();
lcd.setCursor(0, 1);
lcd.print(' ');
}else{ // incorrect...
trycount++;
for(i=0;i<3;i++){
digitalWrite(redled,HIGH);
digitalWrite(yellowled,HIGH);
digitalWrite(greenled,HIGH);
delay(200);
digitalWrite(redled,LOW);
digitalWrite(yellowled,LOW);
digitalWrite(greenled,LOW);
delay(200);
}
keycount = 0;
if(trycount == 2){ //
int totalTime = (Minutes*60+Seconds)/2;
Minutes = totalTime / 60;
Seconds = Seconds % 60;
multipuls = 2;
count_interval = 500 - keytone_interval;
}
if(trycount == 3){ // explode...................
OnExplode();
}else{
lcd.noBlink();
lcd.clear();
lcd.print("Incorrect");
lcd.setCursor(4, 1);
lcd.print(trycount);
lcd.print(" tryed");
delay(1000);
lcd.clear();
lcd.print("Enter code:");
lcd.blink();
lcd.setCursor(0, 1);
lcd.print(' ');
}
}
}
break;
}
}
}
char validateCode(){
for(i=0;i<7;i++){
if(entered[i] == password[i])
return 1;
}
return 0;
}
void OnExplode(){
bCount = 0;
Seconds = 0;
Minutes = 0;
digitalWrite(redled,HIGH);
lcd.clear();
lcd.setCursor(4, 1);
lcd.print("Time out");
delay(1000);
digitalWrite(relay,LOW);
strTime[0] = '0';
strTime[1] = '0';
strTime[2] = '0';
strTime[3] = '0';
updateTM();
lcd.noBlink();
lcd.clear();
lcd.home();
lcd.print("Bomb Defused!");
lcd.setCursor(0, 1);
lcd.print("Well Done!");
keycount = 0;
delay(3000);
digitalWrite(redled,LOW);
delay(1000);
char flag = 0;
for(i=0;i<6;i++){
flag = 1 - flag;
digitalWrite(greenled, flag);
if(flag==1) noTone(buzzer);
else tone(buzzer,2000);
delay(500);
}
digitalWrite(greenled, 1);
tone(buzzer, 2000);
delay(15000);
digitalWrite(greenled, 0);
noTone(buzzer);
stage = INIT;
keycount = 0;
lcd.clear();
lcd.print("Enter code:");
lcd.blink();
lcd.setCursor(0, 1);
lcd.print(' ');
}
void updateTM(){
tm.display(0, strTime[0]-0x30);
tm.display(1, strTime[1]-0x30);
tm.point(1);
tm.display(2, strTime[2]-0x30);
tm.display(3, strTime[3]-0x30);
}