Advertisement
Guest User

wizdum

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