Mbed based laser tag system using IR LEDs and receivers

Dependencies:   mbed fwdcrc16library PinDetect TextLCD

This project was the result of an embedded systems design course held in 2013.

Committer:
Mike951
Date:
Thu Aug 15 18:48:47 2019 +0000
Revision:
5:6e6ab7e5074e
Parent:
4:7294c20b1025
Finished and tested IR Laser Tag project

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Mike951 5:6e6ab7e5074e 1 //////////////////////////////////////////
Mike951 5:6e6ab7e5074e 2 //Embedded Systems Design Final Project //
Mike951 5:6e6ab7e5074e 3 //Robert Michael Swan //
Mike951 5:6e6ab7e5074e 4 //March 21, 2013 //
Mike951 5:6e6ab7e5074e 5 // //
Mike951 5:6e6ab7e5074e 6 //Compiled Code Size: 17.7KB //
Mike951 5:6e6ab7e5074e 7 //////////////////////////////////////////
Mike951 5:6e6ab7e5074e 8 //Libraries Used
Mike951 0:69e5ee3b618d 9 #include "mbed.h"
Mike951 0:69e5ee3b618d 10 #include "TextLCD.h"
Mike951 0:69e5ee3b618d 11 #include "PinDetect.h"
Mike951 0:69e5ee3b618d 12 #include "crc16.h"
Mike951 5:6e6ab7e5074e 13 //Peripherals
Mike951 1:24f46931d010 14 PinDetect sw2(P0_11); //switch2 debounced input
Mike951 1:24f46931d010 15 PinDetect sw3(P0_10); //switch3 debounced input
Mike951 0:69e5ee3b618d 16 TextLCD lcd(P1_15, P1_16, P1_19, P1_20, P1_21, P1_22); // rs, e, d4-d7 led pins:4,6,11-14
Mike951 0:69e5ee3b618d 17 DigitalOut LB(P1_31); //lcd backlight
Mike951 0:69e5ee3b618d 18 DigitalOut LP(P1_29); //lcd power
Mike951 0:69e5ee3b618d 19 DigitalOut led1(P0_22); //on-board led ds1
Mike951 0:69e5ee3b618d 20 DigitalOut led2(P0_23); //on-board led ds2
Mike951 2:15134f79b400 21 Serial IR(P1_27,P1_26); //IR transmitter and receiver output and input control P1_27 controls IR diode, P1_26 controls IR reciever
Mike951 0:69e5ee3b618d 22 PwmOut Square_Gen(P1_25); //square wave generator for IR led
Mike951 5:6e6ab7e5074e 23 //Timers
Mike951 1:24f46931d010 24 Timeout stats; //used for displaying text for limited periods of time
Mike951 2:15134f79b400 25 Timeout shot_time; //used to ensure shots take place in a brief period of time
Mike951 2:15134f79b400 26 Timeout flash; //used to flash leds and backlight when shooting or tagging
Mike951 2:15134f79b400 27 Timer timer; //used as seconds for reset timer
Mike951 1:24f46931d010 28 Ticker clock_tick; //used with timer for minutes of reset timer
Mike951 5:6e6ab7e5074e 29 //Required global variables
Mike951 1:24f46931d010 30 unsigned mins = 0; //global variable for minutes in game, since ticker interrupt cannot attach functions that have parameters
Mike951 1:24f46931d010 31 bool btn2 = false; //global variable for sw2, since the PinDetect interrupt cannot attach functions that have parameters
Mike951 1:24f46931d010 32 bool btn3 = false; //global variable for sw3, since the PinDetect interrupt cannot attach functions that have parameters
Mike951 2:15134f79b400 33 bool done = false; //global variable for timeout, since TimeOut interrupt cannot attach functions that have parameters
Mike951 2:15134f79b400 34 bool taggable = false; //global variable for whether serial received input will be used or not
Mike951 4:7294c20b1025 35 volatile bool tagged = false; //global variable for whether tag is complete
Mike951 2:15134f79b400 36 char id_rx[15]; //global variable for received ID. Required to use serial interrupt correctly
Mike951 2:15134f79b400 37 unsigned id_pos = 0; //global variable for recieved ID array location. Also required for serial interrupt.
Mike951 0:69e5ee3b618d 38
Mike951 5:6e6ab7e5074e 39 //Functions
Mike951 4:7294c20b1025 40 /*Minute Interrupt
Mike951 4:7294c20b1025 41 Intended to be called every minute to increment the minute counter.
Mike951 4:7294c20b1025 42 Also resets the seconds timer as it reaches 60 seconds (assuming it is called at timer.start();)
Mike951 4:7294c20b1025 43 */
Mike951 1:24f46931d010 44 void minutes()
Mike951 1:24f46931d010 45 {
Mike951 1:24f46931d010 46 mins ++;
Mike951 1:24f46931d010 47 timer.reset();
Mike951 1:24f46931d010 48 }
Mike951 1:24f46931d010 49
Mike951 2:15134f79b400 50 /* Flashing interrupt
Mike951 2:15134f79b400 51 Intended to be used with a timeout object to flash lights when shot or shooting
Mike951 2:15134f79b400 52 */
Mike951 2:15134f79b400 53 void flasher()
Mike951 2:15134f79b400 54 {
Mike951 2:15134f79b400 55 LB = 0;
Mike951 2:15134f79b400 56 led1 = !led1;
Mike951 2:15134f79b400 57 led2 = !led2;
Mike951 2:15134f79b400 58 }
Mike951 2:15134f79b400 59
Mike951 4:7294c20b1025 60 /*Shot Check/Reset Interrupt
Mike951 4:7294c20b1025 61 Intended to be called after a short period of time to start array over from the start
Mike951 4:7294c20b1025 62 Should keep data from being received over an excessive amount of time and thus is one
Mike951 4:7294c20b1025 63 method of ensuring player is actually tagged
Mike951 4:7294c20b1025 64 */
Mike951 4:7294c20b1025 65 void shot_check()
Mike951 4:7294c20b1025 66 {
Mike951 4:7294c20b1025 67 id_pos = 0; //resets current id
Mike951 4:7294c20b1025 68 }
Mike951 4:7294c20b1025 69
Mike951 4:7294c20b1025 70 /*Serial Callback interrupt
Mike951 4:7294c20b1025 71 Receives IR information using IR receiver
Mike951 4:7294c20b1025 72 If taggable = false, received data is thrown away.
Mike951 4:7294c20b1025 73 Otherwise, up to 15 characters are collected in a time period of 0.5 seconds
Mike951 4:7294c20b1025 74 If less than 15 characters received in 0.5 seconds, function array returns to first bit
Mike951 4:7294c20b1025 75 */
Mike951 0:69e5ee3b618d 76 void callback()
Mike951 0:69e5ee3b618d 77 {
Mike951 2:15134f79b400 78 // Note: you need to actually read from the serial buffer to clear the RX interrupt
Mike951 2:15134f79b400 79 if (!taggable)
Mike951 2:15134f79b400 80 {
Mike951 2:15134f79b400 81 IR.getc(); //ensures no extra buffering left over when player is not taggable
Mike951 2:15134f79b400 82 return;
Mike951 2:15134f79b400 83 }
Mike951 2:15134f79b400 84
Mike951 2:15134f79b400 85 id_rx[id_pos] = IR.getc(); //place received character into array
Mike951 4:7294c20b1025 86 /*if (id_pos == 0) //starts a timer for the time in which receiver must receive a full id
Mike951 0:69e5ee3b618d 87 {
Mike951 2:15134f79b400 88 shot_time.attach(&shot_check, 0.5);
Mike951 4:7294c20b1025 89 }*/
Mike951 4:7294c20b1025 90 if(id_pos >= 14)
Mike951 0:69e5ee3b618d 91 {
Mike951 2:15134f79b400 92 id_pos = 0; //ensures no array overflows
Mike951 2:15134f79b400 93 shot_time.detach(); //ensures no further action upon array until next time tagged
Mike951 5:6e6ab7e5074e 94 tagged = true; //changes tagged flag such that the main code will trigger after an ID is fully received
Mike951 4:7294c20b1025 95 return;
Mike951 0:69e5ee3b618d 96 }
Mike951 2:15134f79b400 97 id_pos ++; //increment to next array position for id
Mike951 2:15134f79b400 98 return;
Mike951 0:69e5ee3b618d 99 }
Mike951 0:69e5ee3b618d 100
Mike951 4:7294c20b1025 101 /*Button 2 Interrupt
Mike951 4:7294c20b1025 102 Sets button variable to true for use in code when button is pressed
Mike951 4:7294c20b1025 103 */
Mike951 1:24f46931d010 104 void btn2Pressed()
Mike951 0:69e5ee3b618d 105 {
Mike951 0:69e5ee3b618d 106 led1 = !led1;
Mike951 1:24f46931d010 107 btn2 = true;
Mike951 0:69e5ee3b618d 108 }
Mike951 0:69e5ee3b618d 109
Mike951 4:7294c20b1025 110 /*Button 3 Interrupt
Mike951 4:7294c20b1025 111 Sets button variable to true for use in code when button is pressed
Mike951 4:7294c20b1025 112 */
Mike951 1:24f46931d010 113 void btn3Pressed()
Mike951 0:69e5ee3b618d 114 {
Mike951 0:69e5ee3b618d 115 led2 = !led2;
Mike951 1:24f46931d010 116 btn3 = true;
Mike951 0:69e5ee3b618d 117
Mike951 0:69e5ee3b618d 118 }
Mike951 0:69e5ee3b618d 119
Mike951 5:6e6ab7e5074e 120 /*Statistics Display Timeout
Mike951 5:6e6ab7e5074e 121 Sets display "done" flag to true
Mike951 5:6e6ab7e5074e 122 Intended to be used with timeout interrupt and statistics function to jump out of function
Mike951 5:6e6ab7e5074e 123 if it has been 5 seconds.
Mike951 5:6e6ab7e5074e 124 */
Mike951 1:24f46931d010 125 void finish_disp ()
Mike951 0:69e5ee3b618d 126 {
Mike951 0:69e5ee3b618d 127 done = true;
Mike951 0:69e5ee3b618d 128 return;
Mike951 0:69e5ee3b618d 129 }
Mike951 0:69e5ee3b618d 130
Mike951 1:24f46931d010 131 /*Error Routine.
Mike951 1:24f46931d010 132 Displays "ERROR" on LCD screen and flashes leds
Mike951 5:6e6ab7e5074e 133 for an indefinite period of time.
Mike951 1:24f46931d010 134 */
Mike951 1:24f46931d010 135 void error_custom ()
Mike951 1:24f46931d010 136 {
Mike951 1:24f46931d010 137 lcd.cls();
Mike951 1:24f46931d010 138 lcd.printf("ERROR");
Mike951 1:24f46931d010 139 led1 = 0;
Mike951 1:24f46931d010 140 led2 = 1;
Mike951 1:24f46931d010 141 while(1)
Mike951 1:24f46931d010 142 {
Mike951 1:24f46931d010 143 led1 = !led1;
Mike951 1:24f46931d010 144 led2 = !led2;
Mike951 1:24f46931d010 145 wait(0.5);
Mike951 1:24f46931d010 146 }
Mike951 1:24f46931d010 147 }
Mike951 1:24f46931d010 148 /*Alphanumeric selector
Mike951 1:24f46931d010 149 Used with char_sel function in order to select a number 0-9 or letters A-Z through user input.
Mike951 1:24f46931d010 150 Returns a char.
Mike951 1:24f46931d010 151 */
Mike951 1:24f46931d010 152 char alpha_num_sel (bool number)
Mike951 1:24f46931d010 153 {
Mike951 1:24f46931d010 154 char n0 = '0';
Mike951 1:24f46931d010 155 char n_tmp = '0';
Mike951 1:24f46931d010 156 unsigned incr = 0; //used to increment characters between 0-9 or A-Z
Mike951 1:24f46931d010 157 unsigned mod;
Mike951 1:24f46931d010 158 if (number)
Mike951 1:24f46931d010 159 {
Mike951 1:24f46931d010 160 lcd.cls();
Mike951 1:24f46931d010 161 lcd.printf("Pick\nNumber:%c",n_tmp);
Mike951 1:24f46931d010 162 n0 = '0';
Mike951 1:24f46931d010 163 n_tmp = n0;
Mike951 2:15134f79b400 164 mod = 11; //modulus for character range
Mike951 1:24f46931d010 165 }
Mike951 1:24f46931d010 166 else
Mike951 1:24f46931d010 167 {
Mike951 1:24f46931d010 168 lcd.cls();
Mike951 1:24f46931d010 169 n0 = 'A';
Mike951 1:24f46931d010 170 n_tmp = n0;
Mike951 1:24f46931d010 171 lcd.printf("Pick\nLetter:%c",n_tmp);
Mike951 1:24f46931d010 172 mod = 26;
Mike951 1:24f46931d010 173 }
Mike951 1:24f46931d010 174 while(1)
Mike951 1:24f46931d010 175 {
Mike951 1:24f46931d010 176 while(!btn2 && !btn3) //waits until button input received
Mike951 1:24f46931d010 177 {
Mike951 1:24f46931d010 178 wait(0.05);
Mike951 1:24f46931d010 179 }
Mike951 1:24f46931d010 180 if(btn3)
Mike951 1:24f46931d010 181 {
Mike951 1:24f46931d010 182 btn3 = false;
Mike951 1:24f46931d010 183 btn2 = false; //if both butons pressed, it just selects the current character
Mike951 1:24f46931d010 184 return (n_tmp);
Mike951 1:24f46931d010 185 }
Mike951 1:24f46931d010 186 else if(btn2)
Mike951 1:24f46931d010 187 {
Mike951 1:24f46931d010 188 btn2 = false;
Mike951 1:24f46931d010 189 incr ++;
Mike951 2:15134f79b400 190 incr = incr % mod; //ensures that numbers stay within the 0-9/A-Z range
Mike951 2:15134f79b400 191 n_tmp = n0 + incr; //increment current character selected
Mike951 2:15134f79b400 192 if (incr == 10 && number) //feature addition to allow for space entry
Mike951 2:15134f79b400 193 {
Mike951 2:15134f79b400 194 n_tmp = ' ';
Mike951 2:15134f79b400 195 }
Mike951 1:24f46931d010 196 lcd.cls();
Mike951 1:24f46931d010 197 if(number)
Mike951 1:24f46931d010 198 {
Mike951 1:24f46931d010 199 lcd.printf("Pick\nNumber:%c",n_tmp); //displays current number
Mike951 1:24f46931d010 200 }
Mike951 1:24f46931d010 201 else
Mike951 1:24f46931d010 202 {
Mike951 1:24f46931d010 203 lcd.printf("Pick\nLetter:%c",n_tmp); //displays current letter
Mike951 1:24f46931d010 204 }
Mike951 1:24f46931d010 205 }
Mike951 1:24f46931d010 206 else
Mike951 1:24f46931d010 207 {
Mike951 1:24f46931d010 208 error_custom();
Mike951 1:24f46931d010 209 }
Mike951 1:24f46931d010 210
Mike951 1:24f46931d010 211 }
Mike951 1:24f46931d010 212 }
Mike951 5:6e6ab7e5074e 213
Mike951 1:24f46931d010 214 /*Character Selection
Mike951 1:24f46931d010 215 Used with setup() function in order to pick a character A-Z and number 0-9
Mike951 1:24f46931d010 216 for use as part of user id and/or team. Passed a 0 if selecting team letter (A-Z),
Mike951 1:24f46931d010 217 otherwise will select player id letter
Mike951 1:24f46931d010 218 */
Mike951 1:24f46931d010 219 char char_sel (bool player)
Mike951 1:24f46931d010 220 {
Mike951 1:24f46931d010 221 if (player)
Mike951 1:24f46931d010 222 {
Mike951 1:24f46931d010 223 lcd.cls();
Mike951 1:24f46931d010 224 lcd.printf("A-Z? or\n0-9?");
Mike951 1:24f46931d010 225 while(!btn2 && !btn3) //waits until button input received
Mike951 1:24f46931d010 226 {
Mike951 1:24f46931d010 227 wait(0.05);
Mike951 1:24f46931d010 228 }
Mike951 1:24f46931d010 229 if(btn2) //if select button pressed, goes through numerical selection
Mike951 1:24f46931d010 230 {
Mike951 1:24f46931d010 231 btn2 = false;
Mike951 1:24f46931d010 232 btn3 = false; //if both buttons pressed at the same time, it just does numerical selection
Mike951 1:24f46931d010 233
Mike951 1:24f46931d010 234 return(alpha_num_sel(1));
Mike951 1:24f46931d010 235 }
Mike951 1:24f46931d010 236 else if(btn3)
Mike951 1:24f46931d010 237 {
Mike951 1:24f46931d010 238 btn3 = false; //pressing the option button in this case is the same as selecting a team
Mike951 1:24f46931d010 239 }
Mike951 1:24f46931d010 240 else
Mike951 1:24f46931d010 241 {
Mike951 1:24f46931d010 242 error_custom(); //if you somehow make it here without pressing buttons, it will throw an error
Mike951 1:24f46931d010 243 }
Mike951 1:24f46931d010 244 }
Mike951 1:24f46931d010 245 return(alpha_num_sel(0)); //returns capital alpha character for id or team by calling selection function
Mike951 1:24f46931d010 246 }
Mike951 1:24f46931d010 247
Mike951 1:24f46931d010 248
Mike951 1:24f46931d010 249 /*Setup Routine.
Mike951 1:24f46931d010 250 Sets the user id for use in-game.
Mike951 1:24f46931d010 251 Function must be passed an array of characters of size 15
Mike951 1:24f46931d010 252 in order to work correctly.
Mike951 1:24f46931d010 253 */
Mike951 1:24f46931d010 254 void setup (char* ID_array)
Mike951 1:24f46931d010 255 {
Mike951 1:24f46931d010 256 unsigned size = 1;
Mike951 1:24f46931d010 257
Mike951 1:24f46931d010 258 lcd.cls();
Mike951 1:24f46931d010 259 lcd.printf("ID Size?\n%u",size);
Mike951 4:7294c20b1025 260
Mike951 1:24f46931d010 261 while(1)
Mike951 1:24f46931d010 262 {
Mike951 1:24f46931d010 263 while(!btn2 && !btn3) //waits until button input received
Mike951 1:24f46931d010 264 {
Mike951 1:24f46931d010 265 wait(0.05); //ensures buttons cannot be pressed extremely fast
Mike951 1:24f46931d010 266 }
Mike951 1:24f46931d010 267 if(btn2 && btn3) //routine to set size of player id in bytes
Mike951 1:24f46931d010 268 {
Mike951 1:24f46931d010 269 btn2 = false; //handling for simultaneous button pressing
Mike951 1:24f46931d010 270 btn3 = false;
Mike951 1:24f46931d010 271 size++;
Mike951 1:24f46931d010 272 if (size > 12)
Mike951 1:24f46931d010 273 {
Mike951 1:24f46931d010 274 size = 1; //ensures size cannot be greater than 12 or less than 1
Mike951 1:24f46931d010 275 }
Mike951 1:24f46931d010 276 break; //sets size to whatever current size is +1 and moves on
Mike951 1:24f46931d010 277 }
Mike951 1:24f46931d010 278 else if(btn2) //increases size or loops back to 1, displays current size
Mike951 1:24f46931d010 279 {
Mike951 1:24f46931d010 280 btn2 = false;
Mike951 1:24f46931d010 281 size++;
Mike951 1:24f46931d010 282 if (size > 12)
Mike951 1:24f46931d010 283 {
Mike951 1:24f46931d010 284 size = 1; //ensures size cannot be greater than 12 or less than 1
Mike951 1:24f46931d010 285 }
Mike951 1:24f46931d010 286 lcd.cls();
Mike951 1:24f46931d010 287 lcd.printf("ID Size?\n%u",size); //displays current size
Mike951 1:24f46931d010 288 }
Mike951 1:24f46931d010 289 else if(btn3)
Mike951 1:24f46931d010 290 {
Mike951 1:24f46931d010 291 btn3 = false; //selects current size
Mike951 1:24f46931d010 292 break;
Mike951 1:24f46931d010 293 }
Mike951 1:24f46931d010 294 else
Mike951 1:24f46931d010 295 {
Mike951 1:24f46931d010 296 error_custom(); //error called if unexpected output
Mike951 1:24f46931d010 297 }
Mike951 1:24f46931d010 298 }
Mike951 1:24f46931d010 299
Mike951 1:24f46931d010 300 for (unsigned j = 0; j < size; j ++) //sets player id
Mike951 1:24f46931d010 301 {
Mike951 1:24f46931d010 302 ID_array[j] = char_sel(1);
Mike951 1:24f46931d010 303 }
Mike951 1:24f46931d010 304 for (unsigned j = size; j < 12; j ++)
Mike951 1:24f46931d010 305 {
Mike951 1:24f46931d010 306 ID_array[j] = ' '; //fill unused characters with spaces
Mike951 1:24f46931d010 307 }
Mike951 4:7294c20b1025 308
Mike951 1:24f46931d010 309 lcd.cls();
Mike951 1:24f46931d010 310 lcd.printf("On team?\n Y or N");
Mike951 4:7294c20b1025 311
Mike951 1:24f46931d010 312 while(!btn2 && !btn3) //waits until button input received
Mike951 1:24f46931d010 313 {
Mike951 1:24f46931d010 314 wait(0.05); //ensures buttons cannot be pressed extremely fast
Mike951 1:24f46931d010 315 }
Mike951 1:24f46931d010 316 if(btn3)
Mike951 1:24f46931d010 317 {
Mike951 1:24f46931d010 318 btn3 = false;
Mike951 1:24f46931d010 319 btn2 = false; //you're on a team if you press both buttons
Mike951 1:24f46931d010 320 ID_array[12] = char_sel(0); //sets team letter
Mike951 1:24f46931d010 321 }
Mike951 1:24f46931d010 322 else if (btn2)
Mike951 1:24f46931d010 323 {
Mike951 1:24f46931d010 324 btn2 = false;
Mike951 1:24f46931d010 325 ID_array[12] = '0'; //sets team to 'zero', indicating no team
Mike951 1:24f46931d010 326 }
Mike951 1:24f46931d010 327 else
Mike951 1:24f46931d010 328 {
Mike951 1:24f46931d010 329 error_custom(); //throws an error if you somehow get here)
Mike951 1:24f46931d010 330 }
Mike951 4:7294c20b1025 331
Mike951 1:24f46931d010 332 lcd.cls();
Mike951 1:24f46931d010 333 lcd.printf("Your ID\n is:");
Mike951 4:7294c20b1025 334 wait(1);
Mike951 1:24f46931d010 335 lcd.cls();
Mike951 1:24f46931d010 336 for(unsigned j = 0; j <= 12; j++) //prints out player id and team
Mike951 1:24f46931d010 337 {
Mike951 1:24f46931d010 338 lcd.printf("%c",ID_array[j]);
Mike951 1:24f46931d010 339 if (j == 7)
Mike951 1:24f46931d010 340 {
Mike951 4:7294c20b1025 341 lcd.printf("\n"); //puts in a new line after eight characters
Mike951 1:24f46931d010 342 }
Mike951 1:24f46931d010 343 }
Mike951 1:24f46931d010 344 crc16_attach(ID_array,13); //attaches crc bits to last two bits of 15 character array
Mike951 3:752f5f63f783 345 wait(3);
Mike951 1:24f46931d010 346 return;
Mike951 1:24f46931d010 347 }
Mike951 1:24f46931d010 348
Mike951 2:15134f79b400 349 /*ID Checking Routine
Mike951 2:15134f79b400 350 Checks received IDs to see if it is a valid shot
Mike951 2:15134f79b400 351 player_array is the 15 character id array of the player that constains a 16-bit crc in the last two bytes
Mike951 2:15134f79b400 352 Returns a boolean true if shot is valid, otherwise false
Mike951 2:15134f79b400 353 */
Mike951 2:15134f79b400 354 bool check_id(char* player_array)
Mike951 2:15134f79b400 355 {
Mike951 4:7294c20b1025 356 if (id_rx[12] == player_array[12] && id_rx[12] >= 'A')
Mike951 2:15134f79b400 357 {
Mike951 2:15134f79b400 358 return false; //if ids are on the same team or are the same person, they cannot be hit by each other/themselves
Mike951 2:15134f79b400 359 }
Mike951 4:7294c20b1025 360 else if(id_rx[13] == player_array[13] && id_rx[14] == player_array[14])
Mike951 4:7294c20b1025 361 {
Mike951 4:7294c20b1025 362 return false;
Mike951 4:7294c20b1025 363 }
Mike951 2:15134f79b400 364 return (crc16_match(id_rx, 13)); //compares the crc tag in received id to a calculated one. Returns false if different.
Mike951 2:15134f79b400 365 }
Mike951 2:15134f79b400 366
Mike951 4:7294c20b1025 367 /*Respawn Display
Mike951 4:7294c20b1025 368 Displays appropriate information for who player was hit by while they are "respawning"
Mike951 4:7294c20b1025 369 Returns nothing
Mike951 4:7294c20b1025 370 */
Mike951 2:15134f79b400 371 void respawn()
Mike951 2:15134f79b400 372 {
Mike951 2:15134f79b400 373 lcd.cls();
Mike951 2:15134f79b400 374 lcd.printf("Hit by:");
Mike951 4:7294c20b1025 375 wait(1);
Mike951 2:15134f79b400 376 lcd.cls();
Mike951 2:15134f79b400 377 for(unsigned j = 0; j <= 12; j++) //prints out id and team of person who tagged player
Mike951 2:15134f79b400 378 {
Mike951 2:15134f79b400 379 lcd.printf("%c",id_rx[j]);
Mike951 2:15134f79b400 380 if (j == 7)
Mike951 2:15134f79b400 381 {
Mike951 4:7294c20b1025 382 lcd.printf("\n"); //puts in a new line after eight characters
Mike951 2:15134f79b400 383 }
Mike951 2:15134f79b400 384 }
Mike951 4:7294c20b1025 385 wait(4);
Mike951 2:15134f79b400 386 }
Mike951 4:7294c20b1025 387 /*Firing function
Mike951 4:7294c20b1025 388 Sends ID information through IR
Mike951 4:7294c20b1025 389 Parameters: player_id
Mike951 4:7294c20b1025 390 player_id = 15 character array that contains player id and crc hash
Mike951 4:7294c20b1025 391 returns nothing
Mike951 4:7294c20b1025 392 */
Mike951 2:15134f79b400 393 void fire(char* player_id)
Mike951 2:15134f79b400 394 {
Mike951 4:7294c20b1025 395 for (unsigned i = 0; i < 15; i ++)
Mike951 3:752f5f63f783 396 {
Mike951 4:7294c20b1025 397 IR.putc(player_id[i]);
Mike951 3:752f5f63f783 398 }
Mike951 3:752f5f63f783 399 }
Mike951 3:752f5f63f783 400
Mike951 3:752f5f63f783 401 /*Statistics Display Function
Mike951 3:752f5f63f783 402 Displays game statistics without interrupting gameplay significantly
Mike951 3:752f5f63f783 403 Requires LCD to be on.
Mike951 3:752f5f63f783 404 Function will end if fire button is pressed or 5 seconds have passed
Mike951 3:752f5f63f783 405 without the statistics button (btn2) being pressed again.
Mike951 3:752f5f63f783 406 Maximum amount of time possible in this function is 15 seconds,
Mike951 3:752f5f63f783 407 5 seconds for each of the 3 statistics displays
Mike951 3:752f5f63f783 408 Parameters: tag_count = number of times player has been tagged
Mike951 3:752f5f63f783 409 shots = number of times player has shot
Mike951 3:752f5f63f783 410 mode = level of statistics looking at: tag count(0), shots(1), or time since reset(2)
Mike951 3:752f5f63f783 411 Returns nothing
Mike951 3:752f5f63f783 412 */
Mike951 3:752f5f63f783 413 void statistics(const unsigned &tag_count, const unsigned &shots, short mode)
Mike951 3:752f5f63f783 414 {
Mike951 3:752f5f63f783 415 done = false; //Used to timeout on statistics display
Mike951 3:752f5f63f783 416 lcd.cls();
Mike951 3:752f5f63f783 417 if(mode == 0)
Mike951 3:752f5f63f783 418 {
Mike951 3:752f5f63f783 419 lcd.printf("Tagged:\n%u",tag_count);
Mike951 3:752f5f63f783 420 }
Mike951 3:752f5f63f783 421 else if(mode == 1)
Mike951 3:752f5f63f783 422 {
Mike951 3:752f5f63f783 423 lcd.printf("# Shots:\n%u",shots); //shot count
Mike951 3:752f5f63f783 424 }
Mike951 3:752f5f63f783 425 else if(mode == 2)
Mike951 3:752f5f63f783 426 {
Mike951 3:752f5f63f783 427 unsigned secs = 0; //used to readout numer of seconds on timer
Mike951 3:752f5f63f783 428 secs = timer.read();
Mike951 3:752f5f63f783 429 lcd.printf("Mins:%u\nSecs:%u", mins,secs);
Mike951 3:752f5f63f783 430 }
Mike951 3:752f5f63f783 431 else
Mike951 3:752f5f63f783 432 {
Mike951 3:752f5f63f783 433 led1 = 1;
Mike951 3:752f5f63f783 434 led2 = 1;
Mike951 3:752f5f63f783 435 return; //if no valid mode, the function will end. Used to end recursion
Mike951 3:752f5f63f783 436 }
Mike951 3:752f5f63f783 437 stats.attach(&finish_disp, 5);
Mike951 3:752f5f63f783 438 while(!done)
Mike951 3:752f5f63f783 439 {
Mike951 4:7294c20b1025 440 if(btn3 == true || tagged)
Mike951 3:752f5f63f783 441 {
Mike951 3:752f5f63f783 442 stats.detach(); //exit if something interrupts stats
Mike951 3:752f5f63f783 443 lcd.cls();
Mike951 3:752f5f63f783 444 return;
Mike951 3:752f5f63f783 445 }
Mike951 3:752f5f63f783 446 else if(btn2 == true)
Mike951 3:752f5f63f783 447 {
Mike951 3:752f5f63f783 448 btn2 = false;
Mike951 3:752f5f63f783 449 stats.detach(); //keeps statistics display from timing out for another 5 seconds
Mike951 3:752f5f63f783 450 mode ++;
Mike951 3:752f5f63f783 451 statistics(tag_count,shots,mode); //recursive function call of statistics
Mike951 3:752f5f63f783 452 return; //jumps out of function whenever other forms return
Mike951 3:752f5f63f783 453 }
Mike951 3:752f5f63f783 454 wait(0.05); //function will get stuck without short wait
Mike951 3:752f5f63f783 455 }
Mike951 3:752f5f63f783 456 return;
Mike951 3:752f5f63f783 457 }
Mike951 2:15134f79b400 458
Mike951 0:69e5ee3b618d 459 int main()
Mike951 0:69e5ee3b618d 460 {
Mike951 0:69e5ee3b618d 461 Square_Gen.period_us(26); //produces a 38kHz square wave to ensure proper IR communication...
Mike951 0:69e5ee3b618d 462 Square_Gen.pulsewidth_us(13); //...this signal is sent to one of the IR diode terminals through a transistor
Mike951 4:7294c20b1025 463 IR.baud(1200); //sets baud rate of serial output and input
Mike951 4:7294c20b1025 464 IR.attach(&callback); //attaches interrupt for serial buffer
Mike951 0:69e5ee3b618d 465 LB = 1; //turn on lcd backlight
Mike951 0:69e5ee3b618d 466 LP = 1; //turn on lcd power
Mike951 0:69e5ee3b618d 467 sw2.mode(PullUp); //set buttons to a default high voltage for logic low
Mike951 0:69e5ee3b618d 468 sw3.mode(PullUp);
Mike951 0:69e5ee3b618d 469 sw2.setSampleFrequency(); //set buttons to default sample frequency for debouncing
Mike951 0:69e5ee3b618d 470 sw3.setSampleFrequency();
Mike951 0:69e5ee3b618d 471 sw2.setAssertValue(0); //set buttons to be logic high when voltage is low.
Mike951 0:69e5ee3b618d 472 sw3.setAssertValue(0);
Mike951 1:24f46931d010 473 sw2.attach_asserted( &btn2Pressed ); //attach button interrupts
Mike951 1:24f46931d010 474 sw3.attach_asserted( &btn3Pressed );
Mike951 1:24f46931d010 475 clock_tick.attach(&minutes, 60); //ticker interrupts every 60 seconds to add 1 minute and reset timer
Mike951 1:24f46931d010 476 timer.reset(); //ensure timer starts at 0
Mike951 1:24f46931d010 477 timer.start(); //start reset timer
Mike951 0:69e5ee3b618d 478
Mike951 0:69e5ee3b618d 479 led1 = 1;
Mike951 1:24f46931d010 480 char id[15]; //id array, capable of storing user ids up to 12 bytes with 1 byte for team and 2 bytes for CRC.
Mike951 2:15134f79b400 481 unsigned tag_count = 0; //number of times player has been tagged in a game
Mike951 2:15134f79b400 482 unsigned shots = 0; //number of shots fired in a game.
Mike951 1:24f46931d010 483 lcd.cls(); //ensure lcd starts with clear screen
Mike951 1:24f46931d010 484 lcd.printf("Choose \nYour ID.");
Mike951 1:24f46931d010 485 while(btn2 == false && btn3 == false)
Mike951 1:24f46931d010 486 {
Mike951 2:15134f79b400 487 wait(0.2); //wait to start setup until either button is pressed
Mike951 1:24f46931d010 488 }
Mike951 1:24f46931d010 489 btn2 = false; //reset button values
Mike951 1:24f46931d010 490 btn3 = false;
Mike951 1:24f46931d010 491 setup(id); //setup player id and team, passing function the id array
Mike951 2:15134f79b400 492 taggable = true;
Mike951 4:7294c20b1025 493 LB = 0; //turn off lcd screen, backlight, and leds to save power during game
Mike951 3:752f5f63f783 494 LP = 0;
Mike951 4:7294c20b1025 495 led1 = 0;
Mike951 4:7294c20b1025 496 led2 = 0;
Mike951 0:69e5ee3b618d 497 while(1)
Mike951 3:752f5f63f783 498 {
Mike951 4:7294c20b1025 499 if(tagged)
Mike951 0:69e5ee3b618d 500 {
Mike951 3:752f5f63f783 501 flash.attach(&flasher,0.5);
Mike951 4:7294c20b1025 502 tagged = false;
Mike951 4:7294c20b1025 503 //LB = 1; //turn on backlight and leds for flash
Mike951 3:752f5f63f783 504 led1 = 1;
Mike951 3:752f5f63f783 505 led2 = 1;
Mike951 3:752f5f63f783 506 if (check_id(id))
Mike951 2:15134f79b400 507 {
Mike951 4:7294c20b1025 508 taggable = false; //don't allow new tags if respawning
Mike951 3:752f5f63f783 509 flash.detach(); //if tag is valid, no need to flash
Mike951 3:752f5f63f783 510 tag_count ++;
Mike951 3:752f5f63f783 511 LP = 1; //turn LCD power and backlight on
Mike951 2:15134f79b400 512 LB = 1;
Mike951 3:752f5f63f783 513 respawn(); //prints appropriate respawn info
Mike951 4:7294c20b1025 514 taggable = true;
Mike951 4:7294c20b1025 515 led2 = 0;
Mike951 2:15134f79b400 516 }
Mike951 4:7294c20b1025 517 LB = 0; //turn LCD backlight and power back off
Mike951 4:7294c20b1025 518 LP = 0;
Mike951 4:7294c20b1025 519 led1 = 0;
Mike951 0:69e5ee3b618d 520 }
Mike951 3:752f5f63f783 521 if(btn3) //fires IR led if btn3 is pressed
Mike951 3:752f5f63f783 522 {
Mike951 3:752f5f63f783 523 btn3 = false;
Mike951 3:752f5f63f783 524 flash.detach(); //lights will not flash if you fire really fast
Mike951 3:752f5f63f783 525 shots ++; //increment number of times ir has been shot by player
Mike951 3:752f5f63f783 526 LB = 1;
Mike951 3:752f5f63f783 527 led1 = 1;
Mike951 3:752f5f63f783 528 led2 = 1;
Mike951 3:752f5f63f783 529 flash.attach(flasher,0.5); //flashes backlight and leds when firing
Mike951 3:752f5f63f783 530 fire(id); //fires player id using IR diode
Mike951 3:752f5f63f783 531 }
Mike951 4:7294c20b1025 532 if (btn2) //displays statistics if btn2 is pressed
Mike951 3:752f5f63f783 533 {
Mike951 4:7294c20b1025 534 flash.detach();
Mike951 3:752f5f63f783 535 btn2 = false;
Mike951 3:752f5f63f783 536 LP = 1; //turn on display
Mike951 3:752f5f63f783 537 LB = 1;
Mike951 3:752f5f63f783 538 statistics(tag_count,shots,0);
Mike951 3:752f5f63f783 539 LP = 0;
Mike951 3:752f5f63f783 540 LB = 0;
Mike951 3:752f5f63f783 541 }
Mike951 3:752f5f63f783 542 wait(0.01);
Mike951 3:752f5f63f783 543 }
Mike951 5:6e6ab7e5074e 544 }