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.
main.cpp@2:15134f79b400, 2013-03-18 (annotated)
- Committer:
- Mike951
- Date:
- Mon Mar 18 06:19:15 2013 +0000
- Revision:
- 2:15134f79b400
- Parent:
- 1:24f46931d010
- Child:
- 3:752f5f63f783
Basic hit and firing functionality implemented. Still needs full statistic display and firing to be coded.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Mike951 | 0:69e5ee3b618d | 1 | #include "mbed.h" |
Mike951 | 0:69e5ee3b618d | 2 | #include "TextLCD.h" |
Mike951 | 0:69e5ee3b618d | 3 | #include "PinDetect.h" |
Mike951 | 0:69e5ee3b618d | 4 | #include "crc16.h" |
Mike951 | 0:69e5ee3b618d | 5 | |
Mike951 | 0:69e5ee3b618d | 6 | |
Mike951 | 1:24f46931d010 | 7 | PinDetect sw2(P0_11); //switch2 debounced input |
Mike951 | 1:24f46931d010 | 8 | PinDetect sw3(P0_10); //switch3 debounced input |
Mike951 | 0:69e5ee3b618d | 9 | 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 | 10 | DigitalOut LB(P1_31); //lcd backlight |
Mike951 | 0:69e5ee3b618d | 11 | DigitalOut LP(P1_29); //lcd power |
Mike951 | 0:69e5ee3b618d | 12 | DigitalOut led1(P0_22); //on-board led ds1 |
Mike951 | 0:69e5ee3b618d | 13 | DigitalOut led2(P0_23); //on-board led ds2 |
Mike951 | 2:15134f79b400 | 14 | 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 | 15 | PwmOut Square_Gen(P1_25); //square wave generator for IR led |
Mike951 | 1:24f46931d010 | 16 | Timeout stats; //used for displaying text for limited periods of time |
Mike951 | 2:15134f79b400 | 17 | Timeout shot_time; //used to ensure shots take place in a brief period of time |
Mike951 | 2:15134f79b400 | 18 | Timeout flash; //used to flash leds and backlight when shooting or tagging |
Mike951 | 2:15134f79b400 | 19 | Timer timer; //used as seconds for reset timer |
Mike951 | 1:24f46931d010 | 20 | Ticker clock_tick; //used with timer for minutes of reset timer |
Mike951 | 1:24f46931d010 | 21 | unsigned mins = 0; //global variable for minutes in game, since ticker interrupt cannot attach functions that have parameters |
Mike951 | 1:24f46931d010 | 22 | bool btn2 = false; //global variable for sw2, since the PinDetect interrupt cannot attach functions that have parameters |
Mike951 | 1:24f46931d010 | 23 | bool btn3 = false; //global variable for sw3, since the PinDetect interrupt cannot attach functions that have parameters |
Mike951 | 2:15134f79b400 | 24 | bool done = false; //global variable for timeout, since TimeOut interrupt cannot attach functions that have parameters |
Mike951 | 2:15134f79b400 | 25 | bool taggable = false; //global variable for whether serial received input will be used or not |
Mike951 | 2:15134f79b400 | 26 | char id_rx[15]; //global variable for received ID. Required to use serial interrupt correctly |
Mike951 | 2:15134f79b400 | 27 | unsigned id_pos = 0; //global variable for recieved ID array location. Also required for serial interrupt. |
Mike951 | 0:69e5ee3b618d | 28 | |
Mike951 | 1:24f46931d010 | 29 | void minutes() |
Mike951 | 1:24f46931d010 | 30 | { |
Mike951 | 1:24f46931d010 | 31 | mins ++; |
Mike951 | 1:24f46931d010 | 32 | timer.reset(); |
Mike951 | 1:24f46931d010 | 33 | } |
Mike951 | 1:24f46931d010 | 34 | |
Mike951 | 2:15134f79b400 | 35 | void shot_check() |
Mike951 | 2:15134f79b400 | 36 | { |
Mike951 | 2:15134f79b400 | 37 | id_pos = 0; //resets current id |
Mike951 | 2:15134f79b400 | 38 | //sets 15th byte of array to NULL |
Mike951 | 2:15134f79b400 | 39 | id_rx[14] = NULL; //if this byte is changed from NULL, it will signify that the player has been successfully tagged |
Mike951 | 2:15134f79b400 | 40 | LB = 0; //ensure backlight is back off if it was turned on earlier |
Mike951 | 2:15134f79b400 | 41 | } |
Mike951 | 2:15134f79b400 | 42 | |
Mike951 | 2:15134f79b400 | 43 | /* Flashing interrupt |
Mike951 | 2:15134f79b400 | 44 | Intended to be used with a timeout object to flash lights when shot or shooting |
Mike951 | 2:15134f79b400 | 45 | */ |
Mike951 | 2:15134f79b400 | 46 | void flasher() |
Mike951 | 2:15134f79b400 | 47 | { |
Mike951 | 2:15134f79b400 | 48 | LB = 0; |
Mike951 | 2:15134f79b400 | 49 | led1 = !led1; |
Mike951 | 2:15134f79b400 | 50 | led2 = !led2; |
Mike951 | 2:15134f79b400 | 51 | } |
Mike951 | 2:15134f79b400 | 52 | |
Mike951 | 0:69e5ee3b618d | 53 | void callback() |
Mike951 | 0:69e5ee3b618d | 54 | { |
Mike951 | 2:15134f79b400 | 55 | // Note: you need to actually read from the serial buffer to clear the RX interrupt |
Mike951 | 2:15134f79b400 | 56 | if (!taggable) |
Mike951 | 2:15134f79b400 | 57 | { |
Mike951 | 2:15134f79b400 | 58 | IR.getc(); //ensures no extra buffering left over when player is not taggable |
Mike951 | 2:15134f79b400 | 59 | return; |
Mike951 | 2:15134f79b400 | 60 | } |
Mike951 | 2:15134f79b400 | 61 | |
Mike951 | 2:15134f79b400 | 62 | id_rx[id_pos] = IR.getc(); //place received character into array |
Mike951 | 2:15134f79b400 | 63 | if (id_pos == 0) //starts a timer for the time in which receiver must receive a full id |
Mike951 | 0:69e5ee3b618d | 64 | { |
Mike951 | 2:15134f79b400 | 65 | shot_time.attach(&shot_check, 0.5); |
Mike951 | 0:69e5ee3b618d | 66 | } |
Mike951 | 2:15134f79b400 | 67 | else if(id_pos >= 14) |
Mike951 | 0:69e5ee3b618d | 68 | { |
Mike951 | 2:15134f79b400 | 69 | id_pos = 0; //ensures no array overflows |
Mike951 | 2:15134f79b400 | 70 | shot_time.detach(); //ensures no further action upon array until next time tagged |
Mike951 | 0:69e5ee3b618d | 71 | } |
Mike951 | 2:15134f79b400 | 72 | led1 = !led1; //flashes lights when IR is received |
Mike951 | 2:15134f79b400 | 73 | led2 = !led1; |
Mike951 | 2:15134f79b400 | 74 | LB = !LB; //flashes LCD backlight when IR received |
Mike951 | 2:15134f79b400 | 75 | id_pos ++; //increment to next array position for id |
Mike951 | 2:15134f79b400 | 76 | return; |
Mike951 | 0:69e5ee3b618d | 77 | } |
Mike951 | 0:69e5ee3b618d | 78 | |
Mike951 | 1:24f46931d010 | 79 | void btn2Pressed() |
Mike951 | 0:69e5ee3b618d | 80 | { |
Mike951 | 0:69e5ee3b618d | 81 | led1 = !led1; |
Mike951 | 1:24f46931d010 | 82 | btn2 = true; |
Mike951 | 0:69e5ee3b618d | 83 | } |
Mike951 | 0:69e5ee3b618d | 84 | |
Mike951 | 1:24f46931d010 | 85 | void btn3Pressed() |
Mike951 | 0:69e5ee3b618d | 86 | { |
Mike951 | 0:69e5ee3b618d | 87 | led2 = !led2; |
Mike951 | 1:24f46931d010 | 88 | btn3 = true; |
Mike951 | 0:69e5ee3b618d | 89 | |
Mike951 | 0:69e5ee3b618d | 90 | } |
Mike951 | 0:69e5ee3b618d | 91 | |
Mike951 | 1:24f46931d010 | 92 | void finish_disp () |
Mike951 | 0:69e5ee3b618d | 93 | { |
Mike951 | 0:69e5ee3b618d | 94 | done = true; |
Mike951 | 0:69e5ee3b618d | 95 | return; |
Mike951 | 0:69e5ee3b618d | 96 | } |
Mike951 | 0:69e5ee3b618d | 97 | |
Mike951 | 1:24f46931d010 | 98 | /*Error Routine. |
Mike951 | 1:24f46931d010 | 99 | Displays "ERROR" on LCD screen and flashes leds |
Mike951 | 1:24f46931d010 | 100 | when called for an indefinite period of time |
Mike951 | 1:24f46931d010 | 101 | */ |
Mike951 | 1:24f46931d010 | 102 | void error_custom () |
Mike951 | 1:24f46931d010 | 103 | { |
Mike951 | 1:24f46931d010 | 104 | lcd.cls(); |
Mike951 | 1:24f46931d010 | 105 | lcd.printf("ERROR"); |
Mike951 | 1:24f46931d010 | 106 | led1 = 0; |
Mike951 | 1:24f46931d010 | 107 | led2 = 1; |
Mike951 | 1:24f46931d010 | 108 | while(1) |
Mike951 | 1:24f46931d010 | 109 | { |
Mike951 | 1:24f46931d010 | 110 | led1 = !led1; |
Mike951 | 1:24f46931d010 | 111 | led2 = !led2; |
Mike951 | 1:24f46931d010 | 112 | wait(0.5); |
Mike951 | 1:24f46931d010 | 113 | } |
Mike951 | 1:24f46931d010 | 114 | } |
Mike951 | 1:24f46931d010 | 115 | /*Alphanumeric selector |
Mike951 | 1:24f46931d010 | 116 | Used with char_sel function in order to select a number 0-9 or letters A-Z through user input. |
Mike951 | 1:24f46931d010 | 117 | Returns a char. |
Mike951 | 1:24f46931d010 | 118 | */ |
Mike951 | 1:24f46931d010 | 119 | char alpha_num_sel (bool number) |
Mike951 | 1:24f46931d010 | 120 | { |
Mike951 | 1:24f46931d010 | 121 | char n0 = '0'; |
Mike951 | 1:24f46931d010 | 122 | char n_tmp = '0'; |
Mike951 | 1:24f46931d010 | 123 | unsigned incr = 0; //used to increment characters between 0-9 or A-Z |
Mike951 | 1:24f46931d010 | 124 | unsigned mod; |
Mike951 | 1:24f46931d010 | 125 | if (number) |
Mike951 | 1:24f46931d010 | 126 | { |
Mike951 | 1:24f46931d010 | 127 | lcd.cls(); |
Mike951 | 1:24f46931d010 | 128 | lcd.printf("Pick\nNumber:%c",n_tmp); |
Mike951 | 1:24f46931d010 | 129 | n0 = '0'; |
Mike951 | 1:24f46931d010 | 130 | n_tmp = n0; |
Mike951 | 2:15134f79b400 | 131 | mod = 11; //modulus for character range |
Mike951 | 1:24f46931d010 | 132 | } |
Mike951 | 1:24f46931d010 | 133 | else |
Mike951 | 1:24f46931d010 | 134 | { |
Mike951 | 1:24f46931d010 | 135 | lcd.cls(); |
Mike951 | 1:24f46931d010 | 136 | n0 = 'A'; |
Mike951 | 1:24f46931d010 | 137 | n_tmp = n0; |
Mike951 | 1:24f46931d010 | 138 | lcd.printf("Pick\nLetter:%c",n_tmp); |
Mike951 | 1:24f46931d010 | 139 | mod = 26; |
Mike951 | 1:24f46931d010 | 140 | } |
Mike951 | 1:24f46931d010 | 141 | while(1) |
Mike951 | 1:24f46931d010 | 142 | { |
Mike951 | 1:24f46931d010 | 143 | while(!btn2 && !btn3) //waits until button input received |
Mike951 | 1:24f46931d010 | 144 | { |
Mike951 | 1:24f46931d010 | 145 | wait(0.05); |
Mike951 | 1:24f46931d010 | 146 | } |
Mike951 | 1:24f46931d010 | 147 | if(btn3) |
Mike951 | 1:24f46931d010 | 148 | { |
Mike951 | 1:24f46931d010 | 149 | btn3 = false; |
Mike951 | 1:24f46931d010 | 150 | btn2 = false; //if both butons pressed, it just selects the current character |
Mike951 | 1:24f46931d010 | 151 | return (n_tmp); |
Mike951 | 1:24f46931d010 | 152 | } |
Mike951 | 1:24f46931d010 | 153 | else if(btn2) |
Mike951 | 1:24f46931d010 | 154 | { |
Mike951 | 1:24f46931d010 | 155 | btn2 = false; |
Mike951 | 1:24f46931d010 | 156 | incr ++; |
Mike951 | 2:15134f79b400 | 157 | incr = incr % mod; //ensures that numbers stay within the 0-9/A-Z range |
Mike951 | 2:15134f79b400 | 158 | n_tmp = n0 + incr; //increment current character selected |
Mike951 | 2:15134f79b400 | 159 | if (incr == 10 && number) //feature addition to allow for space entry |
Mike951 | 2:15134f79b400 | 160 | { |
Mike951 | 2:15134f79b400 | 161 | n_tmp = ' '; |
Mike951 | 2:15134f79b400 | 162 | } |
Mike951 | 1:24f46931d010 | 163 | lcd.cls(); |
Mike951 | 1:24f46931d010 | 164 | if(number) |
Mike951 | 1:24f46931d010 | 165 | { |
Mike951 | 1:24f46931d010 | 166 | lcd.printf("Pick\nNumber:%c",n_tmp); //displays current number |
Mike951 | 1:24f46931d010 | 167 | } |
Mike951 | 1:24f46931d010 | 168 | else |
Mike951 | 1:24f46931d010 | 169 | { |
Mike951 | 1:24f46931d010 | 170 | lcd.printf("Pick\nLetter:%c",n_tmp); //displays current letter |
Mike951 | 1:24f46931d010 | 171 | } |
Mike951 | 1:24f46931d010 | 172 | } |
Mike951 | 1:24f46931d010 | 173 | else |
Mike951 | 1:24f46931d010 | 174 | { |
Mike951 | 1:24f46931d010 | 175 | error_custom(); |
Mike951 | 1:24f46931d010 | 176 | } |
Mike951 | 1:24f46931d010 | 177 | |
Mike951 | 1:24f46931d010 | 178 | } |
Mike951 | 1:24f46931d010 | 179 | } |
Mike951 | 1:24f46931d010 | 180 | /*Character Selection |
Mike951 | 1:24f46931d010 | 181 | Used with setup() function in order to pick a character A-Z and number 0-9 |
Mike951 | 1:24f46931d010 | 182 | for use as part of user id and/or team. Passed a 0 if selecting team letter (A-Z), |
Mike951 | 1:24f46931d010 | 183 | otherwise will select player id letter |
Mike951 | 1:24f46931d010 | 184 | */ |
Mike951 | 1:24f46931d010 | 185 | char char_sel (bool player) |
Mike951 | 1:24f46931d010 | 186 | { |
Mike951 | 1:24f46931d010 | 187 | if (player) |
Mike951 | 1:24f46931d010 | 188 | { |
Mike951 | 1:24f46931d010 | 189 | lcd.cls(); |
Mike951 | 1:24f46931d010 | 190 | lcd.printf("A-Z? or\n0-9?"); |
Mike951 | 1:24f46931d010 | 191 | while(!btn2 && !btn3) //waits until button input received |
Mike951 | 1:24f46931d010 | 192 | { |
Mike951 | 1:24f46931d010 | 193 | wait(0.05); |
Mike951 | 1:24f46931d010 | 194 | } |
Mike951 | 1:24f46931d010 | 195 | if(btn2) //if select button pressed, goes through numerical selection |
Mike951 | 1:24f46931d010 | 196 | { |
Mike951 | 1:24f46931d010 | 197 | btn2 = false; |
Mike951 | 1:24f46931d010 | 198 | btn3 = false; //if both buttons pressed at the same time, it just does numerical selection |
Mike951 | 1:24f46931d010 | 199 | |
Mike951 | 1:24f46931d010 | 200 | return(alpha_num_sel(1)); |
Mike951 | 1:24f46931d010 | 201 | } |
Mike951 | 1:24f46931d010 | 202 | else if(btn3) |
Mike951 | 1:24f46931d010 | 203 | { |
Mike951 | 1:24f46931d010 | 204 | btn3 = false; //pressing the option button in this case is the same as selecting a team |
Mike951 | 1:24f46931d010 | 205 | } |
Mike951 | 1:24f46931d010 | 206 | else |
Mike951 | 1:24f46931d010 | 207 | { |
Mike951 | 1:24f46931d010 | 208 | error_custom(); //if you somehow make it here without pressing buttons, it will throw an error |
Mike951 | 1:24f46931d010 | 209 | } |
Mike951 | 1:24f46931d010 | 210 | } |
Mike951 | 1:24f46931d010 | 211 | return(alpha_num_sel(0)); //returns capital alpha character for id or team by calling selection function |
Mike951 | 1:24f46931d010 | 212 | } |
Mike951 | 1:24f46931d010 | 213 | |
Mike951 | 1:24f46931d010 | 214 | |
Mike951 | 1:24f46931d010 | 215 | /*Setup Routine. |
Mike951 | 1:24f46931d010 | 216 | Sets the user id for use in-game. |
Mike951 | 1:24f46931d010 | 217 | Function must be passed an array of characters of size 15 |
Mike951 | 1:24f46931d010 | 218 | in order to work correctly. |
Mike951 | 1:24f46931d010 | 219 | */ |
Mike951 | 1:24f46931d010 | 220 | void setup (char* ID_array) |
Mike951 | 1:24f46931d010 | 221 | { |
Mike951 | 1:24f46931d010 | 222 | unsigned size = 1; |
Mike951 | 1:24f46931d010 | 223 | |
Mike951 | 1:24f46931d010 | 224 | lcd.cls(); |
Mike951 | 1:24f46931d010 | 225 | lcd.printf("ID Size?\n%u",size); |
Mike951 | 1:24f46931d010 | 226 | while(1) |
Mike951 | 1:24f46931d010 | 227 | { |
Mike951 | 1:24f46931d010 | 228 | while(!btn2 && !btn3) //waits until button input received |
Mike951 | 1:24f46931d010 | 229 | { |
Mike951 | 1:24f46931d010 | 230 | wait(0.05); //ensures buttons cannot be pressed extremely fast |
Mike951 | 1:24f46931d010 | 231 | } |
Mike951 | 1:24f46931d010 | 232 | if(btn2 && btn3) //routine to set size of player id in bytes |
Mike951 | 1:24f46931d010 | 233 | { |
Mike951 | 1:24f46931d010 | 234 | btn2 = false; //handling for simultaneous button pressing |
Mike951 | 1:24f46931d010 | 235 | btn3 = false; |
Mike951 | 1:24f46931d010 | 236 | size++; |
Mike951 | 1:24f46931d010 | 237 | if (size > 12) |
Mike951 | 1:24f46931d010 | 238 | { |
Mike951 | 1:24f46931d010 | 239 | size = 1; //ensures size cannot be greater than 12 or less than 1 |
Mike951 | 1:24f46931d010 | 240 | } |
Mike951 | 1:24f46931d010 | 241 | break; //sets size to whatever current size is +1 and moves on |
Mike951 | 1:24f46931d010 | 242 | } |
Mike951 | 1:24f46931d010 | 243 | else if(btn2) //increases size or loops back to 1, displays current size |
Mike951 | 1:24f46931d010 | 244 | { |
Mike951 | 1:24f46931d010 | 245 | btn2 = false; |
Mike951 | 1:24f46931d010 | 246 | size++; |
Mike951 | 1:24f46931d010 | 247 | if (size > 12) |
Mike951 | 1:24f46931d010 | 248 | { |
Mike951 | 1:24f46931d010 | 249 | size = 1; //ensures size cannot be greater than 12 or less than 1 |
Mike951 | 1:24f46931d010 | 250 | } |
Mike951 | 1:24f46931d010 | 251 | lcd.cls(); |
Mike951 | 1:24f46931d010 | 252 | lcd.printf("ID Size?\n%u",size); //displays current size |
Mike951 | 1:24f46931d010 | 253 | } |
Mike951 | 1:24f46931d010 | 254 | else if(btn3) |
Mike951 | 1:24f46931d010 | 255 | { |
Mike951 | 1:24f46931d010 | 256 | btn3 = false; //selects current size |
Mike951 | 1:24f46931d010 | 257 | break; |
Mike951 | 1:24f46931d010 | 258 | } |
Mike951 | 1:24f46931d010 | 259 | else |
Mike951 | 1:24f46931d010 | 260 | { |
Mike951 | 1:24f46931d010 | 261 | error_custom(); //error called if unexpected output |
Mike951 | 1:24f46931d010 | 262 | } |
Mike951 | 1:24f46931d010 | 263 | } |
Mike951 | 1:24f46931d010 | 264 | |
Mike951 | 1:24f46931d010 | 265 | for (unsigned j = 0; j < size; j ++) //sets player id |
Mike951 | 1:24f46931d010 | 266 | { |
Mike951 | 1:24f46931d010 | 267 | ID_array[j] = char_sel(1); |
Mike951 | 1:24f46931d010 | 268 | } |
Mike951 | 1:24f46931d010 | 269 | for (unsigned j = size; j < 12; j ++) |
Mike951 | 1:24f46931d010 | 270 | { |
Mike951 | 1:24f46931d010 | 271 | ID_array[j] = ' '; //fill unused characters with spaces |
Mike951 | 1:24f46931d010 | 272 | } |
Mike951 | 1:24f46931d010 | 273 | lcd.cls(); |
Mike951 | 1:24f46931d010 | 274 | lcd.printf("On team?\n Y or N"); |
Mike951 | 1:24f46931d010 | 275 | while(!btn2 && !btn3) //waits until button input received |
Mike951 | 1:24f46931d010 | 276 | { |
Mike951 | 1:24f46931d010 | 277 | wait(0.05); //ensures buttons cannot be pressed extremely fast |
Mike951 | 1:24f46931d010 | 278 | } |
Mike951 | 1:24f46931d010 | 279 | if(btn3) |
Mike951 | 1:24f46931d010 | 280 | { |
Mike951 | 1:24f46931d010 | 281 | btn3 = false; |
Mike951 | 1:24f46931d010 | 282 | btn2 = false; //you're on a team if you press both buttons |
Mike951 | 1:24f46931d010 | 283 | ID_array[12] = char_sel(0); //sets team letter |
Mike951 | 1:24f46931d010 | 284 | } |
Mike951 | 1:24f46931d010 | 285 | else if (btn2) |
Mike951 | 1:24f46931d010 | 286 | { |
Mike951 | 1:24f46931d010 | 287 | btn2 = false; |
Mike951 | 1:24f46931d010 | 288 | ID_array[12] = '0'; //sets team to 'zero', indicating no team |
Mike951 | 1:24f46931d010 | 289 | } |
Mike951 | 1:24f46931d010 | 290 | else |
Mike951 | 1:24f46931d010 | 291 | { |
Mike951 | 1:24f46931d010 | 292 | error_custom(); //throws an error if you somehow get here) |
Mike951 | 1:24f46931d010 | 293 | } |
Mike951 | 1:24f46931d010 | 294 | lcd.cls(); |
Mike951 | 1:24f46931d010 | 295 | lcd.printf("Your ID\n is:"); |
Mike951 | 1:24f46931d010 | 296 | wait(1.5); |
Mike951 | 1:24f46931d010 | 297 | lcd.cls(); |
Mike951 | 1:24f46931d010 | 298 | for(unsigned j = 0; j <= 12; j++) //prints out player id and team |
Mike951 | 1:24f46931d010 | 299 | { |
Mike951 | 1:24f46931d010 | 300 | lcd.printf("%c",ID_array[j]); |
Mike951 | 1:24f46931d010 | 301 | if (j == 7) |
Mike951 | 1:24f46931d010 | 302 | { |
Mike951 | 1:24f46931d010 | 303 | lcd.printf("\n"); //puts in a new line if id is longer than eight characters |
Mike951 | 1:24f46931d010 | 304 | } |
Mike951 | 1:24f46931d010 | 305 | } |
Mike951 | 1:24f46931d010 | 306 | crc16_attach(ID_array,13); //attaches crc bits to last two bits of 15 character array |
Mike951 | 1:24f46931d010 | 307 | wait(5); |
Mike951 | 1:24f46931d010 | 308 | return; |
Mike951 | 1:24f46931d010 | 309 | } |
Mike951 | 1:24f46931d010 | 310 | |
Mike951 | 2:15134f79b400 | 311 | /*ID Checking Routine |
Mike951 | 2:15134f79b400 | 312 | Checks received IDs to see if it is a valid shot |
Mike951 | 2:15134f79b400 | 313 | 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 | 314 | Returns a boolean true if shot is valid, otherwise false |
Mike951 | 2:15134f79b400 | 315 | */ |
Mike951 | 2:15134f79b400 | 316 | bool check_id(char* player_array) |
Mike951 | 2:15134f79b400 | 317 | { |
Mike951 | 2:15134f79b400 | 318 | if (id_rx[12] == player_array[12] && id_rx[12] >= 'A' || id_rx[13] == player_array[13] && id_rx[14] == player_array[14]) |
Mike951 | 2:15134f79b400 | 319 | { |
Mike951 | 2:15134f79b400 | 320 | 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 | 321 | } |
Mike951 | 2:15134f79b400 | 322 | |
Mike951 | 2:15134f79b400 | 323 | return (crc16_match(id_rx, 13)); //compares the crc tag in received id to a calculated one. Returns false if different. |
Mike951 | 2:15134f79b400 | 324 | } |
Mike951 | 2:15134f79b400 | 325 | |
Mike951 | 2:15134f79b400 | 326 | void respawn() |
Mike951 | 2:15134f79b400 | 327 | { |
Mike951 | 2:15134f79b400 | 328 | lcd.cls(); |
Mike951 | 2:15134f79b400 | 329 | lcd.printf("Hit by:"); |
Mike951 | 2:15134f79b400 | 330 | wait(1.5); |
Mike951 | 2:15134f79b400 | 331 | lcd.cls(); |
Mike951 | 2:15134f79b400 | 332 | for(unsigned j = 0; j <= 12; j++) //prints out id and team of person who tagged player |
Mike951 | 2:15134f79b400 | 333 | { |
Mike951 | 2:15134f79b400 | 334 | lcd.printf("%c",id_rx[j]); |
Mike951 | 2:15134f79b400 | 335 | if (j == 7) |
Mike951 | 2:15134f79b400 | 336 | { |
Mike951 | 2:15134f79b400 | 337 | lcd.printf("\n"); //puts in a new line if id is longer than eight characters |
Mike951 | 2:15134f79b400 | 338 | } |
Mike951 | 2:15134f79b400 | 339 | } |
Mike951 | 2:15134f79b400 | 340 | wait(3.5); |
Mike951 | 2:15134f79b400 | 341 | } |
Mike951 | 2:15134f79b400 | 342 | |
Mike951 | 2:15134f79b400 | 343 | void fire(char* player_id) |
Mike951 | 2:15134f79b400 | 344 | { |
Mike951 | 2:15134f79b400 | 345 | wait(0.05); |
Mike951 | 2:15134f79b400 | 346 | } |
Mike951 | 2:15134f79b400 | 347 | |
Mike951 | 0:69e5ee3b618d | 348 | int main() |
Mike951 | 0:69e5ee3b618d | 349 | { |
Mike951 | 2:15134f79b400 | 350 | id_rx[14] = NULL; |
Mike951 | 0:69e5ee3b618d | 351 | IR.attach(&callback); //attaches interrupt for serial buffer |
Mike951 | 0:69e5ee3b618d | 352 | IR.baud(1200); //sets baud rate of serial output and input |
Mike951 | 0:69e5ee3b618d | 353 | Square_Gen.period_us(26); //produces a 38kHz square wave to ensure proper IR communication... |
Mike951 | 0:69e5ee3b618d | 354 | Square_Gen.pulsewidth_us(13); //...this signal is sent to one of the IR diode terminals through a transistor |
Mike951 | 0:69e5ee3b618d | 355 | LB = 1; //turn on lcd backlight |
Mike951 | 0:69e5ee3b618d | 356 | LP = 1; //turn on lcd power |
Mike951 | 0:69e5ee3b618d | 357 | sw2.mode(PullUp); //set buttons to a default high voltage for logic low |
Mike951 | 0:69e5ee3b618d | 358 | sw3.mode(PullUp); |
Mike951 | 0:69e5ee3b618d | 359 | sw2.setSampleFrequency(); //set buttons to default sample frequency for debouncing |
Mike951 | 0:69e5ee3b618d | 360 | sw3.setSampleFrequency(); |
Mike951 | 0:69e5ee3b618d | 361 | sw2.setAssertValue(0); //set buttons to be logic high when voltage is low. |
Mike951 | 0:69e5ee3b618d | 362 | sw3.setAssertValue(0); |
Mike951 | 1:24f46931d010 | 363 | sw2.attach_asserted( &btn2Pressed ); //attach button interrupts |
Mike951 | 1:24f46931d010 | 364 | sw3.attach_asserted( &btn3Pressed ); |
Mike951 | 1:24f46931d010 | 365 | clock_tick.attach(&minutes, 60); //ticker interrupts every 60 seconds to add 1 minute and reset timer |
Mike951 | 1:24f46931d010 | 366 | timer.reset(); //ensure timer starts at 0 |
Mike951 | 1:24f46931d010 | 367 | timer.start(); //start reset timer |
Mike951 | 2:15134f79b400 | 368 | unsigned secs; //Used to display number of seconds since reset |
Mike951 | 0:69e5ee3b618d | 369 | |
Mike951 | 0:69e5ee3b618d | 370 | led1 = 1; |
Mike951 | 1:24f46931d010 | 371 | 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 | 372 | unsigned tag_count = 0; //number of times player has been tagged in a game |
Mike951 | 2:15134f79b400 | 373 | unsigned shots = 0; //number of shots fired in a game. |
Mike951 | 1:24f46931d010 | 374 | lcd.cls(); //ensure lcd starts with clear screen |
Mike951 | 1:24f46931d010 | 375 | lcd.printf("Choose \nYour ID."); |
Mike951 | 1:24f46931d010 | 376 | while(btn2 == false && btn3 == false) |
Mike951 | 1:24f46931d010 | 377 | { |
Mike951 | 2:15134f79b400 | 378 | wait(0.2); //wait to start setup until either button is pressed |
Mike951 | 1:24f46931d010 | 379 | } |
Mike951 | 1:24f46931d010 | 380 | btn2 = false; //reset button values |
Mike951 | 1:24f46931d010 | 381 | btn3 = false; |
Mike951 | 1:24f46931d010 | 382 | setup(id); //setup player id and team, passing function the id array |
Mike951 | 2:15134f79b400 | 383 | lcd.cls(); |
Mike951 | 2:15134f79b400 | 384 | lcd.printf("Starting\nin 3 sec"); |
Mike951 | 2:15134f79b400 | 385 | wait(3); |
Mike951 | 2:15134f79b400 | 386 | taggable = true; |
Mike951 | 2:15134f79b400 | 387 | LB = 0; //turn off lcd screen and backlight to save power during game |
Mike951 | 2:15134f79b400 | 388 | //LP = 0; |
Mike951 | 0:69e5ee3b618d | 389 | while(1) |
Mike951 | 0:69e5ee3b618d | 390 | { |
Mike951 | 2:15134f79b400 | 391 | if(id_rx[14]) |
Mike951 | 2:15134f79b400 | 392 | { |
Mike951 | 2:15134f79b400 | 393 | taggable = false; //don't allow new tags while the current one is checked |
Mike951 | 2:15134f79b400 | 394 | flash.attach(&flasher,0.5); |
Mike951 | 2:15134f79b400 | 395 | LB = 1; //turn on backlight and leds |
Mike951 | 2:15134f79b400 | 396 | led1 = 1; |
Mike951 | 2:15134f79b400 | 397 | led2 = 1; |
Mike951 | 2:15134f79b400 | 398 | if (check_id(id)) |
Mike951 | 2:15134f79b400 | 399 | { |
Mike951 | 2:15134f79b400 | 400 | flash.detach(); //if tag is valid, no need to flash |
Mike951 | 2:15134f79b400 | 401 | tag_count ++; |
Mike951 | 2:15134f79b400 | 402 | LP = 1; //turn LCD power and backlight on |
Mike951 | 2:15134f79b400 | 403 | LB = 1; |
Mike951 | 2:15134f79b400 | 404 | respawn(); //prints appropriate respawn info |
Mike951 | 2:15134f79b400 | 405 | LB = 0; //turn LCD backlight and power back off |
Mike951 | 2:15134f79b400 | 406 | LP = 0; |
Mike951 | 2:15134f79b400 | 407 | } |
Mike951 | 2:15134f79b400 | 408 | id_rx[14] = NULL; //ensure this if statement does not immediately reactivate |
Mike951 | 2:15134f79b400 | 409 | taggable = true; |
Mike951 | 2:15134f79b400 | 410 | } |
Mike951 | 2:15134f79b400 | 411 | if(btn3) |
Mike951 | 2:15134f79b400 | 412 | { |
Mike951 | 2:15134f79b400 | 413 | btn3 = false; |
Mike951 | 2:15134f79b400 | 414 | flash.detach(); //lights will not flash if you fire really fast |
Mike951 | 2:15134f79b400 | 415 | shots ++; |
Mike951 | 2:15134f79b400 | 416 | LB = 1; |
Mike951 | 2:15134f79b400 | 417 | led1 = 1; |
Mike951 | 2:15134f79b400 | 418 | led2 = 1; |
Mike951 | 2:15134f79b400 | 419 | flash.attach(flasher,0.5); //flashes backlight and leds when firing |
Mike951 | 2:15134f79b400 | 420 | fire(id); //fires player id using IR diode |
Mike951 | 2:15134f79b400 | 421 | } |
Mike951 | 2:15134f79b400 | 422 | |
Mike951 | 1:24f46931d010 | 423 | secs = timer.read(); |
Mike951 | 0:69e5ee3b618d | 424 | lcd.cls(); |
Mike951 | 1:24f46931d010 | 425 | lcd.printf("Mins:%u\nSecs:%u", mins,secs); |
Mike951 | 1:24f46931d010 | 426 | wait(1); |
Mike951 | 0:69e5ee3b618d | 427 | //lcd.cls(); |
Mike951 | 0:69e5ee3b618d | 428 | //lcd.printf("43%c%c%c!",c[0],c[1],c[2]); |
Mike951 | 0:69e5ee3b618d | 429 | //IR.printf("%c%c%c",id); |
Mike951 | 1:24f46931d010 | 430 | |
Mike951 | 1:24f46931d010 | 431 | |
Mike951 | 1:24f46931d010 | 432 | //crc16 matching test - works! |
Mike951 | 1:24f46931d010 | 433 | /*if (btn3 == true) |
Mike951 | 0:69e5ee3b618d | 434 | { |
Mike951 | 1:24f46931d010 | 435 | btn3 = false; |
Mike951 | 1:24f46931d010 | 436 | lcd.cls(); |
Mike951 | 1:24f46931d010 | 437 | if (crc16_match(id,2)) |
Mike951 | 1:24f46931d010 | 438 | { |
Mike951 | 1:24f46931d010 | 439 | lcd.printf("true"); |
Mike951 | 1:24f46931d010 | 440 | } |
Mike951 | 1:24f46931d010 | 441 | else |
Mike951 | 1:24f46931d010 | 442 | { |
Mike951 | 1:24f46931d010 | 443 | lcd.printf("false"); |
Mike951 | 1:24f46931d010 | 444 | } |
Mike951 | 1:24f46931d010 | 445 | wait(5); |
Mike951 | 1:24f46931d010 | 446 | }*/ |
Mike951 | 1:24f46931d010 | 447 | |
Mike951 | 1:24f46931d010 | 448 | //statistics display test - works! |
Mike951 | 1:24f46931d010 | 449 | /* |
Mike951 | 1:24f46931d010 | 450 | if (btn2 == true) |
Mike951 | 1:24f46931d010 | 451 | { |
Mike951 | 1:24f46931d010 | 452 | btn2 = false; |
Mike951 | 0:69e5ee3b618d | 453 | done = false; |
Mike951 | 0:69e5ee3b618d | 454 | wait(0.05); |
Mike951 | 0:69e5ee3b618d | 455 | stats.attach(&finish_disp, 5); |
Mike951 | 1:24f46931d010 | 456 | lcd.cls(); |
Mike951 | 1:24f46931d010 | 457 | lcd.printf("ID:%c%c%c%c", id[0],id[1],id[2],id[3]); |
Mike951 | 0:69e5ee3b618d | 458 | while(!done) |
Mike951 | 0:69e5ee3b618d | 459 | { |
Mike951 | 1:24f46931d010 | 460 | if(btn2 == true) |
Mike951 | 0:69e5ee3b618d | 461 | { |
Mike951 | 1:24f46931d010 | 462 | btn2 = false; |
Mike951 | 0:69e5ee3b618d | 463 | stats.detach(); |
Mike951 | 0:69e5ee3b618d | 464 | lcd.cls(); |
Mike951 | 0:69e5ee3b618d | 465 | break; |
Mike951 | 0:69e5ee3b618d | 466 | } |
Mike951 | 1:24f46931d010 | 467 | wait(0.2); |
Mike951 | 0:69e5ee3b618d | 468 | } |
Mike951 | 1:24f46931d010 | 469 | }*/ |
Mike951 | 0:69e5ee3b618d | 470 | |
Mike951 | 0:69e5ee3b618d | 471 | //IR.printf("%c",id); |
Mike951 | 0:69e5ee3b618d | 472 | |
Mike951 | 0:69e5ee3b618d | 473 | |
Mike951 | 0:69e5ee3b618d | 474 | } |
Mike951 | 0:69e5ee3b618d | 475 | } |