Guest User

Arduino C4 prop

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