Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <Keypad.h>
- #include <EEPROM.h>
- #include "EEPROMAnything.h"
- const byte ROWS = 4; //four rows
- const byte COLS = 3; //three columns
- char keys[ROWS][COLS] = {
- {'1','2','3'},
- {'4','5','6'},
- {'7','8','9'},
- {'*','0','#'}
- };
- byte rowPins[ROWS] = {10, 9, 8, 7}; //connect to the row pinouts of the keypad
- byte colPins[COLS] = {13, 12, 11}; //connect to the column pinouts of the keypad
- Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );
- //Define all the bomb states
- #define READY 0
- #define ARMED 1
- #define DISARMED 2
- #define DETONATED 3
- int second=30, minute=10, hour=0; // declare time variables
- int bombState=0; //0 = Ready, 1 = Armed, 2 = Disarmed, 3 = detonated
- int configMenuFlag = 0; //prevents configMenu from launching after a key is pressed
- int speakerPin = 5;//pin that the piezo buzzer is connected to.
- //variables for buzzer chirp function
- static unsigned long currentMillis = 0;
- long previousTime = 0;//holds previous time in ms
- long previousDelay = 0;//holds previous time in ms since buzzer was active
- int stop = 0;//function kill flag
- long code = 0;//keeps a running tally of the digits entered into the keypad
- int count = 0;//number of correct digits
- char ArmCode[] = "8507840";//code to arm the bomb
- char disarmCode[] = "5248040";//code to disarm the bomb
- char adminCode[] = "4725226";//code to change timer
- //configuration
- //structure for storing the arm code, disarm code, admin code, and time in the eeprom memory
- struct config_t
- {
- long arm;
- long disarm;
- long admin;
- int c_hour;
- int c_minute;
- int c_second;
- } configuration;
- void setup()
- {
- Serial.begin(9600);
- backlightOn();
- pinMode(speakerPin, OUTPUT);//sets the output pin for the piezo buzzer
- readConfig();//read in the arm, disarm, admin codes and timer
- //saveConfig();
- //display the default timer when prop boots up
- clearLCD();
- delay(1000);
- selectLineTwo();
- Serial.print(hour, DEC); // the hour, sent to the screen in decimal format
- Serial.print(":"); // a colon between the hour and the minute
- Serial.print(minute, DEC); // the minute, sent to the screen in decimal format
- Serial.print(":"); // a colon between the minute and the second
- Serial.println(second, DEC); // the second, sent to the screen in decimal format
- delay(1000);
- clearLCD();
- }
- void loop(){
- switch (bombState) {
- /***********************************************************
- *Ready state prepares bomb, waits for arm code to be input *
- * *
- ************************************************************/
- case READY:
- while (count < (sizeof(ArmCode) - 1)) {//loop until the full and correct arm code is entered
- selectLineTwo();
- Serial.print("Enter ArmCode");
- selectLineOne();
- Serial.print("Code"); //prompt for arm code
- Serial.print(": ");
- char key = '\0';
- do{
- key = keypad.getKey();
- }
- while(key == '\0');
- code = (code * 10) + (key - 48); //stores the current correct digits for display later
- if(key == '#' && configMenuFlag == 0) {//check if user wants to enter menu
- key = '\0';
- configMenu();// enter menu
- count = 0;
- code = 0;
- clearLCD();
- }
- else if(key == ArmCode[count]) {//if the key matches the code
- count++;
- configMenuFlag = 1;//once the code is started, the menu cannot be entered
- }
- // else { //if the key does not match the code, reset
- //count = 0;
- //code = 0;
- //configMenuFlag = 1;//once the code is started, the menu cannot be entered
- //clearLCD();
- // }
- selectLineOne();
- Serial.print("Code"); //prompt for arm code
- Serial.print(": ");
- Serial.print(code);//display correct digits that have been entered
- }//end while
- clearLCD();
- bombState = ARMED;//when the correct code has been entered, move to armed state
- count = 0;
- code = 0;
- break;
- /***********************************************************
- *Armed *
- * *
- ************************************************************/
- case ARMED:
- selectLineOne();
- Serial.print("Code"); //prompt for disarm code
- Serial.print(": ");
- char key;
- do{
- key = keypad.getKey();
- countdown();//displays countdown while simultaneously checking for disarm code
- if (second == 0 && minute == 0 && hour == 0) {
- code = 0;
- clearLCD();
- bombState = DETONATED; //clear LCD and set bomb state to "detonated" when timer runs out
- break;
- }
- //if the correct code is entered, move to disarmed state
- else if(count == (sizeof(disarmCode) - 1)){
- code = 0;
- clearLCD();
- bombState = DISARMED;
- }
- }//end do
- while(key == '\0' && bombState == ARMED);
- code = (code * 10) + (key - 48); //store correct digits for display later
- //if the key entered matches the disarm code, increase count.
- if(key == disarmCode[count]) {
- count++;
- }
- else {
- count = 0;
- code = 0;
- clearLCD();
- }
- selectLineOne();
- Serial.print("Code"); //prompt for arm code
- Serial.print(": ");
- Serial.print(code);//display the current correct digits
- break;
- /*******************************************************
- *Detonated. activate buzzer for 8 beeps, then 1 long.
- *Print bomb detonated message to LCD.
- ********************************************************/
- case DETONATED:
- clearLCD();
- digitalWrite(speakerPin, HIGH);//turn on buzzer
- delay(5000);//wait 5 seconds
- digitalWrite(speakerPin, LOW);//turn off buzzer
- selectLineOne();
- Serial.print(">Bomb Detonated<"); //loop message informing user of bomb detonation.
- do{
- stop = 1;
- }
- while(stop == 1);//endless loop stops program
- /**************************************************************
- *DISARMED. Counter stopped, displays "bomb disarmed"
- *
- **************************************************************/
- case DISARMED:
- selectLineOne();
- Serial.print("Bomb Disarmed"); //bomb has been disarmed, inform user.
- do{
- int stop = 1;
- }
- while(stop == 1);//endless loop stops program
- }//end case statements
- }
- /***********************************************************
- * Main countdown timer *
- * countdown() *
- ************************************************************/
- void countdown(){
- static unsigned long lastTick = 0; // set up a local variable to hold the last time we decremented one second
- // (static variables are initialized once and keep their values between function calls)
- // decrement one second every 1000 milliseconds
- if (second > 0) {
- if (millis() - lastTick >= 1000) {
- lastTick = millis();
- second--;
- }
- }
- // decrement one minute every 60 seconds
- if (minute > 0) {
- if (second <= 0) {
- minute--;
- second = 60; // reset seconds to 60
- }
- }
- // decrement one hour every 60 minutes
- if (hour > 0) {
- if (minute <= 0) {
- hour--;
- minute = 60; // reset minutes to 60
- }//closes if
- }//closes if
- beepSecondaryBuzzer();
- //the code below beeps the siren once every minute.
- /*
- currentMillis = millis();
- if (currentMillis - previousTime > interval)
- {
- previousTime = currentMillis;
- previousDelay = currentMillis;
- digitalWrite(speakerPin, HIGH);//turn on buzzer
- }
- if (currentMillis - previousDelay > 100) {//100ms chirp duration
- digitalWrite(speakerPin, LOW);//turn off buzzer
- }
- */
- selectLineTwo();
- Serial.print("ARMED: ");
- Serial.print(hour, DEC); // the hour, sent to the screen in decimal format
- Serial.print(":"); // a colon between the hour and the minute
- Serial.print(minute, DEC); // the minute, sent to the screen in decimal format
- Serial.print(":"); // a colon between the minute and the second
- Serial.println(second, DEC); // the second, sent to the screen in decimal format
- } //close countdown();
- /*********************************************************************
- * Serial LCD disagnostic and general use tools *
- * selectLineOne(); | selectLineTwo(); | goTo(); | clearLCD(); *
- * backlightOn(); | backlightOff(); | serCommand(); *
- **********************************************************************/
- void selectLineOne(){ //puts the cursor at line 0 char 0.
- Serial.print(0xFE, BYTE); //command flag
- Serial.print(128, BYTE); //position
- }
- void selectLineTwo(){ //puts the cursor at line 0 char 0.
- Serial.print(0xFE, BYTE); //command flag
- Serial.print(192, BYTE); //position
- }
- void goTo(int position) { //position = line 1: 0-15, line 2: 16-31, 31+ defaults back to 0
- if (position<16){ Serial.print(0xFE, BYTE); //command flag
- Serial.print((position+128), BYTE); //position
- }else if (position<32){Serial.print(0xFE, BYTE); //command flag
- Serial.print((position+48+128), BYTE); //position
- } else { goTo(0); }
- }
- void clearLCD(){
- Serial.print(0xFE, BYTE); //command flag
- Serial.print(0x01, BYTE); //clear command.
- }
- void backlightOn(){ //turns on the backlight
- Serial.print(0x7C, BYTE); //command flag for backlight stuff
- Serial.print(157, BYTE); //light level.
- }
- void backlightOff(){ //turns off the backlight
- Serial.print(0x7C, BYTE); //command flag for backlight stuff
- Serial.print(128, BYTE); //light level for off.
- }
- void serCommand(){ //a general function to call the command flag for issuing all other commands
- Serial.print(0xFE, BYTE);
- }
- /***********************************************************
- * admin code, arm code, disarm code, and timer editing *
- * function. *
- * configMenu(); *
- ************************************************************/
- void configMenu(){
- int exitMenu = 0;
- int back = 0; //prevent user from exiting without typing in full code
- char menuPage; //prompt for Menu page
- clearLCD();
- selectLineOne();
- Serial.print("Menu");//inform the user that they are entered the menu
- delay(2000);
- clearLCD();
- code = 0;
- count = 0;
- while (count < (sizeof(adminCode) - 1)) {
- selectLineTwo();
- Serial.print("Enter AdminCode");
- selectLineOne();
- Serial.print("Code"); //prompt for admin code
- Serial.print(": ");
- char adminKey;
- do{
- adminKey = keypad.getKey(); //loop and wait for keypress
- }
- while(adminKey == '\0');
- code = (code * 10) + (adminKey - 48);//store correct digits for later use
- if(adminKey == '#') {
- return;//return to the arm code state
- count = 0;
- code = 0;
- clearLCD();
- }
- //if the correct key is pressed
- else if(adminKey == adminCode[count]) {
- count++;
- }
- else {
- count = 0;
- code = 0;
- clearLCD();//if the key is incorrect, reset
- }
- selectLineOne();
- Serial.print("Code"); //prompt for admin code
- Serial.print(": ");
- Serial.print(code);//display correct digits
- }//end while
- clearLCD();
- do { //display menu
- selectLineOne();
- Serial.print("1.Admin 2.Time");
- selectLineTwo();
- Serial.print("3.Arm 4.Disarm");
- do{
- menuPage = keypad.getKey();
- } //keep reading if anything but 1 - 4 is entered
- while(menuPage == '\0' || menuPage == '*' || menuPage == '0' || menuPage > 52);
- switch(menuPage) {
- case '1': // Edit admin code
- clearLCD();
- selectLineTwo();
- Serial.print("# To Exit");
- delay(2000);
- clearLCD();
- selectLineTwo();
- Serial.print("AdminCode");
- selectLineOne();
- Serial.print("Code"); //prompt for admin code
- Serial.print(": ");
- count = 0;
- code = 0;//
- while(count < (sizeof(adminCode) - 1)) {
- char adminCodeKey;
- do{
- adminCodeKey = keypad.getKey();//wait for a keypress
- }
- while(adminCodeKey == '\0');
- code = (code * 10) + (adminCodeKey - 48); //store correct digits for later use
- if(adminCodeKey == '#' && back == 0) {
- count = sizeof(adminCode);
- code = 0;
- exitMenu = 1;//bail out if # is pressed
- clearLCD();
- }
- else {
- //if key matches code
- adminCode[count] = adminCodeKey;
- count++;
- back = 1;
- }
- selectLineOne();
- Serial.print("Code"); //prompt for arm code
- Serial.print(": ");
- Serial.print(code);
- }//end admincode while
- clearLCD();
- selectLineOne();
- Serial.print(code);
- selectLineTwo();
- Serial.print("* to exit");//display new code and give user time to see it
- char key1;
- do{
- key1 = keypad.getKey();
- }
- while(key1 == '\0' || key1 != '*');//keep looping until user presses *
- break;
- case '2': //Timer
- clearLCD();
- selectLineTwo();
- Serial.print("# To Exit");
- delay(2000);
- clearLCD();
- char timeInt;
- selectLineOne();
- Serial.print("Enter Hours");
- do{
- timeInt = keypad.getKey();
- }
- while(timeInt == '\0' || timeInt < '0' || timeInt > '6');
- hour = (timeInt - '0') * 10;//get first digit and convert to int
- do{
- timeInt = keypad.getKey();
- }
- while(timeInt == '\0');
- hour = (timeInt - '0') + hour;//get second digit.
- clearLCD();
- timeInt = 'L';
- Serial.print("Enter Minutes");
- do{
- timeInt = keypad.getKey();
- }
- while(timeInt == '\0' || timeInt < '0' || timeInt > '6');
- while (timeInt < '0' || timeInt > '6'){
- timeInt = keypad.getKey();
- }
- minute = (timeInt - '0') * 10;//get first digit and convert to int
- do{
- timeInt = keypad.getKey();
- }
- while(timeInt == '\0');
- minute = (timeInt - '0') + minute;//get second digit.
- clearLCD();
- timeInt = 'L';
- Serial.print("Enter Seconds");
- do{
- timeInt = keypad.getKey();
- }
- while(timeInt == '\0' || timeInt < '0' || timeInt > '6');
- while (timeInt < '0' || timeInt > '6'){
- timeInt = keypad.getKey();
- }
- second = (timeInt - '0') * 10;//get first digit and convert to int
- do{
- timeInt = keypad.getKey();
- }
- while(timeInt == '\0');
- second = (timeInt - '0') + second;//get second digit.
- clearLCD();
- timeInt = 'L';
- clearLCD();
- selectLineOne();
- Serial.print(hour, DEC); // the hour, sent to the screen in decimal format
- Serial.print(":"); // a colon between the hour and the minute
- Serial.print(minute, DEC); // the minute, sent to the screen in decimal format
- Serial.print(":"); // a colon between the minute and the second
- Serial.println(second, DEC); // the second, sent to the screen in decimal format
- selectLineTwo();
- Serial.print("* to exit");
- char key2;
- do{
- key2 = keypad.getKey();
- }
- while(key2 == '\0' || key2!= '*');//display new code and give user time to see it
- break;
- case '3': //Arm code
- clearLCD();
- selectLineTwo();
- Serial.print("# To Exit");
- delay(2000);
- clearLCD();
- selectLineTwo();
- Serial.print("ArmCode");
- selectLineOne();
- Serial.print("Code"); //prompt for admin code
- Serial.print(": ");
- count = 0;
- code = 0;
- back = 0;
- while(count < (sizeof(ArmCode) - 1)) {
- char armCodeKey;
- do{
- armCodeKey = keypad.getKey();
- }
- while(armCodeKey == '\0');
- code = (code * 10) + (armCodeKey - 48);//store correct digits for later use
- if(armCodeKey == '#' && back == 0) {
- count = sizeof(ArmCode);
- code = 0;
- exitMenu = 1;
- clearLCD();//bail out if exit key is pressed
- }
- else {
- //if key matches code
- ArmCode[count] = armCodeKey;
- count++;
- back = 1;
- }
- selectLineOne();
- Serial.print("Code"); //prompt for arm code
- Serial.print(": ");
- Serial.print(code);
- }//end armcode while
- clearLCD();
- selectLineOne();
- Serial.print(code);
- selectLineTwo();
- Serial.print("* to exit");
- char key3;
- do{
- key3 = keypad.getKey(); //display new code and give user time to see it
- }
- while(key3 == '\0' || key3!= '*');
- break;
- case '4': //disarm
- clearLCD();
- selectLineTwo();
- Serial.print("# To Exit");
- delay(2000);
- clearLCD();
- selectLineTwo();
- Serial.print("disarmCode");
- selectLineOne();
- Serial.print("Code"); //prompt for admin code
- Serial.print(": ");
- count = 0;
- code = 0;
- back = 0;
- while(count < (sizeof(disarmCode) - 1)) {
- char disarmCodeKey;
- do{
- disarmCodeKey = keypad.getKey();
- }
- while(disarmCodeKey == '\0');
- code = (code * 10) + (disarmCodeKey - 48);
- if(disarmCodeKey == '#' && back == 0) {
- count = sizeof(disarmCode);
- code = 0;
- exitMenu = 1;
- clearLCD();
- }
- else {
- disarmCode[count] = disarmCodeKey;
- count++;
- back = 1;
- }
- selectLineOne();
- Serial.print("Code"); //prompt for arm code
- Serial.print(": ");
- Serial.print(code);
- }//end disarmcode while
- clearLCD();
- selectLineOne();
- Serial.print(code);
- selectLineTwo();
- Serial.print("* to exit");
- char key4;
- do{
- key4 = keypad.getKey();//display new code and give user time to see it
- }
- while(key4 == '\0' || key4 != '*');
- break;
- case '#'://exit case
- exitMenu = 1;//exit menu if # is pressed
- break;
- case 'L'://exit case no admin code
- exitMenu = 1;
- break;
- }//end switch
- }while(exitMenu == 0); //end menu while loop
- configMenuFlag = 1;//set flag so menu cannot be opened later
- saveConfig();//write new configuration into memory
- }//end configMenu
- /***********************************************************
- * saves the admin code, arm code, disarm code, and timer *
- * into EEPROM memory where they will survive a power down *
- * saveConfig(); *
- ************************************************************/
- void saveConfig() {
- configuration.arm = atol(ArmCode);
- configuration.disarm = atol(disarmCode);
- configuration.admin = atol(adminCode);
- configuration.c_hour = hour;
- configuration.c_minute = minute;
- configuration.c_second = second;
- EEPROM_writeAnything(0, configuration);
- }
- /***********************************************************
- * Reads the admin code, arm code, disarm code, and timer *
- * from EEPROM memory and into local variables *
- * readConfig(); *
- ************************************************************/
- void readConfig() {
- EEPROM_readAnything(0, configuration);
- ltoa(configuration.arm, ArmCode, 10);
- ltoa(configuration.disarm,disarmCode,10);
- ltoa(configuration.admin,adminCode,10);
- hour = configuration.c_hour;
- minute = configuration.c_minute;
- second = configuration.c_second;
- }
- /***********************************************************
- * chirps a buzzer at 3 different intervals > 30 seconds *
- * < 30 seconds, and < 10 seconds *
- * beepSecondaryBuzzer() *
- ************************************************************/
- void beepSecondaryBuzzer() {
- int timeLeft = 0;//default, seconds > 30
- if(hour == 0 && minute == 0 && second <= 30 && second > 10){
- timeLeft = 1; //if less than 30 seconds but more than 10 seconds left
- }
- else if (hour == 0 && minute == 0 && second <= 10 && second > 0){
- timeLeft = 2; //if less than 10 seconds left
- }
- switch(timeLeft){
- case 0:
- currentMillis = millis();
- if (currentMillis - previousTime > 60000)//1 minute interval
- {
- previousTime = currentMillis;
- previousDelay = currentMillis;
- digitalWrite(speakerPin, HIGH);//turn on buzzer
- }
- if (currentMillis - previousDelay > 100) {//100ms chirp duration
- digitalWrite(speakerPin, LOW);//turn off buzzer
- }
- break;
- case 1:
- currentMillis = millis();
- if (currentMillis - previousTime > 2000)// 2 second interval
- {
- previousTime = currentMillis;
- previousDelay = currentMillis;
- digitalWrite(speakerPin, HIGH);//turn on buzzer
- }
- if (currentMillis - previousDelay > 100) {//100ms chirp duration
- digitalWrite(speakerPin, LOW);//turn off buzzer
- }
- break;
- case 2:
- currentMillis = millis();
- if (currentMillis - previousTime > 500)// 1/2 second interval
- {
- previousTime = currentMillis;
- previousDelay = currentMillis;
- digitalWrite(speakerPin, HIGH);//turn on buzzer
- }
- if (currentMillis - previousDelay > 100) {//100ms chirp duration
- digitalWrite(speakerPin, LOW);//turn off buzzer
- }
- break;
- }//end case statement
- }//end beepSecondaryBuzzer();
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement