Two player imu pong

Dependencies:   4DGL-uLCD-SE IMUfilter LSM9DS0 PinDetect mbed

Committer:
rrr93
Date:
Thu Oct 22 16:50:22 2015 +0000
Revision:
0:941225f01ccc
qewrt

Who changed what in which revision?

UserRevisionLine numberNew contents of line
rrr93 0:941225f01ccc 1 #include "mbed.h"
rrr93 0:941225f01ccc 2 #include "PinDetect.h"
rrr93 0:941225f01ccc 3 #include "uLCD_4DGL.h"
rrr93 0:941225f01ccc 4 #include "Speaker.h"
rrr93 0:941225f01ccc 5 #include "paddle.h"
rrr93 0:941225f01ccc 6 #include "ball.h"
rrr93 0:941225f01ccc 7 #include "soundBuilder.h"
rrr93 0:941225f01ccc 8 #include "LSM9DS0.h"
rrr93 0:941225f01ccc 9
rrr93 0:941225f01ccc 10 Serial pc(USBTX, USBRX);
rrr93 0:941225f01ccc 11 //IMU
rrr93 0:941225f01ccc 12 // SDO_XM and SDO_G are pulled up, so our addresses are:
rrr93 0:941225f01ccc 13 #define LSM9DS0_XM_ADDR 0x1D // Would be 0x1E if SDO_XM is LOW
rrr93 0:941225f01ccc 14 #define LSM9DS0_G_ADDR 0x6B // Would be 0x6A if SDO_G is LOW
rrr93 0:941225f01ccc 15 LSM9DS0 imu(p9, p10, LSM9DS0_G_ADDR, LSM9DS0_XM_ADDR);
rrr93 0:941225f01ccc 16 LSM9DS0 imu2(p28,p27, LSM9DS0_G_ADDR, LSM9DS0_XM_ADDR);
rrr93 0:941225f01ccc 17
rrr93 0:941225f01ccc 18 // Pushbuttons
rrr93 0:941225f01ccc 19 PinDetect pbUp(p15);
rrr93 0:941225f01ccc 20 PinDetect pbDown(p16);
rrr93 0:941225f01ccc 21 // uLCD
rrr93 0:941225f01ccc 22 uLCD_4DGL uLCD(p13, p14, p29);
rrr93 0:941225f01ccc 23 //Speaker
rrr93 0:941225f01ccc 24 Speaker mySpeaker(p21);
rrr93 0:941225f01ccc 25
rrr93 0:941225f01ccc 26 // Global variables needed for the push button interrupts
rrr93 0:941225f01ccc 27 Paddle paddle(40, 3, 118,1);
rrr93 0:941225f01ccc 28 Paddle paddle2(40,3, 8, 1);
rrr93 0:941225f01ccc 29 Ball ball(p19, 1.6,1.2,5,50,21);
rrr93 0:941225f01ccc 30
rrr93 0:941225f01ccc 31 // State machine definitions
rrr93 0:941225f01ccc 32 enum gameStateType {START, WAIT, GAME_SETUP, GAME, LOSE};
rrr93 0:941225f01ccc 33 /* State Definitions:
rrr93 0:941225f01ccc 34 * START -- Creates the start screen
rrr93 0:941225f01ccc 35 * WAIT -- After the start screen, goes into wait where mbed spins and does nothing
rrr93 0:941225f01ccc 36 * GAME_SETUP -- Sets up one time things (like boarders, initializes beginning velocity
rrr93 0:941225f01ccc 37 * GAME -- When the user actually gets to play
rrr93 0:941225f01ccc 38 * LOSE -- clears the screen, prints you lose, waits, then goes back to start
rrr93 0:941225f01ccc 39 */
rrr93 0:941225f01ccc 40
rrr93 0:941225f01ccc 41 // Global state machine variable (So that the pushbuttons can modify it)
rrr93 0:941225f01ccc 42 gameStateType gameState = START;
rrr93 0:941225f01ccc 43
rrr93 0:941225f01ccc 44 // Pushbutton callbacks
rrr93 0:941225f01ccc 45 // WARNING: Do not call to draw anything to the uLCD in these
rrr93 0:941225f01ccc 46 // as this will cause the uLCD to crash sometimes. Update positions
rrr93 0:941225f01ccc 47 // and draw elsewhere (like it's done here).
rrr93 0:941225f01ccc 48 // Only modify the logic inside the callback functions.
rrr93 0:941225f01ccc 49 void pbUp_hit_callback (void)
rrr93 0:941225f01ccc 50 {
rrr93 0:941225f01ccc 51 switch (gameState)
rrr93 0:941225f01ccc 52 {
rrr93 0:941225f01ccc 53 case WAIT:
rrr93 0:941225f01ccc 54 gameState = GAME_SETUP;
rrr93 0:941225f01ccc 55 break;
rrr93 0:941225f01ccc 56 case GAME:
rrr93 0:941225f01ccc 57 paddle.movePaddle(true);
rrr93 0:941225f01ccc 58 paddle2.movePaddle(true);
rrr93 0:941225f01ccc 59 break;
rrr93 0:941225f01ccc 60 }
rrr93 0:941225f01ccc 61 }
rrr93 0:941225f01ccc 62
rrr93 0:941225f01ccc 63 void pbDown_hit_callback (void)
rrr93 0:941225f01ccc 64 {
rrr93 0:941225f01ccc 65 switch (gameState)
rrr93 0:941225f01ccc 66 {
rrr93 0:941225f01ccc 67 case WAIT:
rrr93 0:941225f01ccc 68 gameState = GAME_SETUP;
rrr93 0:941225f01ccc 69 break;
rrr93 0:941225f01ccc 70 case GAME:
rrr93 0:941225f01ccc 71 paddle.movePaddle(false);
rrr93 0:941225f01ccc 72 paddle2.movePaddle(false);
rrr93 0:941225f01ccc 73 break;
rrr93 0:941225f01ccc 74 }
rrr93 0:941225f01ccc 75 }
rrr93 0:941225f01ccc 76
rrr93 0:941225f01ccc 77 int main()
rrr93 0:941225f01ccc 78 {
rrr93 0:941225f01ccc 79
rrr93 0:941225f01ccc 80 //IMU
rrr93 0:941225f01ccc 81 uint16_t status = imu.begin();
rrr93 0:941225f01ccc 82 //Make sure communication is working
rrr93 0:941225f01ccc 83 pc.printf("LSM9DS0 WHO_AM_I's returned: 0x%X\n", status);
rrr93 0:941225f01ccc 84 pc.printf("Should be 0x49D4\n\n");
rrr93 0:941225f01ccc 85
rrr93 0:941225f01ccc 86 uint16_t status2 = imu2.begin();
rrr93 0:941225f01ccc 87 //Make sure communication is working
rrr93 0:941225f01ccc 88 pc.printf("LSM9DS0 #2 WHO_AM_I's returned: 0x%X\n", status2);
rrr93 0:941225f01ccc 89 pc.printf("Should be 0x49D4\n\n");
rrr93 0:941225f01ccc 90
rrr93 0:941225f01ccc 91
rrr93 0:941225f01ccc 92
rrr93 0:941225f01ccc 93 float IMU_offset = 0.14; //detrmined empirically
rrr93 0:941225f01ccc 94
rrr93 0:941225f01ccc 95 // This is setting up the pushbuttons
rrr93 0:941225f01ccc 96 // Don't modify this code.
rrr93 0:941225f01ccc 97 pbUp.mode(PullUp);
rrr93 0:941225f01ccc 98 pbDown.mode(PullUp);
rrr93 0:941225f01ccc 99 wait(0.1);
rrr93 0:941225f01ccc 100 pbUp.attach_deasserted(&pbUp_hit_callback);
rrr93 0:941225f01ccc 101 pbDown.attach_deasserted(&pbDown_hit_callback);
rrr93 0:941225f01ccc 102 pbUp.setSampleFrequency();
rrr93 0:941225f01ccc 103 pbDown.setSampleFrequency();
rrr93 0:941225f01ccc 104 // Don't modify this code.
rrr93 0:941225f01ccc 105
rrr93 0:941225f01ccc 106 uLCD.display_control(PORTRAIT);
rrr93 0:941225f01ccc 107 uLCD.cls();
rrr93 0:941225f01ccc 108 uLCD.baudrate(BAUD_3000000);
rrr93 0:941225f01ccc 109 uLCD.background_color(BLACK);
rrr93 0:941225f01ccc 110
rrr93 0:941225f01ccc 111 // Initialize all your variables outside the while/switch statement
rrr93 0:941225f01ccc 112 // to avoid compiler warning/errors
rrr93 0:941225f01ccc 113 int i = 0;
rrr93 0:941225f01ccc 114 int random;
rrr93 0:941225f01ccc 115
rrr93 0:941225f01ccc 116 //paddle stuff
rrr93 0:941225f01ccc 117 int pmoveMin = 25;
rrr93 0:941225f01ccc 118 int pmoveMax = 70;
rrr93 0:941225f01ccc 119 int pmove;
rrr93 0:941225f01ccc 120
rrr93 0:941225f01ccc 121 while (1)
rrr93 0:941225f01ccc 122 {
rrr93 0:941225f01ccc 123 switch (gameState)
rrr93 0:941225f01ccc 124 {
rrr93 0:941225f01ccc 125 case START:
rrr93 0:941225f01ccc 126 uLCD.cls();
rrr93 0:941225f01ccc 127 uLCD.locate(0,0);
rrr93 0:941225f01ccc 128 uLCD.printf("Pong!!!\n\n");
rrr93 0:941225f01ccc 129 uLCD.printf("Press Key to Start");
rrr93 0:941225f01ccc 130 gameState = WAIT;
rrr93 0:941225f01ccc 131 ball.setX(50);
rrr93 0:941225f01ccc 132 ball.setY(50);
rrr93 0:941225f01ccc 133 break;
rrr93 0:941225f01ccc 134 case GAME_SETUP:
rrr93 0:941225f01ccc 135 uLCD.cls();
rrr93 0:941225f01ccc 136 uLCD.line(0, 0, 127, 0, 0xCFB53B);
rrr93 0:941225f01ccc 137 uLCD.line(127, 0, 127, 127, 0xCFB53B);
rrr93 0:941225f01ccc 138 uLCD.line(127, 127, 0, 127, 0xCFB53B);
rrr93 0:941225f01ccc 139 uLCD.line(0, 127, 0, 0, 0xCFB53B);
rrr93 0:941225f01ccc 140 ball.setBaseVx(2.0);
rrr93 0:941225f01ccc 141 ball.setBaseVy(2.0);
rrr93 0:941225f01ccc 142 random = rand() % 1;
rrr93 0:941225f01ccc 143 ball.setVxSign(-1); ball.setVySign(((float)random - 0.5)*2);
rrr93 0:941225f01ccc 144 paddle.initDraw(&uLCD);
rrr93 0:941225f01ccc 145 paddle2.initDraw(&uLCD);
rrr93 0:941225f01ccc 146
rrr93 0:941225f01ccc 147 Note note1(4000.0, 0.7, 0.5);
rrr93 0:941225f01ccc 148 Note note2(3000.0, 0.3, 0.5);
rrr93 0:941225f01ccc 149 Note note3(2000.0, 0.3, 0.5);
rrr93 0:941225f01ccc 150 Note note4(1000.0, 0.7, 0.5);
rrr93 0:941225f01ccc 151 Note note5(2500.0, 0.3, 0.5);
rrr93 0:941225f01ccc 152 SoundBuilder sound(&mySpeaker);
rrr93 0:941225f01ccc 153 sound.addNote(note1);
rrr93 0:941225f01ccc 154 sound.addNote(note2);
rrr93 0:941225f01ccc 155 sound.addNote(note3);
rrr93 0:941225f01ccc 156 sound.addNote(note4);
rrr93 0:941225f01ccc 157 sound.addNote(note5);
rrr93 0:941225f01ccc 158 sound.playSong();
rrr93 0:941225f01ccc 159 gameState = GAME;
rrr93 0:941225f01ccc 160 break;
rrr93 0:941225f01ccc 161 case GAME:
rrr93 0:941225f01ccc 162 if(ball.CheckHit())
rrr93 0:941225f01ccc 163 {
rrr93 0:941225f01ccc 164 Note note(1000.0, 0.03, 0.5);
rrr93 0:941225f01ccc 165 SoundBuilder sound(&mySpeaker);
rrr93 0:941225f01ccc 166 sound.addNote(note);
rrr93 0:941225f01ccc 167 sound.playSong();
rrr93 0:941225f01ccc 168 }
rrr93 0:941225f01ccc 169
rrr93 0:941225f01ccc 170 if (paddle.checkHitY(ball.getFutureX(), ball.getFutureY(), ball.getRadius()))
rrr93 0:941225f01ccc 171 {
rrr93 0:941225f01ccc 172
rrr93 0:941225f01ccc 173 ball.reverseYDirection();
rrr93 0:941225f01ccc 174 }
rrr93 0:941225f01ccc 175
rrr93 0:941225f01ccc 176 if (paddle2.checkHitY(ball.getFutureX(), ball.getFutureY(), ball.getRadius()))
rrr93 0:941225f01ccc 177 {
rrr93 0:941225f01ccc 178
rrr93 0:941225f01ccc 179 ball.reverseYDirection();
rrr93 0:941225f01ccc 180 }
rrr93 0:941225f01ccc 181
rrr93 0:941225f01ccc 182 if (ball.CheckLose())
rrr93 0:941225f01ccc 183 {gameState = LOSE;}
rrr93 0:941225f01ccc 184 if (paddle.checkHitX(ball.getFutureX(), ball.getFutureY(), ball.getRadius(),false))
rrr93 0:941225f01ccc 185 {
rrr93 0:941225f01ccc 186 Note note(4000.0, 0.03, 0.5);
rrr93 0:941225f01ccc 187 SoundBuilder sound(&mySpeaker);
rrr93 0:941225f01ccc 188 sound.addNote(note);
rrr93 0:941225f01ccc 189 sound.playSong();
rrr93 0:941225f01ccc 190
rrr93 0:941225f01ccc 191 ball.reverseXDirection();
rrr93 0:941225f01ccc 192 uLCD.locate(1,1);
rrr93 0:941225f01ccc 193 }
rrr93 0:941225f01ccc 194
rrr93 0:941225f01ccc 195 if (paddle2.checkHitX(ball.getFutureX(), ball.getFutureY(), ball.getRadius(),true))
rrr93 0:941225f01ccc 196 {
rrr93 0:941225f01ccc 197 Note note(4000.0, 0.03, 0.5);
rrr93 0:941225f01ccc 198 SoundBuilder sound(&mySpeaker);
rrr93 0:941225f01ccc 199 sound.addNote(note);
rrr93 0:941225f01ccc 200 sound.playSong();
rrr93 0:941225f01ccc 201 ball.reverseXDirection();
rrr93 0:941225f01ccc 202 uLCD.locate(1,1);
rrr93 0:941225f01ccc 203 }
rrr93 0:941225f01ccc 204
rrr93 0:941225f01ccc 205
rrr93 0:941225f01ccc 206 ball.update(&uLCD);
rrr93 0:941225f01ccc 207 imu.readAccel();
rrr93 0:941225f01ccc 208
rrr93 0:941225f01ccc 209 imu2.readAccel();
rrr93 0:941225f01ccc 210
rrr93 0:941225f01ccc 211 if ( imu.ax + IMU_offset > 0.1)
rrr93 0:941225f01ccc 212 {
rrr93 0:941225f01ccc 213 paddle.movePaddle(true);
rrr93 0:941225f01ccc 214 }
rrr93 0:941225f01ccc 215 else if (imu.ax+ IMU_offset < -0.1)
rrr93 0:941225f01ccc 216 {
rrr93 0:941225f01ccc 217 paddle.movePaddle(false);
rrr93 0:941225f01ccc 218 }
rrr93 0:941225f01ccc 219
rrr93 0:941225f01ccc 220 if ( imu2.ax + IMU_offset > 0.1)
rrr93 0:941225f01ccc 221 {
rrr93 0:941225f01ccc 222 paddle2.movePaddle(true);
rrr93 0:941225f01ccc 223 }
rrr93 0:941225f01ccc 224 else if (imu2.ax+ IMU_offset < -0.1)
rrr93 0:941225f01ccc 225 {
rrr93 0:941225f01ccc 226 paddle2.movePaddle(false);
rrr93 0:941225f01ccc 227 }
rrr93 0:941225f01ccc 228
rrr93 0:941225f01ccc 229 // We can assume that these for loops are quick enough that the paddle will move only one interval.
rrr93 0:941225f01ccc 230 // These movements of the paddle have been optimized. Feel free to draw it out to see how it's been done.
rrr93 0:941225f01ccc 231 paddle.redraw(&uLCD);
rrr93 0:941225f01ccc 232 paddle2.redraw(&uLCD);
rrr93 0:941225f01ccc 233 break;
rrr93 0:941225f01ccc 234 case LOSE:
rrr93 0:941225f01ccc 235 uLCD.cls();
rrr93 0:941225f01ccc 236 uLCD.printf("YOU LOSE D:");
rrr93 0:941225f01ccc 237 Note note6(3000.0, 0.7, 0.5);
rrr93 0:941225f01ccc 238 Note note7(2000.0, 0.3, 0.5);
rrr93 0:941225f01ccc 239 Note note8(1000.0, 0.3, 0.5);
rrr93 0:941225f01ccc 240 Note note9(2300.0, 0.7, 0.5);
rrr93 0:941225f01ccc 241 Note note10(2500.0, 0.3, 0.5);
rrr93 0:941225f01ccc 242 SoundBuilder sound2(&mySpeaker);
rrr93 0:941225f01ccc 243 sound2.addNote(note6);
rrr93 0:941225f01ccc 244 sound2.addNote(note7);
rrr93 0:941225f01ccc 245 sound2.addNote(note8);
rrr93 0:941225f01ccc 246 sound2.addNote(note9);
rrr93 0:941225f01ccc 247 sound2.addNote(note10);
rrr93 0:941225f01ccc 248 sound2.playSong();
rrr93 0:941225f01ccc 249 paddle.resetScore();
rrr93 0:941225f01ccc 250 paddle2.resetScore();
rrr93 0:941225f01ccc 251 wait(5.0);
rrr93 0:941225f01ccc 252 gameState = START;
rrr93 0:941225f01ccc 253 break;
rrr93 0:941225f01ccc 254 case WAIT:
rrr93 0:941225f01ccc 255 // Used to seed the rand() function so we don't get the same starting position every time.
rrr93 0:941225f01ccc 256 i++;
rrr93 0:941225f01ccc 257 break;
rrr93 0:941225f01ccc 258 }
rrr93 0:941225f01ccc 259 }
rrr93 0:941225f01ccc 260 }