Share Pastebin
Guest
Public paste!

Joao

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