#include <Keypad.h>
#include <LiquidCrystal.h>
#include <Servo.h>
int LED_GREEN_PIN = 2;
int LED_RED_PIN = 3;
int LED_TIMER1_PIN = 46;
int LED_TIMER2_PIN = 47;
int LED_TIMER3_PIN = 38;
int LED_TIMER4_PIN = 39;
int LED_TIMER5_PIN = 40;
int LED_TIMER6_PIN = 41;
int LED_TIMER7_PIN = 42;
int LED_TIMER8_PIN = 43;
int LED_TIMER9_PIN = 44;
int LED_TIMER10_PIN = 45;
long DEFUSE_TIME = 900; //seconds
// Keypad defines.
const uint8_t ROWS = 4;
const uint8_t COLS = 4;
char keys[ROWS][COLS] = {
{ '1', '2', '3'},
{ '4', '5', '6' },
{ '7', '8', '9' },
{ '*', '0', '#' }
};
uint8_t colPins[COLS] = { 31, 33, 35 };
uint8_t rowPins[ROWS] = { 23, 25, 27, 29 };
// Hardware defines.
LiquidCrystal LCD(12, 11, 4, 5, 6, 7);
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
Servo SERVO;
// STATE
boolean SETUP_CODE_COMPLETE = false;
boolean SETUP_ARMED_COMPLETE = false;
boolean GAME_END = false;
int LcdTextLength = 16;
String CODE = "";
String DEFUSE_CODE = "";
String TEXT_INPUT_SET_CODE = "SET CODE: ";
String TEXT_RESET_INPUT_CODE = "RESET INPUT...";
String TEXT_INPUT_CODE = "CODE: ";
String TEXT_BOMB_ARMING = "BOMB ARMING";
String TEXT_BOMB_ARMED = "BOMB ARMED";
String TEXT_BOMB_DEFUSED = "BOMB DEFUSED";
int MAX_CODE_LENGTH = 4;
unsigned long lifetime;
long NEXT_LED_TICK = 0;
long BOMB_EXPLODE_TICK = 0;
boolean IS_BOMB_TICK_SET = false;
void setText(const String text="set text", boolean clear=true, int position=0, int line=2){
if(clear == true) {
LCD.clear();
LCD.setCursor(0, 0);
};
if(text.length() > LcdTextLength) {
int i = 0;
while (i <= text.length())
{
if(i == LcdTextLength) {
LCD.setCursor(0, 1);
}
LCD.print(text.charAt(i));
i++;
}
} else{
LCD.print(text);
}
}
void setup() {
Serial.begin(9600);
pinMode(LED_GREEN_PIN, OUTPUT);
pinMode(LED_RED_PIN, OUTPUT);
pinMode(49, INPUT);
SERVO.write(0);
SERVO.attach(52);
LCD.begin(16, 2);
setText(TEXT_INPUT_SET_CODE, false);
keypad.addEventListener(keypadEvent); //add an event listener for this keypad
delay(1000);
}
void loop() {
Serial.println(digitalRead(49));
if(digitalRead(49) == 1) {
triggerServo();
}
lifetime = millis() / 1000;
char key = keypad.getKey();
if(SETUP_ARMED_COMPLETE) {
if(lifetime > NEXT_LED_TICK ) {
// do something;
NEXT_LED_TICK = lifetime + 60;
//setupTimerLeds();
Serial.println(lifetime);
Serial.println(NEXT_LED_TICK);
}
if(lifetime > BOMB_EXPLODE_TICK && GAME_END == false) {
GAME_END = true;
setText("Booooom");
triggerServo();
}
};
}
void triggerServo() {
if(SERVO.read() == 0) {
SERVO.write(90);
} else{
SERVO.write(0);
}
delay(2000);
}
void ledBlinkOnce(int pin, int blinkDelay=500) {
digitalWrite(pin, HIGH);
delay(blinkDelay);
digitalWrite(pin, LOW);
}
void setLedStatus(int pin, uint8_t status=LOW) {
digitalWrite(pin, status);
}
void setAndUpdateCode(String codeInput){
CODE = CODE + codeInput;
ledBlinkOnce(LED_GREEN_PIN);
if(CODE.length() == MAX_CODE_LENGTH ){
SETUP_CODE_COMPLETE = true;
setupDefuseStage();
}
}
void setAndUpdateDefuseCode(String codeInput){
DEFUSE_CODE = DEFUSE_CODE + codeInput;
ledBlinkOnce(LED_GREEN_PIN);
if(DEFUSE_CODE == CODE ){
setLedStatus(LED_RED_PIN, LOW);
setLedStatus(LED_GREEN_PIN, HIGH);
keypad.addEventListener(nullptr);
setText(TEXT_BOMB_DEFUSED);
delay(5000);
setLedStatus(LED_GREEN_PIN, LOW);
}
}
void setupDefuseStage(){
int i = 0;
String dots = "";
while(i < 4) {
ledBlinkOnce(LED_RED_PIN);
setText(TEXT_BOMB_ARMING + dots);
i++;
dots.concat(".");
delay(2000);
}
setText(TEXT_BOMB_ARMED);
setLedStatus(LED_RED_PIN, HIGH);
keypad.addEventListener(nullptr);
BOMB_EXPLODE_TICK = (millis() / 1000 ) + DEFUSE_TIME;
Serial.println(BOMB_EXPLODE_TICK);
delay(2000);
SETUP_ARMED_COMPLETE = true;
int ledTimerPins[] = {
LED_TIMER1_PIN,
LED_TIMER2_PIN,
LED_TIMER3_PIN,
LED_TIMER4_PIN,
LED_TIMER5_PIN,
LED_TIMER6_PIN,
LED_TIMER7_PIN,
LED_TIMER8_PIN,
LED_TIMER9_PIN,
LED_TIMER10_PIN,
};
int timeForLed = 60;
int timeMult = 2;
for (byte i = 0; i < sizeof(ledTimerPins); i = i + 1) {
if(timeForLed < DEFUSE_TIME ) {
setLedStatus(ledTimerPins[i], HIGH);
timeForLed = 60 * (timeMult++);
}
}
setText(TEXT_INPUT_CODE);
keypad.addEventListener(keypadEventDefuse);
}
// Keypad for setup.
void keypadEvent(KeypadEvent key){
String keyInput = String(key);
switch (keypad.getState()){
case PRESSED:
setText(keyInput, false);
setAndUpdateCode(keyInput);
break;
case RELEASED:
switch (key){
}
break;
case HOLD:
switch (key){
}
break;
}
}
// Keypad for defuse.
void keypadEventDefuse(KeypadEvent key){
String keyInput = String(key);
switch (keypad.getState()){
case PRESSED:
setText(keyInput, false);
setAndUpdateDefuseCode(keyInput);
break;
case RELEASED:
switch (key){
}
break;
case HOLD:
switch (key){
case '*':
setText(TEXT_RESET_INPUT_CODE);
DEFUSE_CODE = "";
delay(1000);
setText(TEXT_INPUT_CODE);
}
break;
}
}