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.
Diff: main.cpp
- Revision:
- 1:24f46931d010
- Parent:
- 0:69e5ee3b618d
- Child:
- 2:15134f79b400
--- a/main.cpp Sun Mar 17 20:13:05 2013 +0000 +++ b/main.cpp Mon Mar 18 03:49:33 2013 +0000 @@ -4,8 +4,8 @@ #include "crc16.h" -PinDetect sw2(P0_10); //switch2 debounced input -PinDetect sw3(P0_11); //switch3 debounced input +PinDetect sw2(P0_11); //switch2 debounced input +PinDetect sw3(P0_10); //switch3 debounced input TextLCD lcd(P1_15, P1_16, P1_19, P1_20, P1_21, P1_22); // rs, e, d4-d7 led pins:4,6,11-14 DigitalOut LB(P1_31); //lcd backlight DigitalOut LP(P1_29); //lcd power @@ -13,12 +13,22 @@ DigitalOut led2(P0_23); //on-board led ds2 Serial IR(P1_27,P1_26); //IR transmitter and receiver output and input control PwmOut Square_Gen(P1_25); //square wave generator for IR led -bool btn1 = false; //global variable for sw2, since the PinDetect interrupt cannot attach functions that have parameters -bool btn2 = false; //global variable for sw3, since the PinDetect interrupt cannot attach functions that have parameters +Timeout stats; //used for displaying text for limited periods of time +Timer timer; //used as seconds for reset timer +Ticker clock_tick; //used with timer for minutes of reset timer +unsigned mins = 0; //global variable for minutes in game, since ticker interrupt cannot attach functions that have parameters +bool btn2 = false; //global variable for sw2, since the PinDetect interrupt cannot attach functions that have parameters +bool btn3 = false; //global variable for sw3, since the PinDetect interrupt cannot attach functions that have parameters bool done = false; //global variable for timeout, since TimeOut interrupt cannot attach functions that have paramaters char c[3]; unsigned arr = 0; +void minutes() +{ + mins ++; + timer.reset(); +} + void callback() { // Note: you need to actually read from the serial to clear the RX interrupt @@ -56,25 +66,234 @@ led2 = !led2; }*/ -void Btn1Pressed() +void btn2Pressed() { led1 = !led1; - btn1 = true; + btn2 = true; } -void Btn2Pressed() +void btn3Pressed() { led2 = !led2; - btn2 = true; + btn3 = true; } -void finish_disp() +void finish_disp () { done = true; return; } +/*Error Routine. + Displays "ERROR" on LCD screen and flashes leds + when called for an indefinite period of time +*/ +void error_custom () +{ + lcd.cls(); + lcd.printf("ERROR"); + led1 = 0; + led2 = 1; + while(1) + { + led1 = !led1; + led2 = !led2; + wait(0.5); + } +} +/*Alphanumeric selector + Used with char_sel function in order to select a number 0-9 or letters A-Z through user input. + Returns a char. +*/ +char alpha_num_sel (bool number) +{ + char n0 = '0'; + char n_tmp = '0'; + unsigned incr = 0; //used to increment characters between 0-9 or A-Z + unsigned mod; + if (number) + { + lcd.cls(); + lcd.printf("Pick\nNumber:%c",n_tmp); + n0 = '0'; + n_tmp = n0; + mod = 10; + } + else + { + lcd.cls(); + n0 = 'A'; + n_tmp = n0; + lcd.printf("Pick\nLetter:%c",n_tmp); + mod = 26; + } + while(1) + { + while(!btn2 && !btn3) //waits until button input received + { + wait(0.05); + } + if(btn3) + { + btn3 = false; + btn2 = false; //if both butons pressed, it just selects the current character + return (n_tmp); + } + else if(btn2) + { + btn2 = false; + incr ++; + incr = incr % mod; //ensures that numbers stay within the 0-9 range + n_tmp = n0 + incr; //increment current number selected + lcd.cls(); + if(number) + { + lcd.printf("Pick\nNumber:%c",n_tmp); //displays current number + } + else + { + lcd.printf("Pick\nLetter:%c",n_tmp); //displays current letter + } + } + else + { + error_custom(); + } + + } +} +/*Character Selection + Used with setup() function in order to pick a character A-Z and number 0-9 + for use as part of user id and/or team. Passed a 0 if selecting team letter (A-Z), + otherwise will select player id letter +*/ +char char_sel (bool player) +{ + if (player) + { + lcd.cls(); + lcd.printf("A-Z? or\n0-9?"); + while(!btn2 && !btn3) //waits until button input received + { + wait(0.05); + } + if(btn2) //if select button pressed, goes through numerical selection + { + btn2 = false; + btn3 = false; //if both buttons pressed at the same time, it just does numerical selection + + return(alpha_num_sel(1)); + } + else if(btn3) + { + btn3 = false; //pressing the option button in this case is the same as selecting a team + } + else + { + error_custom(); //if you somehow make it here without pressing buttons, it will throw an error + } + } +return(alpha_num_sel(0)); //returns capital alpha character for id or team by calling selection function +} + + +/*Setup Routine. + Sets the user id for use in-game. + Function must be passed an array of characters of size 15 + in order to work correctly. +*/ +void setup (char* ID_array) +{ + unsigned size = 1; + + lcd.cls(); + lcd.printf("ID Size?\n%u",size); + while(1) + { + while(!btn2 && !btn3) //waits until button input received + { + wait(0.05); //ensures buttons cannot be pressed extremely fast + } + if(btn2 && btn3) //routine to set size of player id in bytes + { + btn2 = false; //handling for simultaneous button pressing + btn3 = false; + size++; + if (size > 12) + { + size = 1; //ensures size cannot be greater than 12 or less than 1 + } + break; //sets size to whatever current size is +1 and moves on + } + else if(btn2) //increases size or loops back to 1, displays current size + { + btn2 = false; + size++; + if (size > 12) + { + size = 1; //ensures size cannot be greater than 12 or less than 1 + } + lcd.cls(); + lcd.printf("ID Size?\n%u",size); //displays current size + } + else if(btn3) + { + btn3 = false; //selects current size + break; + } + else + { + error_custom(); //error called if unexpected output + } + } + + for (unsigned j = 0; j < size; j ++) //sets player id + { + ID_array[j] = char_sel(1); + } + for (unsigned j = size; j < 12; j ++) + { + ID_array[j] = ' '; //fill unused characters with spaces + } + lcd.cls(); + lcd.printf("On team?\n Y or N"); + while(!btn2 && !btn3) //waits until button input received + { + wait(0.05); //ensures buttons cannot be pressed extremely fast + } + if(btn3) + { + btn3 = false; + btn2 = false; //you're on a team if you press both buttons + ID_array[12] = char_sel(0); //sets team letter + } + else if (btn2) + { + btn2 = false; + ID_array[12] = '0'; //sets team to 'zero', indicating no team + } + else + { + error_custom(); //throws an error if you somehow get here) + } + lcd.cls(); + lcd.printf("Your ID\n is:"); + wait(1.5); + lcd.cls(); + for(unsigned j = 0; j <= 12; j++) //prints out player id and team + { + lcd.printf("%c",ID_array[j]); + if (j == 7) + { + lcd.printf("\n"); //puts in a new line if id is longer than eight characters + } + } + crc16_attach(ID_array,13); //attaches crc bits to last two bits of 15 character array + wait(5); + return; +} + int main() { IR.attach(&callback); //attaches interrupt for serial buffer @@ -89,53 +308,90 @@ sw3.setSampleFrequency(); sw2.setAssertValue(0); //set buttons to be logic high when voltage is low. sw3.setAssertValue(0); - sw2.attach_asserted( &Btn1Pressed ); //attach button interrupts - sw3.attach_asserted( &Btn2Pressed ); + sw2.attach_asserted( &btn2Pressed ); //attach button interrupts + sw3.attach_asserted( &btn3Pressed ); + clock_tick.attach(&minutes, 60); //ticker interrupts every 60 seconds to add 1 minute and reset timer + timer.reset(); //ensure timer starts at 0 + timer.start(); //start reset timer + unsigned secs; led1 = 1; - char id = 'j'; - Timeout stats; - //stats.attach(&finish_disp, 5); - //bool done = false; - unsigned time; - unsigned time_compare = 0; - Timer timer; - - timer.reset(); //ensure timer starts at 0 - timer.start(); //start reset timer + char id[15]; //id array, capable of storing user ids up to 12 bytes with 1 byte for team and 2 bytes for CRC. + lcd.cls(); //ensure lcd starts with clear screen + lcd.printf("Choose \nYour ID."); + while(btn2 == false && btn3 == false) + { + wait(0.2); //wait to start setup until select button is pressed + } + btn2 = false; //reset button values + btn3 = false; + setup(id); //setup player id and team, passing function the id array while(1) { - time = timer.read(); + secs = timer.read(); lcd.cls(); - lcd.printf("%d", time); + lcd.printf("Mins:%u\nSecs:%u", mins,secs); + wait(1); //lcd.cls(); //lcd.printf("43%c%c%c!",c[0],c[1],c[2]); //IR.printf("%c%c%c",id); - if (btn1 == true) + + if (btn3 == true) + { + btn3 = false; + lcd.cls(); + if (crc16_match(id,2)) + { + lcd.printf("true"); + } + else + { + lcd.printf("false"); + } + wait(5); + } + + //crc16 matching test - works! + /*if (btn3 == true) { - btn1 = false; + btn3 = false; + lcd.cls(); + if (crc16_match(id,2)) + { + lcd.printf("true"); + } + else + { + lcd.printf("false"); + } + wait(5); + }*/ + + //statistics display test - works! + /* + if (btn2 == true) + { + btn2 = false; done = false; wait(0.05); stats.attach(&finish_disp, 5); + lcd.cls(); + lcd.printf("ID:%c%c%c%c", id[0],id[1],id[2],id[3]); while(!done) { - time = timer.read(); - lcd.cls(); - lcd.printf("New:%d", time); - if(btn1 == true) + if(btn2 == true) { - btn1 = false; + btn2 = false; stats.detach(); lcd.cls(); break; } - wait(0.5); + wait(0.2); } - } + }*/ //IR.printf("%c",id); - wait(1); } }