Share Pastebin
Guest
Public paste!

Alexander Brevig

By: a guest | Feb 9th, 2010 | Syntax: None | Size: 16.62 KB | Hits: 25 | Expires: Never
This paste has a previous version, view the difference. Copy text to clipboard
  1. /******************************************************************************************
  2. * Airsoft C4 Prop by Joshua Burgess                                                       *
  3. * www.nightscapeairsoft.com                                                               *
  4. * joshuaburgess@gmail.com                                                                 *
  5. *******************************************************************************************/
  6. #include <Keypad.h>
  7.  
  8. //Define all the bomb states  
  9. #define ON 0
  10. #define READY 1
  11. #define ARMED 2
  12. #define DISARMED 3
  13. #define DETONATED 4
  14.  
  15. const byte ROWS = 4; //four rows
  16. const byte COLS = 3; //four columns
  17. char keys[ROWS][COLS] = {
  18.   {'1','2','3'},
  19.   {'4','5','6'},
  20.   {'7','8','9'},
  21.   {'#','0','*'}
  22. };
  23. byte rowPins[ROWS] = {5, 4, 3, 2}; //connect to the row pinouts of the keypad
  24. byte colPins[COLS] = {8, 7, 6}; //connect to the column pinouts of the keypad
  25.  
  26. Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );
  27.  
  28.  
  29.  int second=30, minute=2, hour=0; // declare time variables
  30.  int bombState=0; //1 = Ready, 2 = Armed, 3 = Disarmed, 4 = detonated
  31.  int repeat=0;//flag to prevent repeat of getArmCode();
  32.  int repeatDisarm=0;//flag to prevent repeat of getDisarmCode();
  33.  int repeatBuzzer=0;//flag to prevent buzzer from running multiple times.
  34.  int tether = 2;//pin that contains the tether.
  35.  int disarmPin = 3;//pin that the red pushbutton is plugged into.
  36.  int speakerPin = 5;//pin that the piezo buzzer is connected to.
  37.  int pinStatus = 0;//stores value of the tether pin.
  38.  int disarmPinStatus = 0;//stores value of the disarm pin.
  39.  
  40.  char ArmCode[] = "7355608";//code to arm the bomb
  41.  char disarmCode[] = "1234567";//code to disarm the bomb
  42.  char CANCEL_KEY = '*';//stores the cancel key variable.
  43.  
  44.  
  45.  char notes[] = "A c A c A c E "; // a space represents a rest
  46.  const byte length = sizeof(notes); // the number of notes
  47.  byte beats[length] = { 1, 1, 1, 1, 1, 1, 1, 4};
  48.  char names[] = { 'c', 'd', 'e', 'f', 'g', 'a', 'b', 'C', 'D', 'E', 'F', 'G', 'A', 'B' };
  49.  unsigned int tones[] = { 1915, 1700, 1519, 1432, 1275, 1136, 1014, 956, 587, 659, 698, 784, 880, 988 };
  50.  
  51. //Above is the beats the note plays for
  52.  byte tempo = 1000;
  53.  
  54.  void setup()
  55. {
  56.   Serial.begin(9600);
  57.   kpd.init();
  58.   clearLCD();
  59.   backlightOn();
  60.   pinMode(disarmPin, INPUT);//sets the input pin for the pushbutton.
  61.   pinMode(speakerPin, OUTPUT);//sets the output pin for the piezo buzzer
  62. }
  63.  
  64.  void loop(){
  65.   switch (bombState) {
  66. /*****************************************************
  67. *Initial bomb state, waiting for teather.
  68. *
  69. *******************************************************/
  70.   case ON:
  71.    
  72.   pinStatus = digitalRead(tether);
  73.   if (pinStatus == HIGH) {
  74.       selectLineOne();
  75.       delay(100);
  76.       Serial.print("Attach Tether");
  77.   }
  78.   else {
  79.       bombState = READY;
  80.       delay(500);
  81.   }
  82.     break;
  83.    
  84. /***********************************************************
  85. *Ready state prepares bomb, waits for arm code to be input
  86. *
  87. ************************************************************/
  88.   case READY:
  89.  
  90.   clearLCD();
  91.   selectLineOne();
  92.   delay(100);
  93.   Serial.print("Enter Code"); //Notify user of status.
  94.  
  95.    if (getArmCode() == true) {
  96.      
  97.        //Make sure tether hasn't been removed
  98.        pinStatus = digitalRead(tether);
  99.        if (pinStatus == HIGH) { //if the tether has been removed,
  100.             selectLineOne();
  101.             delay(100);
  102.             Serial.print("Tether Removed"); //make it known
  103.             delay(1000);
  104.             clearLCD();
  105.             bombState = DETONATED; //and set off bomb.
  106.        }
  107.        
  108.        else { //if the tether is still connected, print "correct".
  109.            clearLCD();
  110.            selectLineOne();
  111.            delay(100);
  112.            Serial.print("Correct");
  113.            delay(500);
  114.            clearLCD();
  115.            bombState = ARMED; //Start countdown
  116.        }
  117.   }//Close getArmCode(); = true
  118.  
  119.  if (getArmCode() == false) {
  120.    
  121.        //Make sure tether hasn't been removed
  122.        pinStatus = digitalRead(tether);
  123.        if (pinStatus == HIGH) { //if the tether has been removed,
  124.            selectLineOne();
  125.            delay(100);
  126.            Serial.print("Tether Removed"); //make it known
  127.            delay(1000);
  128.            clearLCD();
  129.            bombState = DETONATED; //and set off bomb.
  130.        }
  131.    
  132.        else {
  133.            clearLCD();
  134.            selectLineOne();
  135.            delay(100);
  136.            Serial.print("Incorrect");//if code fails, and tether is connected, print "Incorrect"
  137.        }
  138.  }// Close getArmCode(); = false.
  139.  
  140.   break;
  141.    
  142. /**************************************************
  143. *Armed state. Countdown starts, waits for pushbutton to be pressed.
  144. *If button is pressed, wait for code from keypad.
  145. ***************************************************/
  146.  
  147.   case ARMED:
  148.  
  149.   disarmPinStatus = digitalRead(disarmPin);
  150.   if (disarmPinStatus == LOW) {
  151.        selectLineOne();
  152.        delay(100);
  153.        Serial.print("Enter Code:"); //if disarm button is pressed, ask user to input code.
  154.    
  155.        if (getDisarmCode() == true) {
  156.    
  157.             //Make sure tether hasn't been removed
  158.             pinStatus = digitalRead(tether);
  159.            
  160.             if (pinStatus == HIGH) { //if the tether has been removed,
  161.                 selectLineOne();
  162.                 delay(100);
  163.                 Serial.print("Tether Removed"); //make it known
  164.                 delay(1000);
  165.                 clearLCD();
  166.                 bombState = DETONATED; //and set off bomb.
  167.             }
  168.  
  169.             else {    
  170.                 clearLCD();
  171.                 selectLineOne();
  172.                 delay(100);
  173.                 Serial.print("Correct"); //if code is correct, and tether is connected, print "Correct".
  174.                 delay(500);
  175.                 clearLCD();
  176.                 bombState = DISARMED; //and set bombState to disarmed.
  177.                 break;
  178.             }
  179.       } //close getDisarmCode(); = True
  180.  
  181.       if (getDisarmCode() == false) {
  182.    
  183.       //Make sure tether hasn't been removed
  184.       pinStatus = digitalRead(tether);
  185.          
  186.           if (pinStatus == HIGH) { //if the tether has been removed,
  187.               selectLineOne();
  188.               delay(100);
  189.               Serial.print("Tether Removed"); //make it known
  190.               delay(1000);
  191.               clearLCD();
  192.               bombState = DETONATED; //and set off bomb.
  193.           }
  194.    
  195.           else {
  196.               clearLCD();
  197.               selectLineOne();
  198.               delay(100);
  199.               Serial.print("Try Again");//if code fails, notify user
  200.               //second = 1; //and remove all the remaining seconds.
  201.          
  202.               if (second > 15) {
  203.                 second = second - 15;
  204.              }
  205.          
  206.               else {
  207.                   second=1;// erase seconds from count after button press.
  208.               }
  209.           }    
  210.    } //close getDisarmCode(); = false
  211.      
  212.      
  213.   } //close disarmPinStatus(); = true
  214.  
  215.   else {
  216.       countdown(); //if disarmpin has not been pressed, continue countdown.
  217.   }
  218.  
  219.   break;
  220.  
  221. /**************************************************************
  222. *DISARMED. Counter stopped, displays "bomb disarmed"
  223. *
  224. **************************************************************/
  225.  
  226.  case DISARMED:
  227.  
  228.     selectLineOne();
  229.     delay(100);
  230.     Serial.print("Bomb Disarmed"); //bomb has been disarmed, inform user.
  231.     break;
  232.  
  233. /*******************************************************
  234. *Detonated. activate buzzer for 8 beeps, then 1 long.
  235. *Print "Have A Nice Day. to LCD.
  236. ********************************************************/
  237.  
  238.  case DETONATED:
  239.  
  240.   if (repeatBuzzer == 0) { //make sure buzzer for loop has not already been run.
  241.  
  242.        for (int i = 0; i < length; i++) {
  243.            if (notes[i] == ' ') {
  244.                delay(beats[i] * tempo); // rest
  245.            }
  246.        
  247.            else {
  248.                 playNote(notes[i], beats[i] * tempo);
  249.            }
  250.      
  251.            // pause between notes
  252.            delay(tempo / 2);
  253.            repeatBuzzer = 1; //set flag to prevent code from looping again.
  254.         }//clos for loop
  255.   }//close repeatBuzzer.
  256.  
  257.   else {
  258.       selectLineOne();
  259.       delay(100);
  260.       Serial.print("Have A Nice Day"); //loop message informing user of bomb detonation.
  261.   }
  262.  
  263.   }//closes switch
  264. }//closes loop
  265.  
  266.  
  267. /***********************************************************
  268. * Main countdown timer                                     *
  269. *                 countdown()                              *
  270. ************************************************************/
  271.  void countdown(){
  272.  
  273.     //Make sure tether hasn't been removed
  274.     pinStatus = digitalRead(tether);
  275.    
  276.        if (pinStatus == HIGH) { //if the tether has been removed,
  277.            selectLineOne();
  278.            delay(100);
  279.            Serial.print("Tether Removed"); //make it known
  280.            delay(1000);
  281.            clearLCD();
  282.            bombState = DETONATED; //and set off bomb.
  283.       }
  284.  
  285.   static unsigned long lastTick = 0; // set up a local variable to hold the last time we decremented one second
  286. // (static variables are initialized once and keep their values between function calls)
  287.  
  288. // decrement one second every 1000 milliseconds
  289.   if (second > 0) {
  290.       if (millis() - lastTick >= 1000) {
  291.           lastTick = millis();
  292.           second--;
  293.           serialOutput();
  294.       }
  295.   }
  296.  
  297.  // decrement one minute every 60 seconds
  298.   if (minute > 0) {
  299.       if (second <= 0) {
  300.           minute--;
  301.           second = 60; // reset seconds to 60
  302.       }
  303.   }
  304.  
  305. // decrement one hour every 60 minutes
  306.   if (hour > 0) {
  307.       if (minute <= 0) {
  308.           hour--;
  309.           minute = 60; // reset minutes to 60
  310.       }//closes if
  311.   }//closes if
  312.  
  313. } //close countdown();
  314.  
  315.  
  316. /***********************************************************************
  317. *                          getArmCode();                               *
  318. *  Grabs the code to arm the bomb from the keypad.                     *
  319. *                                                                      *
  320. ************************************************************************/
  321.  boolean getArmCode(){
  322.   // returns true when all PW keys are pressed in sequence
  323.   // returns false when number of keys in pW pressed but don't exactly match the PW
  324.   // CANCEL_KEY erases all previous digits input
  325.   int count=0;  // how many keys we have
  326.   int matchCount=0;  // how many keys match
  327.  
  328.   if(repeat == 0){
  329.  
  330.       for(count=0, matchCount=0; count < sizeof(ArmCode)-1; count++){
  331.           char key;
  332.          
  333.           do{
  334.               key = kpd.getKey();
  335.           }
  336.           while(key == '\0');
  337.          
  338.           if(key == ArmCode[count]) {
  339.               matchCount++;
  340.           }
  341.          
  342.           else if(key == CANCEL_KEY){
  343.               count=0;
  344.               matchCount=0;
  345.               loop();
  346.           }
  347.       }//close for loop
  348.   }//close repeat flag check
  349.  
  350. // here when the same number of keys pressed as characters in the PW
  351.   if(matchCount == count) {
  352.       repeat=1;
  353.       return true;
  354.   }
  355.  
  356.   else {
  357.       return false;
  358.  
  359.   }
  360. }//close getArmCode();
  361.  
  362.  
  363. /**********************************************************************
  364. *                   getDisarmCode();                                  *
  365. *    Gets disarm code from keypad.                                    *
  366. *                                                                     *
  367. ***********************************************************************/
  368.  boolean getDisarmCode(){
  369.  
  370. // returns true when all PW keys are pressed in sequence
  371. // returns false when number of keys in pW pressed but don't exactly match the PW
  372. // CANCEL_KEY erases all previous digits input
  373.  
  374.   int count=0;  // how many keys we have
  375.   int matchCount=0;  // how many keys match
  376.   long disarmTime = millis()+7000L;//7000 instead of 15000 b/c of added delays making total 30s
  377.  
  378.   if(repeatDisarm == 0){
  379.  
  380.       for(count=0, matchCount=0; count < sizeof(disarmCode)-1; count++){
  381.           char key;
  382.           do{
  383.                if(disarmTime < millis()){ //if 15 seconds have passed, bail out
  384.               //count=sizeof(disarmCode)+1;
  385.               break;
  386.               }
  387.              
  388.             key = kpd.getKey();        
  389.           }
  390.           while(key == '\0');
  391.    
  392.           if(key == disarmCode[count]) {
  393.               matchCount++;
  394.           }
  395.    
  396.           else if(key == CANCEL_KEY){
  397.               count=0;
  398.               matchCount=0;
  399.               //loop();
  400.           }
  401.  
  402.           if(disarmTime < millis()) {
  403.               //count = 9999; //ensure count != matchcount.
  404.               return false;
  405.               break;
  406.           }
  407.  
  408.      }// close for loop
  409.   } //close repeat flag check
  410.  
  411. // here when the same number of keys pressed as characters in the PW
  412.   if(matchCount == count) {
  413.       repeatDisarm=1;
  414.       return true;
  415.   }
  416.   else {
  417.       return false;
  418.  
  419.   }
  420. }//close getDisarmCode();
  421.  
  422. /**************************************************
  423. *PIEZO BUZZER STUFF                               *
  424. *                                                 *
  425. ***************************************************/
  426.  
  427.  void playTone(int tone, int duration) {
  428.   for (long i = 0; i < duration * 1000L; i += tone * 2) {
  429.     digitalWrite(speakerPin, HIGH);
  430.     delayMicroseconds(tone);
  431.     digitalWrite(speakerPin, LOW);
  432.     delayMicroseconds(tone);
  433.   }
  434. }
  435.  
  436.  void playNote(char note, int duration) {
  437.  
  438.   // play the tone corresponding to the note name
  439.   for (int i = 0; i < 14; i++) {
  440.     if (names[i] == note) {
  441.         playTone(tones[i], duration);
  442.     }
  443.   }
  444. }
  445.  
  446.  
  447. /****************************************************************
  448. *                     serialOutput();                           *
  449. *    prints the values of the timer over the serial connection  *
  450. *         and onto the LCD                                      *
  451. *****************************************************************/
  452.  void serialOutput() {
  453. //clearLCD();
  454.   backlightOn();
  455. //Print time on each line
  456.   selectLineTwo();
  457.   delay(100);
  458.   Serial.print("ARMED : ");
  459.   Serial.print(hour, DEC); // the hour, sent to the screen in decimal format
  460.   Serial.print(":"); // a colon between the hour and the minute
  461.   Serial.print(minute, DEC); // the minute, sent to the screen in decimal format
  462.   Serial.print(":"); // a colon between the minute and the second
  463.   Serial.println(second, DEC); // the second, sent to the screen in decimal format
  464. //termination condition
  465.   if (second == 0 && minute == 0 && hour == 0) {
  466.       clearLCD();
  467.       backlightOn();
  468.       bombState = DETONATED; //clear LCD and set bomb state to "detonated" when timer runs out
  469.   }
  470. }//close serialOutput();
  471.  
  472.  
  473. /*********************************************************************
  474. *       Serial LCD disagnostic and general use tools                 *
  475. *   selectLineOne(); | selectLineTwo(); | goTo(); | clearLCD();      *
  476. *      backlightOn(); | backlightOff(); | serCommand();             *
  477. **********************************************************************/
  478.  void selectLineOne(){  //puts the cursor at line 0 char 0.
  479.    Serial.print(0xFE, BYTE);   //command flag
  480.    Serial.print(128, BYTE);    //position
  481. }
  482.  void selectLineTwo(){  //puts the cursor at line 0 char 0.
  483.    Serial.print(0xFE, BYTE);   //command flag
  484.    Serial.print(192, BYTE);    //position
  485. }
  486.  void goTo(int position) { //position = line 1: 0-15, line 2: 16-31, 31+ defaults back to 0
  487.  if (position<16){ Serial.print(0xFE, BYTE);   //command flag
  488.               Serial.print((position+128), BYTE);    //position
  489. }else if (position<32){Serial.print(0xFE, BYTE);   //command flag
  490.               Serial.print((position+48+128), BYTE);    //position
  491. } else { goTo(0); }
  492. }
  493.  
  494.  void clearLCD(){
  495.    Serial.print(0xFE, BYTE);   //command flag
  496.    Serial.print(0x01, BYTE);   //clear command.
  497. }
  498.  void backlightOn(){  //turns on the backlight
  499.     Serial.print(0x7C, BYTE);   //command flag for backlight stuff
  500.     Serial.print(157, BYTE);    //light level.
  501. }
  502.  void backlightOff(){  //turns off the backlight
  503.     Serial.print(0x7C, BYTE);   //command flag for backlight stuff
  504.     Serial.print(128, BYTE);     //light level for off.
  505. }
  506.  void serCommand(){   //a general function to call the command flag for issuing all other commands  
  507.   Serial.print(0xFE, BYTE);
  508. }
  509.  
  510. //END of bomb program.
  511.  
  512. errors:
  513. In function 'void setup()':
  514. error: redefinition of 'void setup()' In function 'void loop()':
  515.  In function 'void countdown()':
  516.  In function 'boolean getArmCode()':
  517.  In function 'boolean getDisarmCode()':
  518.  In function 'void serialOutput()':