Accelerometer game
Dependencies: 4DGL-uLCD-SE ADXL345 mbed-rtos mbed
main.cpp@1:54ed477da4d3, 2014-03-20 (annotated)
- Committer:
- yhazrat3
- Date:
- Thu Mar 20 03:33:00 2014 +0000
- Revision:
- 1:54ed477da4d3
- Parent:
- 0:c69d1ec4d395
Done
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
yhazrat3 | 0:c69d1ec4d395 | 1 | #include "mbed.h" |
yhazrat3 | 0:c69d1ec4d395 | 2 | #include "rtos.h" |
yhazrat3 | 0:c69d1ec4d395 | 3 | #include "uLCD_4DGL.h" |
yhazrat3 | 0:c69d1ec4d395 | 4 | #include "ADXL345.h" |
yhazrat3 | 0:c69d1ec4d395 | 5 | |
yhazrat3 | 0:c69d1ec4d395 | 6 | |
yhazrat3 | 1:54ed477da4d3 | 7 | PwmOut speaker(p21); //create a PwmOut object for the speaker |
yhazrat3 | 0:c69d1ec4d395 | 8 | uLCD_4DGL uLCD(p28, p27, p29); // create a global lcd object |
yhazrat3 | 1:54ed477da4d3 | 9 | ADXL345 accelerometer(p5, p6, p7, p8);//create a global accelerometer object |
yhazrat3 | 1:54ed477da4d3 | 10 | Serial pc(USBTX, USBRX);// for debugging |
yhazrat3 | 1:54ed477da4d3 | 11 | Mutex lcd_mutex;// Create the mutex lock object |
yhazrat3 | 0:c69d1ec4d395 | 12 | |
yhazrat3 | 0:c69d1ec4d395 | 13 | int red_car_x, red_car_y,blue_car_x,blue_car_y,frog_x,frog_y,i,j; |
yhazrat3 | 0:c69d1ec4d395 | 14 | int x=0,y=0; |
yhazrat3 | 1:54ed477da4d3 | 15 | void thread1(void const *args)//thread 1 moves the red car |
yhazrat3 | 0:c69d1ec4d395 | 16 | { |
yhazrat3 | 0:c69d1ec4d395 | 17 | |
yhazrat3 | 1:54ed477da4d3 | 18 | while(true) { |
yhazrat3 | 1:54ed477da4d3 | 19 | //check for boundary conditions |
yhazrat3 | 0:c69d1ec4d395 | 20 | if(red_car_x>127){ |
yhazrat3 | 0:c69d1ec4d395 | 21 | red_car_x=-16; |
yhazrat3 | 0:c69d1ec4d395 | 22 | red_car_y=32; |
yhazrat3 | 0:c69d1ec4d395 | 23 | |
yhazrat3 | 0:c69d1ec4d395 | 24 | } |
yhazrat3 | 1:54ed477da4d3 | 25 | lcd_mutex.lock();//acquire lock |
yhazrat3 | 1:54ed477da4d3 | 26 | uLCD.filled_rectangle(red_car_x,red_car_y,red_car_x+15,red_car_y+15,0x000000);//erase previous position |
yhazrat3 | 0:c69d1ec4d395 | 27 | red_car_x=red_car_x+16; |
yhazrat3 | 0:c69d1ec4d395 | 28 | |
yhazrat3 | 0:c69d1ec4d395 | 29 | for(i=0;i<10;i++){ |
yhazrat3 | 0:c69d1ec4d395 | 30 | uLCD.filled_rectangle(red_car_x,red_car_y,red_car_x+15,red_car_y+15,0xFF3300);//change position |
yhazrat3 | 0:c69d1ec4d395 | 31 | |
yhazrat3 | 1:54ed477da4d3 | 32 | } |
yhazrat3 | 0:c69d1ec4d395 | 33 | |
yhazrat3 | 1:54ed477da4d3 | 34 | lcd_mutex.unlock();//release the lock |
yhazrat3 | 0:c69d1ec4d395 | 35 | Thread::wait(500); |
yhazrat3 | 0:c69d1ec4d395 | 36 | |
yhazrat3 | 0:c69d1ec4d395 | 37 | } |
yhazrat3 | 0:c69d1ec4d395 | 38 | } |
yhazrat3 | 0:c69d1ec4d395 | 39 | |
yhazrat3 | 0:c69d1ec4d395 | 40 | |
yhazrat3 | 1:54ed477da4d3 | 41 | void thread2(void const *args)//thread 1 moves the blue car, code similar to thread 1 |
yhazrat3 | 0:c69d1ec4d395 | 42 | { |
yhazrat3 | 0:c69d1ec4d395 | 43 | |
yhazrat3 | 1:54ed477da4d3 | 44 | while(true) { |
yhazrat3 | 1:54ed477da4d3 | 45 | |
yhazrat3 | 0:c69d1ec4d395 | 46 | if(blue_car_x>127){ |
yhazrat3 | 0:c69d1ec4d395 | 47 | blue_car_x=-16; |
yhazrat3 | 0:c69d1ec4d395 | 48 | blue_car_y=64; |
yhazrat3 | 0:c69d1ec4d395 | 49 | |
yhazrat3 | 0:c69d1ec4d395 | 50 | } |
yhazrat3 | 0:c69d1ec4d395 | 51 | lcd_mutex.lock(); |
yhazrat3 | 0:c69d1ec4d395 | 52 | uLCD.filled_rectangle(blue_car_x,blue_car_y,blue_car_x+15,blue_car_y+15,0x000000); |
yhazrat3 | 0:c69d1ec4d395 | 53 | blue_car_x=blue_car_x+16; |
yhazrat3 | 0:c69d1ec4d395 | 54 | for(i=0;i<5;i++){ |
yhazrat3 | 0:c69d1ec4d395 | 55 | uLCD.filled_rectangle(blue_car_x,blue_car_y,blue_car_x+15,blue_car_y+15,BLUE);//change position |
yhazrat3 | 0:c69d1ec4d395 | 56 | |
yhazrat3 | 0:c69d1ec4d395 | 57 | } |
yhazrat3 | 1:54ed477da4d3 | 58 | |
yhazrat3 | 0:c69d1ec4d395 | 59 | lcd_mutex.unlock(); |
yhazrat3 | 0:c69d1ec4d395 | 60 | Thread::wait(200); |
yhazrat3 | 0:c69d1ec4d395 | 61 | |
yhazrat3 | 0:c69d1ec4d395 | 62 | } |
yhazrat3 | 0:c69d1ec4d395 | 63 | } |
yhazrat3 | 0:c69d1ec4d395 | 64 | |
yhazrat3 | 1:54ed477da4d3 | 65 | void thread3(void const *args)//thread 3 plays the sound effects |
yhazrat3 | 0:c69d1ec4d395 | 66 | { |
yhazrat3 | 0:c69d1ec4d395 | 67 | |
yhazrat3 | 0:c69d1ec4d395 | 68 | |
yhazrat3 | 1:54ed477da4d3 | 69 | while(true) { |
yhazrat3 | 1:54ed477da4d3 | 70 | |
yhazrat3 | 0:c69d1ec4d395 | 71 | speaker.period(1.0/150.0); // 500hz period |
yhazrat3 | 0:c69d1ec4d395 | 72 | speaker =0.25; //25% duty cycle - mid range volume |
yhazrat3 | 0:c69d1ec4d395 | 73 | wait(.02); |
yhazrat3 | 1:54ed477da4d3 | 74 | speaker=0.0;//stop the speaker |
yhazrat3 | 1:54ed477da4d3 | 75 | |
yhazrat3 | 0:c69d1ec4d395 | 76 | Thread::wait(500); |
yhazrat3 | 0:c69d1ec4d395 | 77 | |
yhazrat3 | 0:c69d1ec4d395 | 78 | } |
yhazrat3 | 0:c69d1ec4d395 | 79 | } |
yhazrat3 | 1:54ed477da4d3 | 80 | |
yhazrat3 | 0:c69d1ec4d395 | 81 | int main() |
yhazrat3 | 0:c69d1ec4d395 | 82 | { |
yhazrat3 | 1:54ed477da4d3 | 83 | |
yhazrat3 | 1:54ed477da4d3 | 84 | A:uLCD.cls();// clear the LCD |
yhazrat3 | 0:c69d1ec4d395 | 85 | |
yhazrat3 | 0:c69d1ec4d395 | 86 | uLCD.text_width(2); //2X size text |
yhazrat3 | 0:c69d1ec4d395 | 87 | uLCD.text_height(2); |
yhazrat3 | 0:c69d1ec4d395 | 88 | |
yhazrat3 | 0:c69d1ec4d395 | 89 | |
yhazrat3 | 0:c69d1ec4d395 | 90 | uLCD.locate(2,2); |
yhazrat3 | 0:c69d1ec4d395 | 91 | |
yhazrat3 | 1:54ed477da4d3 | 92 | uLCD.printf("\n Frogger-G\n");//display the Title |
yhazrat3 | 0:c69d1ec4d395 | 93 | wait(0.1); |
yhazrat3 | 0:c69d1ec4d395 | 94 | |
yhazrat3 | 1:54ed477da4d3 | 95 | // Sound effects at the start of the game |
yhazrat3 | 0:c69d1ec4d395 | 96 | for (i=0; i<500; i=i+100) { |
yhazrat3 | 0:c69d1ec4d395 | 97 | speaker.period(1.0/float(i)); |
yhazrat3 | 0:c69d1ec4d395 | 98 | speaker=0.25; |
yhazrat3 | 0:c69d1ec4d395 | 99 | wait(.1); |
yhazrat3 | 0:c69d1ec4d395 | 100 | } |
yhazrat3 | 0:c69d1ec4d395 | 101 | wait(2); |
yhazrat3 | 0:c69d1ec4d395 | 102 | uLCD.cls(); |
yhazrat3 | 0:c69d1ec4d395 | 103 | uLCD.text_width(2); //2X size text |
yhazrat3 | 0:c69d1ec4d395 | 104 | uLCD.text_height(2); |
yhazrat3 | 0:c69d1ec4d395 | 105 | uLCD.locate(0,0); |
yhazrat3 | 0:c69d1ec4d395 | 106 | uLCD.color( 0xFF00FF); |
yhazrat3 | 0:c69d1ec4d395 | 107 | uLCD.printf("\n Help the frog \n cross \nthe road!\n"); |
yhazrat3 | 0:c69d1ec4d395 | 108 | wait (2); |
yhazrat3 | 0:c69d1ec4d395 | 109 | |
yhazrat3 | 0:c69d1ec4d395 | 110 | uLCD.cls(); |
yhazrat3 | 0:c69d1ec4d395 | 111 | |
yhazrat3 | 0:c69d1ec4d395 | 112 | |
yhazrat3 | 0:c69d1ec4d395 | 113 | red_car_x=0; |
yhazrat3 | 0:c69d1ec4d395 | 114 | red_car_y=32; |
yhazrat3 | 0:c69d1ec4d395 | 115 | blue_car_x=0; |
yhazrat3 | 0:c69d1ec4d395 | 116 | blue_car_y=64; |
yhazrat3 | 0:c69d1ec4d395 | 117 | frog_x=32; |
yhazrat3 | 0:c69d1ec4d395 | 118 | frog_y=96; |
yhazrat3 | 1:54ed477da4d3 | 119 | //initialize the frog position |
yhazrat3 | 0:c69d1ec4d395 | 120 | uLCD.filled_rectangle(frog_x,frog_y,frog_x+15,frog_y+15,0x99FF00); |
yhazrat3 | 0:c69d1ec4d395 | 121 | uLCD.filled_rectangle(red_car_x,red_car_y,red_car_x+15,red_car_y+15,0xff3300); |
yhazrat3 | 0:c69d1ec4d395 | 122 | uLCD.filled_rectangle(blue_car_x,blue_car_y,blue_car_x+15,blue_car_y+15,BLUE); |
yhazrat3 | 0:c69d1ec4d395 | 123 | |
yhazrat3 | 0:c69d1ec4d395 | 124 | int readings[3] = {0, 0, 0}; |
yhazrat3 | 0:c69d1ec4d395 | 125 | |
yhazrat3 | 1:54ed477da4d3 | 126 | //Go into standby mode to configure the device. |
yhazrat3 | 0:c69d1ec4d395 | 127 | accelerometer.setPowerControl(0x00); |
yhazrat3 | 0:c69d1ec4d395 | 128 | |
yhazrat3 | 0:c69d1ec4d395 | 129 | //Full resolution, +/-16g, 4mg/LSB. |
yhazrat3 | 0:c69d1ec4d395 | 130 | accelerometer.setDataFormatControl(0x0B); |
yhazrat3 | 0:c69d1ec4d395 | 131 | |
yhazrat3 | 0:c69d1ec4d395 | 132 | //3.2kHz data rate. |
yhazrat3 | 0:c69d1ec4d395 | 133 | accelerometer.setDataRate(ADXL345_3200HZ); |
yhazrat3 | 0:c69d1ec4d395 | 134 | |
yhazrat3 | 0:c69d1ec4d395 | 135 | //Measurement mode. |
yhazrat3 | 0:c69d1ec4d395 | 136 | accelerometer.setPowerControl(0x08); |
yhazrat3 | 1:54ed477da4d3 | 137 | //Initialize all threads |
yhazrat3 | 1:54ed477da4d3 | 138 | Thread t1(thread1); |
yhazrat3 | 1:54ed477da4d3 | 139 | Thread t2(thread2); |
yhazrat3 | 0:c69d1ec4d395 | 140 | Thread t3(thread3); |
yhazrat3 | 1:54ed477da4d3 | 141 | |
yhazrat3 | 0:c69d1ec4d395 | 142 | while (1) { |
yhazrat3 | 0:c69d1ec4d395 | 143 | |
yhazrat3 | 0:c69d1ec4d395 | 144 | |
yhazrat3 | 0:c69d1ec4d395 | 145 | for(i=0;i<5;i++) |
yhazrat3 | 1:54ed477da4d3 | 146 | //average accelerometer readings for accuracy |
yhazrat3 | 0:c69d1ec4d395 | 147 | { |
yhazrat3 | 0:c69d1ec4d395 | 148 | accelerometer.getOutput(readings); |
yhazrat3 | 0:c69d1ec4d395 | 149 | pc.printf("%i, %i, %i ", (int16_t)readings[0], (int16_t)readings[1], (int16_t)readings[2]); |
yhazrat3 | 0:c69d1ec4d395 | 150 | x=x+int16_t(readings[0]); |
yhazrat3 | 0:c69d1ec4d395 | 151 | y=y+int16_t(readings[1]); |
yhazrat3 | 0:c69d1ec4d395 | 152 | } |
yhazrat3 | 0:c69d1ec4d395 | 153 | x=int(x/5); |
yhazrat3 | 0:c69d1ec4d395 | 154 | y=int(y/5); |
yhazrat3 | 0:c69d1ec4d395 | 155 | |
yhazrat3 | 1:54ed477da4d3 | 156 | //debug |
yhazrat3 | 0:c69d1ec4d395 | 157 | pc.printf("%d, %d ", int(x),int(y) ); |
yhazrat3 | 1:54ed477da4d3 | 158 | |
yhazrat3 | 1:54ed477da4d3 | 159 | //move the frog according to accelerometer readings |
yhazrat3 | 1:54ed477da4d3 | 160 | //thresholds obtained through trial and error |
yhazrat3 | 1:54ed477da4d3 | 161 | //move right |
yhazrat3 | 0:c69d1ec4d395 | 162 | if(y>0){ |
yhazrat3 | 0:c69d1ec4d395 | 163 | lcd_mutex.lock(); |
yhazrat3 | 0:c69d1ec4d395 | 164 | uLCD.filled_rectangle(frog_x,frog_y,frog_x+15,frog_y+15,0x000000); |
yhazrat3 | 0:c69d1ec4d395 | 165 | frog_x=frog_x+16; |
yhazrat3 | 0:c69d1ec4d395 | 166 | |
yhazrat3 | 0:c69d1ec4d395 | 167 | uLCD.filled_rectangle(frog_x,frog_y,frog_x+15,frog_y+15,0x99FF00); |
yhazrat3 | 0:c69d1ec4d395 | 168 | lcd_mutex.unlock(); |
yhazrat3 | 0:c69d1ec4d395 | 169 | } |
yhazrat3 | 1:54ed477da4d3 | 170 | //move up |
yhazrat3 | 0:c69d1ec4d395 | 171 | if(x<70){ |
yhazrat3 | 0:c69d1ec4d395 | 172 | lcd_mutex.lock(); |
yhazrat3 | 0:c69d1ec4d395 | 173 | uLCD.filled_rectangle(frog_x,frog_y,frog_x+15,frog_y+15,0x000000); |
yhazrat3 | 0:c69d1ec4d395 | 174 | frog_y=frog_y-16; |
yhazrat3 | 0:c69d1ec4d395 | 175 | |
yhazrat3 | 0:c69d1ec4d395 | 176 | uLCD.filled_rectangle(frog_x,frog_y,frog_x+15,frog_y+15,0x99FF00); |
yhazrat3 | 0:c69d1ec4d395 | 177 | lcd_mutex.unlock(); |
yhazrat3 | 0:c69d1ec4d395 | 178 | } |
yhazrat3 | 1:54ed477da4d3 | 179 | //move left |
yhazrat3 | 0:c69d1ec4d395 | 180 | if(y<-70){ |
yhazrat3 | 0:c69d1ec4d395 | 181 | lcd_mutex.lock(); |
yhazrat3 | 0:c69d1ec4d395 | 182 | uLCD.filled_rectangle(frog_x,frog_y,frog_x+15,frog_y+15,0x000000); |
yhazrat3 | 0:c69d1ec4d395 | 183 | frog_x=frog_x-16; |
yhazrat3 | 0:c69d1ec4d395 | 184 | |
yhazrat3 | 0:c69d1ec4d395 | 185 | uLCD.filled_rectangle(frog_x,frog_y,frog_x+15,frog_y+15,0x99FF00); |
yhazrat3 | 0:c69d1ec4d395 | 186 | lcd_mutex.unlock(); |
yhazrat3 | 0:c69d1ec4d395 | 187 | } |
yhazrat3 | 1:54ed477da4d3 | 188 | //move down |
yhazrat3 | 0:c69d1ec4d395 | 189 | if(x>180){ |
yhazrat3 | 0:c69d1ec4d395 | 190 | lcd_mutex.lock(); |
yhazrat3 | 0:c69d1ec4d395 | 191 | uLCD.filled_rectangle(frog_x,frog_y,frog_x+15,frog_y+15,0x000000); |
yhazrat3 | 0:c69d1ec4d395 | 192 | frog_y=frog_y+16; |
yhazrat3 | 0:c69d1ec4d395 | 193 | |
yhazrat3 | 0:c69d1ec4d395 | 194 | uLCD.filled_rectangle(frog_x,frog_y,frog_x+15,frog_y+15,0x99FF00); |
yhazrat3 | 0:c69d1ec4d395 | 195 | lcd_mutex.unlock(); |
yhazrat3 | 0:c69d1ec4d395 | 196 | } |
yhazrat3 | 0:c69d1ec4d395 | 197 | |
yhazrat3 | 1:54ed477da4d3 | 198 | //check collisions |
yhazrat3 | 0:c69d1ec4d395 | 199 | if ((frog_x==red_car_x & frog_y==red_car_y)|(frog_x==blue_car_x & frog_y==blue_car_y)) |
yhazrat3 | 0:c69d1ec4d395 | 200 | { |
yhazrat3 | 0:c69d1ec4d395 | 201 | lcd_mutex.lock(); |
yhazrat3 | 0:c69d1ec4d395 | 202 | uLCD.cls(); |
yhazrat3 | 1:54ed477da4d3 | 203 | |
yhazrat3 | 1:54ed477da4d3 | 204 | uLCD.text_width(2); //2X size text |
yhazrat3 | 0:c69d1ec4d395 | 205 | uLCD.text_height(2); |
yhazrat3 | 0:c69d1ec4d395 | 206 | uLCD.color(RED); |
yhazrat3 | 0:c69d1ec4d395 | 207 | uLCD.locate(2,2); |
yhazrat3 | 1:54ed477da4d3 | 208 | uLCD.printf("\n GAME \n OVER!\n");// display message |
yhazrat3 | 0:c69d1ec4d395 | 209 | speaker.period(1.0/500.0); // 500hz period |
yhazrat3 | 0:c69d1ec4d395 | 210 | speaker =0.5; //50% duty cycle - max volume |
yhazrat3 | 0:c69d1ec4d395 | 211 | wait(3); |
yhazrat3 | 0:c69d1ec4d395 | 212 | speaker=0.0; // turn off audio |
yhazrat3 | 0:c69d1ec4d395 | 213 | |
yhazrat3 | 0:c69d1ec4d395 | 214 | wait(2); |
yhazrat3 | 0:c69d1ec4d395 | 215 | lcd_mutex.unlock(); |
yhazrat3 | 1:54ed477da4d3 | 216 | goto A;//restart the game |
yhazrat3 | 0:c69d1ec4d395 | 217 | } |
yhazrat3 | 1:54ed477da4d3 | 218 | //check if frog has crossed the road |
yhazrat3 | 0:c69d1ec4d395 | 219 | if (frog_y<32) |
yhazrat3 | 0:c69d1ec4d395 | 220 | { |
yhazrat3 | 0:c69d1ec4d395 | 221 | |
yhazrat3 | 0:c69d1ec4d395 | 222 | lcd_mutex.lock(); |
yhazrat3 | 0:c69d1ec4d395 | 223 | uLCD.cls(); |
yhazrat3 | 1:54ed477da4d3 | 224 | |
yhazrat3 | 1:54ed477da4d3 | 225 | uLCD.text_width(2); //2X size text |
yhazrat3 | 0:c69d1ec4d395 | 226 | uLCD.text_height(2); |
yhazrat3 | 0:c69d1ec4d395 | 227 | uLCD.color(0xffff00); |
yhazrat3 | 0:c69d1ec4d395 | 228 | uLCD.locate(2,2); |
yhazrat3 | 1:54ed477da4d3 | 229 | uLCD.printf("\n You \n WIN!\n");//display message |
yhazrat3 | 0:c69d1ec4d395 | 230 | |
yhazrat3 | 0:c69d1ec4d395 | 231 | for (i=0; i<500; i=i+100) { |
yhazrat3 | 0:c69d1ec4d395 | 232 | speaker.period(1.0/float(i)); |
yhazrat3 | 0:c69d1ec4d395 | 233 | speaker=0.25; |
yhazrat3 | 0:c69d1ec4d395 | 234 | wait(.1); |
yhazrat3 | 0:c69d1ec4d395 | 235 | } |
yhazrat3 | 0:c69d1ec4d395 | 236 | wait(5); |
yhazrat3 | 0:c69d1ec4d395 | 237 | lcd_mutex.unlock(); |
yhazrat3 | 1:54ed477da4d3 | 238 | goto A;//restart the game |
yhazrat3 | 0:c69d1ec4d395 | 239 | } |
yhazrat3 | 0:c69d1ec4d395 | 240 | |
yhazrat3 | 0:c69d1ec4d395 | 241 | |
yhazrat3 | 0:c69d1ec4d395 | 242 | Thread::wait(50); // wait 0.5s |
yhazrat3 | 0:c69d1ec4d395 | 243 | } |
yhazrat3 | 0:c69d1ec4d395 | 244 | |
yhazrat3 | 0:c69d1ec4d395 | 245 | |
yhazrat3 | 0:c69d1ec4d395 | 246 | |
yhazrat3 | 0:c69d1ec4d395 | 247 | } |