Guest User

Untitled

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