Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <Keypad.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] = {7, 8, 9, 10}; //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=2, hour=0; // declare time variables
- int bombState=0; //0 = Ready, 1 = Armed, 2 = Disarmed, 3 = detonated
- int repeat=0;//flag to prevent repeat of getArmCode();
- int repeatDisarm=0;//flag to prevent repeat of getDisarmCode();
- int repeatBuzzer=0;//flag to prevent buzzer from running multiple times.
- int speakerPin = 5;//pin that the piezo buzzer is connected to.
- long previousTime = 0;//holds previous time in ms
- long previousDelay = 0;//holds previous time in ms since buzzer was active
- long interval = 60000;//60 second delay
- char ArmCode[] = "7355608";//code to arm the bomb
- char disarmCode[] = "1761820";//code to disarm the bomb
- char CANCEL_KEY = '*';//stores the cancel key variable.
- char notes[] = "A c A c A c E "; // a space represents a rest
- const byte length = sizeof(notes); // the number of notes
- byte beats[length] = { 1, 1, 1, 1, 1, 1, 1, 4};
- char names[] = { 'c', 'd', 'e', 'f', 'g', 'a', 'b', 'C', 'D', 'E', 'F', 'G', 'A', 'B' };
- unsigned int tones[] = { 1915, 1700, 1519, 1432, 1275, 1136, 1014, 956, 587, 659, 698, 784, 880, 988 };
- //Above is the beats the note plays for
- byte tempo = 1000;
- void setup()
- {
- Serial.begin(9600);
- clearLCD();
- backlightOn();
- pinMode(speakerPin, OUTPUT);//sets the output pin for the piezo buzzer
- }
- void loop(){
- switch (bombState) {
- /***********************************************************
- *Ready state prepares bomb, waits for arm code to be input
- *
- ************************************************************/
- case READY:
- selectLineOne();
- delay(100);
- Serial.print("Enter Code"); //Notify user of status.
- if (getArmCode() == true) {
- clearLCD();
- selectLineOne();
- delay(100);
- Serial.print("Correct");
- delay(500);
- clearLCD();
- bombState = ARMED; //Start countdown
- }//Close getArmCode(); = true
- if (getArmCode() == false) {
- clearLCD();
- selectLineOne();
- delay(100);
- Serial.print("Incorrect");//if code fails print "Incorrect"
- }// Close getArmCode(); = false.
- break;
- /**************************************************
- *Armed state. Countdown starts, waits for pushbutton to be pressed.
- *If button is pressed, wait for code from keypad.
- ***************************************************/
- case ARMED:
- {
- char disarmKey = keypad.getKey();
- if (disarmKey == '#') {
- selectLineOne();
- delay(100);
- Serial.print("Enter Code:"); //if disarm button is pressed, ask user to input code.
- if (getDisarmCode() == true) {
- clearLCD();
- selectLineOne();
- delay(100);
- Serial.print("Correct"); //if code is correct print "Correct".
- delay(500);
- clearLCD();
- bombState = DISARMED; //and set bombState to disarmed.
- break;
- } //close getDisarmCode(); = True
- if (getDisarmCode() == false) {
- clearLCD();
- selectLineOne();
- delay(100);
- Serial.print("Try Again");//if code fails, notify user
- if (second >= 15) {
- second = second - 15;
- }
- else {
- if (minute == 0 && hour == 0) {
- second=1; //detonate.
- }
- if (minute > 0) {
- second = 60 - (15 - second);
- minute = minute - 1;
- }
- if (hour > 0 && minute == 0) {
- second = 60 - (15 - second);
- minute = 59;
- hour = hour - 1 ;
- }
- }
- } //close getDisarmCode(); = false
- } //close if
- }
- countdown(); //if disarm key has not been pressed, continue countdown.
- break;
- /**************************************************************
- *DISARMED. Counter stopped, displays "bomb disarmed"
- *
- **************************************************************/
- case DISARMED:
- selectLineOne();
- delay(100);
- Serial.print("Bomb Disarmed"); //bomb has been disarmed, inform user.
- break;
- /*******************************************************
- *Detonated. activate buzzer for 8 beeps, then 1 long.
- *Print "Have A Nice Day. to LCD.
- ********************************************************/
- case DETONATED:
- if (repeatBuzzer == 0) { //make sure buzzer for loop has not already been run.
- digitalWrite(speakerPin, HIGH);//turn on buzzer
- delay(5000);//wait 5 seconds
- digitalWrite(speakerPin, LOW);//turn off buzzer
- repeatBuzzer = 1;//set flag to prevent code from looping again.
- }
- else {
- selectLineOne();
- delay(100);
- Serial.print("Have A Nice Day"); //loop message informing user of bomb detonation.
- }
- }//closes switch
- }//closes loop
- /***********************************************************
- * 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 unsigned long currentMillis = 0;
- // (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--;
- serialOutput();
- }
- }
- // 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
- //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
- }
- } //close countdown();
- /***********************************************************************
- * getArmCode(); *
- * Grabs the code to arm the bomb from the keypad. *
- * *
- ************************************************************************/
- boolean getArmCode(){
- // returns true when all PW keys are pressed in sequence
- // returns false when number of keys in pW pressed but don't exactly match the PW
- // CANCEL_KEY erases all previous digits input
- int count=0; // how many keys we have
- int matchCount=0; // how many keys match
- if(repeat == 0){
- for(count=0, matchCount=0; count < sizeof(ArmCode)-1; count++){
- char key;
- do{
- key = keypad.getKey();
- }
- while(key == '\0');
- selectLineTwo();
- Serial.print(key);
- if(key == ArmCode[count]) {
- matchCount++;
- }
- else if(key == CANCEL_KEY){
- count=0;
- matchCount=0;
- return false;
- }
- }//close for loop
- }//close repeat flag check
- // here when the same number of keys pressed as characters in the PW
- if(matchCount == count) {
- repeat=1;
- return true;
- }
- else {
- return false;
- }
- }//close getArmCode();
- /**********************************************************************
- * getDisarmCode(); *
- * Gets disarm code from keypad. *
- * *
- ***********************************************************************/
- boolean getDisarmCode(){
- // returns true when all PW keys are pressed in sequence
- // returns false when number of keys in pW pressed but don't exactly match the PW
- // CANCEL_KEY erases all previous digits input
- int count=0; // how many keys we have
- int matchCount=0; // how many keys match
- long disarmTime = millis()+7000L;//7000 instead of 15000 b/c of added delays making total 30s
- if(repeatDisarm == 0){
- for(count=0, matchCount=0; count < sizeof(disarmCode)-1; count++){
- char key;
- do{
- if(disarmTime < millis()){ //if 15 seconds have passed, bail out
- break;
- }
- key = keypad.getKey();
- }
- while(key == '\0');
- selectLineTwo();
- Serial.print(key);
- if(key == disarmCode[count]) {
- matchCount++;
- }
- else if(key == CANCEL_KEY){
- count=0;
- matchCount=0;
- return false;
- }
- if(disarmTime < millis()) {
- return false;
- break;
- }
- }// close for loop
- } //close repeat flag check
- // here when the same number of keys pressed as characters in the PW
- if(matchCount == count) {
- repeatDisarm=1;
- return true;
- }
- else {
- return false;
- }
- }//close getDisarmCode();
- /**************************************************
- *PIEZO BUZZER STUFF *
- * *
- ***************************************************/
- void playTone(int tone, int duration) {
- for (long i = 0; i < duration * 1000L; i += tone * 2) {
- digitalWrite(speakerPin, HIGH);
- delayMicroseconds(tone);
- digitalWrite(speakerPin, LOW);
- delayMicroseconds(tone);
- }
- }
- void playNote(char note, int duration) {
- // play the tone corresponding to the note name
- for (int i = 0; i < 14; i++) {
- if (names[i] == note) {
- playTone(tones[i], duration);
- }
- }
- }
- /****************************************************************
- * serialOutput(); *
- * prints the values of the timer over the serial connection *
- * and onto the LCD *
- *****************************************************************/
- void serialOutput() {
- if(bombState != DISARMED){
- backlightOn();
- //Print time on each line
- selectLineTwo();
- delay(100);
- 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
- //termination condition
- }
- if (second == 0 && minute == 0 && hour == 0) {
- clearLCD();
- backlightOn();
- bombState = DETONATED; //clear LCD and set bomb state to "detonated" when timer runs out
- }
- if (bombState == DISARMED) {
- clearLCD;
- }
- }//close serialOutput();
- /*********************************************************************
- * 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);
- }
- //END of bomb program.
Advertisement
Add Comment
Please, Sign In to add comment