ELEC2645 (2015/16) / Mbed 2 deprecated SnakeProjectRev1

Dependencies:   Joystick N5110 SDFileSystem beep fsmMenu mbed

Fork of SnakeProjectRev1 by Meurig Phillips

Committer:
meurigp
Date:
Tue Apr 05 19:39:22 2016 +0000
Revision:
2:663b9aadf00c
Parent:
1:97ac723959f2
Child:
3:0e3179c452c5
snake head correct movement, random fruit working

Who changed what in which revision?

UserRevisionLine numberNew contents of line
meurigp 0:fcb5a32bc2fc 1 /* Joystick
meurigp 0:fcb5a32bc2fc 2
meurigp 0:fcb5a32bc2fc 3 Example code of how to read a joystick
meurigp 0:fcb5a32bc2fc 4
meurigp 0:fcb5a32bc2fc 5 https://www.sparkfun.com/products/9032
meurigp 0:fcb5a32bc2fc 6
meurigp 0:fcb5a32bc2fc 7 Craig A. Evans
meurigp 0:fcb5a32bc2fc 8 7 March 2015
meurigp 0:fcb5a32bc2fc 9 */
meurigp 0:fcb5a32bc2fc 10
meurigp 0:fcb5a32bc2fc 11 #include "mbed.h"
meurigp 0:fcb5a32bc2fc 12 #include "N5110.h"
meurigp 0:fcb5a32bc2fc 13
meurigp 0:fcb5a32bc2fc 14 // change this to alter tolerance of joystick direction
meurigp 0:fcb5a32bc2fc 15 #define DIRECTION_TOLERANCE 0.05
meurigp 0:fcb5a32bc2fc 16
meurigp 0:fcb5a32bc2fc 17 // VCC, SCE, RST, D/C, MOSI, SCLK, LED
meurigp 0:fcb5a32bc2fc 18 N5110 lcd (PTD3, PTA0 , PTC4 , PTD0 , PTD2 , PTD1 , PTC3);
meurigp 0:fcb5a32bc2fc 19 // Can also power (VCC) directly from VOUT (3.3 V) -
meurigp 0:fcb5a32bc2fc 20 // Can give better performance due to current limitation from GPIO pin
meurigp 0:fcb5a32bc2fc 21
meurigp 0:fcb5a32bc2fc 22 // connections for joystick
meurigp 0:fcb5a32bc2fc 23 DigitalIn button(PTB18);
meurigp 1:97ac723959f2 24 AnalogIn xPot(PTC11);
meurigp 1:97ac723959f2 25 AnalogIn yPot(PTC10);
meurigp 0:fcb5a32bc2fc 26
meurigp 0:fcb5a32bc2fc 27 // timer to regularly read the joystick
meurigp 0:fcb5a32bc2fc 28 Ticker pollJoystick;
meurigp 0:fcb5a32bc2fc 29 // Serial for debug
meurigp 0:fcb5a32bc2fc 30 Serial serial(USBTX,USBRX);
meurigp 2:663b9aadf00c 31
meurigp 2:663b9aadf00c 32
meurigp 0:fcb5a32bc2fc 33
meurigp 0:fcb5a32bc2fc 34 // create enumerated type (0,1,2,3 etc. for direction)
meurigp 0:fcb5a32bc2fc 35 // could be extended for diagonals etc.
meurigp 0:fcb5a32bc2fc 36 enum DirectionName {
meurigp 0:fcb5a32bc2fc 37 UP,
meurigp 0:fcb5a32bc2fc 38 DOWN,
meurigp 0:fcb5a32bc2fc 39 LEFT,
meurigp 0:fcb5a32bc2fc 40 RIGHT,
meurigp 0:fcb5a32bc2fc 41 CENTRE,
meurigp 0:fcb5a32bc2fc 42 UNKNOWN
meurigp 0:fcb5a32bc2fc 43 };
meurigp 0:fcb5a32bc2fc 44
meurigp 0:fcb5a32bc2fc 45 /// create enumerated type (0,1,2,3 etc. for current direction snake is travelling (not joystick reading))
meurigp 0:fcb5a32bc2fc 46 enum CurrentDirection {
meurigp 0:fcb5a32bc2fc 47 up,
meurigp 0:fcb5a32bc2fc 48 down,
meurigp 0:fcb5a32bc2fc 49 left,
meurigp 0:fcb5a32bc2fc 50 right,
meurigp 0:fcb5a32bc2fc 51 centre,
meurigp 0:fcb5a32bc2fc 52 };
meurigp 0:fcb5a32bc2fc 53 CurrentDirection currentDirection = centre; /// intialise direction at beginning
meurigp 0:fcb5a32bc2fc 54
meurigp 0:fcb5a32bc2fc 55 // struct for Joystick
meurigp 0:fcb5a32bc2fc 56 typedef struct JoyStick Joystick;
meurigp 0:fcb5a32bc2fc 57 struct JoyStick {
meurigp 0:fcb5a32bc2fc 58 float x; // current x value
meurigp 0:fcb5a32bc2fc 59 float x0; // 'centred' x value
meurigp 0:fcb5a32bc2fc 60 float y; // current y value
meurigp 0:fcb5a32bc2fc 61 float y0; // 'centred' y value
meurigp 0:fcb5a32bc2fc 62 int button; // button state (assume pull-down used, so 1 = pressed, 0 = unpressed)
meurigp 0:fcb5a32bc2fc 63 DirectionName direction; // current direction
meurigp 0:fcb5a32bc2fc 64 };
meurigp 0:fcb5a32bc2fc 65 // create struct variable
meurigp 0:fcb5a32bc2fc 66 Joystick joystick;
meurigp 0:fcb5a32bc2fc 67
meurigp 0:fcb5a32bc2fc 68 int printFlag = 0;
meurigp 0:fcb5a32bc2fc 69
meurigp 2:663b9aadf00c 70 int pixels[84][48];
meurigp 2:663b9aadf00c 71
meurigp 2:663b9aadf00c 72 int randomX = rand() % 83 + 1; // randomX in the range 1 to 81
meurigp 2:663b9aadf00c 73 int randomY = rand() % 47 + 1; // randomY in the range 1 to 47
meurigp 2:663b9aadf00c 74 int randomXoddEven = randomX%2; // find out whether odd or even
meurigp 2:663b9aadf00c 75 int randomYoddEven = randomY%2;
meurigp 2:663b9aadf00c 76
meurigp 0:fcb5a32bc2fc 77 // function prototypes
meurigp 0:fcb5a32bc2fc 78 void calibrateJoystick();
meurigp 0:fcb5a32bc2fc 79 void updateJoystick();
meurigp 2:663b9aadf00c 80 void generateFood();
meurigp 0:fcb5a32bc2fc 81
meurigp 0:fcb5a32bc2fc 82 int main()
meurigp 0:fcb5a32bc2fc 83 {
meurigp 2:663b9aadf00c 84
meurigp 0:fcb5a32bc2fc 85 calibrateJoystick(); // get centred values of joystick
meurigp 0:fcb5a32bc2fc 86 pollJoystick.attach(&updateJoystick,1.0/10.0); // read joystick 10 times per second
meurigp 2:663b9aadf00c 87
meurigp 0:fcb5a32bc2fc 88
meurigp 2:663b9aadf00c 89 int i = 41; // snake head origin x
meurigp 2:663b9aadf00c 90 int j = 23; // snake head origin y
meurigp 2:663b9aadf00c 91
meurigp 2:663b9aadf00c 92 srand(time(NULL));
meurigp 2:663b9aadf00c 93
meurigp 0:fcb5a32bc2fc 94
meurigp 0:fcb5a32bc2fc 95 lcd.init();
meurigp 2:663b9aadf00c 96 lcd.drawRect(i,j,1,1,1); // default snake position
meurigp 2:663b9aadf00c 97
meurigp 2:663b9aadf00c 98 generateFood();
meurigp 0:fcb5a32bc2fc 99
meurigp 0:fcb5a32bc2fc 100 while(1) {
meurigp 0:fcb5a32bc2fc 101
meurigp 0:fcb5a32bc2fc 102 if (printFlag) { // if flag set, clear flag and print joystick values to serial port
meurigp 0:fcb5a32bc2fc 103 printFlag = 0;
meurigp 0:fcb5a32bc2fc 104 serial.printf("x = %f y = %f button = %d ",joystick.x,joystick.y,joystick.button);
meurigp 0:fcb5a32bc2fc 105
meurigp 0:fcb5a32bc2fc 106 // check joystick direction
meurigp 0:fcb5a32bc2fc 107 if (joystick.direction == UP)
meurigp 0:fcb5a32bc2fc 108 serial.printf(" UP\n");
meurigp 0:fcb5a32bc2fc 109 if (joystick.direction == DOWN)
meurigp 0:fcb5a32bc2fc 110 serial.printf(" DOWN\n");
meurigp 0:fcb5a32bc2fc 111 if (joystick.direction == LEFT)
meurigp 0:fcb5a32bc2fc 112 serial.printf(" LEFT\n");
meurigp 0:fcb5a32bc2fc 113 if (joystick.direction == RIGHT)
meurigp 0:fcb5a32bc2fc 114 serial.printf(" RIGHT\n");
meurigp 0:fcb5a32bc2fc 115 if (joystick.direction == CENTRE)
meurigp 0:fcb5a32bc2fc 116 serial.printf(" CENTRE\n");
meurigp 0:fcb5a32bc2fc 117 if (joystick.direction == UNKNOWN)
meurigp 0:fcb5a32bc2fc 118 serial.printf(" Unsupported direction\n");
meurigp 0:fcb5a32bc2fc 119
meurigp 2:663b9aadf00c 120 if (joystick.direction == LEFT) {
meurigp 1:97ac723959f2 121 if (currentDirection != right) { // user can't turn opposite way
meurigp 1:97ac723959f2 122 currentDirection = left; // direct enum updated
meurigp 0:fcb5a32bc2fc 123 }
meurigp 1:97ac723959f2 124 while (currentDirection == left) { // enters left movement loop
meurigp 0:fcb5a32bc2fc 125 lcd.clear();
meurigp 2:663b9aadf00c 126 i -= 2; // shifts two pixels (snake thickness)
meurigp 2:663b9aadf00c 127 lcd.drawRect(i,j,1,1,1); // snake head
meurigp 2:663b9aadf00c 128 lcd.drawRect(randomX,randomY,1,1,1); // food
meurigp 2:663b9aadf00c 129 if (i == randomX && j == randomY) {
meurigp 2:663b9aadf00c 130 randomX = rand() % 83 + 1; // randomX in the range 1 to 81
meurigp 2:663b9aadf00c 131 randomY = rand() % 47 + 1; // randomY in the range 1 to 47
meurigp 2:663b9aadf00c 132 randomXoddEven = randomX%2; // find out whether odd or even
meurigp 2:663b9aadf00c 133 randomYoddEven = randomY%2;
meurigp 2:663b9aadf00c 134 generateFood();
meurigp 2:663b9aadf00c 135 }
meurigp 0:fcb5a32bc2fc 136 wait(1.0);
meurigp 2:663b9aadf00c 137 if (joystick.direction == UP) {
meurigp 1:97ac723959f2 138 currentDirection = up; // direction enum updated, this while loop ends, up while loop starts
meurigp 1:97ac723959f2 139 }
meurigp 2:663b9aadf00c 140 if (joystick.direction == DOWN) {
meurigp 1:97ac723959f2 141 currentDirection = down; // direction enum updated, this while loop ends, down while loop starts
meurigp 1:97ac723959f2 142 }
meurigp 0:fcb5a32bc2fc 143 }
meurigp 0:fcb5a32bc2fc 144 }
meurigp 2:663b9aadf00c 145 if (joystick.direction == RIGHT) {
meurigp 0:fcb5a32bc2fc 146 if (currentDirection != left) {
meurigp 0:fcb5a32bc2fc 147 currentDirection = right;
meurigp 0:fcb5a32bc2fc 148 }
meurigp 0:fcb5a32bc2fc 149 while (currentDirection == right) {
meurigp 0:fcb5a32bc2fc 150 lcd.clear();
meurigp 2:663b9aadf00c 151 i += 2;
meurigp 2:663b9aadf00c 152 lcd.drawRect(i,j,1,1,1); // snake head
meurigp 2:663b9aadf00c 153 lcd.drawRect(randomX,randomY,1,1,1); // food
meurigp 2:663b9aadf00c 154 if (i == randomX && j == randomY) {
meurigp 2:663b9aadf00c 155 randomX = rand() % 83 + 1; // randomX in the range 1 to 81
meurigp 2:663b9aadf00c 156 randomY = rand() % 47 + 1; // randomY in the range 1 to 47
meurigp 2:663b9aadf00c 157 randomXoddEven = randomX%2; // find out whether odd or even
meurigp 2:663b9aadf00c 158 randomYoddEven = randomY%2;
meurigp 2:663b9aadf00c 159 generateFood();
meurigp 2:663b9aadf00c 160 }
meurigp 0:fcb5a32bc2fc 161 wait(1.0);
meurigp 2:663b9aadf00c 162 if (joystick.direction == UP) {
meurigp 1:97ac723959f2 163 currentDirection = up; // direction enum updated, this while loop ends, up while loop starts
meurigp 1:97ac723959f2 164 }
meurigp 2:663b9aadf00c 165 if (joystick.direction == DOWN) {
meurigp 1:97ac723959f2 166 currentDirection = down; // direction enum updated, this while loop ends, down while loop starts
meurigp 1:97ac723959f2 167 }
meurigp 0:fcb5a32bc2fc 168 }
meurigp 0:fcb5a32bc2fc 169 }
meurigp 2:663b9aadf00c 170 if (joystick.direction == UP) {
meurigp 0:fcb5a32bc2fc 171 if (currentDirection != down) {
meurigp 0:fcb5a32bc2fc 172 currentDirection = up;
meurigp 0:fcb5a32bc2fc 173 }
meurigp 0:fcb5a32bc2fc 174 while (currentDirection == up) {
meurigp 0:fcb5a32bc2fc 175 lcd.clear();
meurigp 2:663b9aadf00c 176 j -= 2;
meurigp 2:663b9aadf00c 177 lcd.drawRect(i,j,1,1,1); // snake head
meurigp 2:663b9aadf00c 178 lcd.drawRect(randomX,randomY,1,1,1); // food
meurigp 2:663b9aadf00c 179 if (i == randomX && j == randomY) {
meurigp 2:663b9aadf00c 180 randomX = rand() % 83 + 1; // randomX in the range 1 to 81
meurigp 2:663b9aadf00c 181 randomY = rand() % 47 + 1; // randomY in the range 1 to 47
meurigp 2:663b9aadf00c 182 randomXoddEven = randomX%2; // find out whether odd or even
meurigp 2:663b9aadf00c 183 randomYoddEven = randomY%2;
meurigp 2:663b9aadf00c 184 generateFood();
meurigp 2:663b9aadf00c 185 }
meurigp 0:fcb5a32bc2fc 186 wait(1.0);
meurigp 2:663b9aadf00c 187 if (joystick.direction == LEFT) {
meurigp 1:97ac723959f2 188 currentDirection = left; // direction enum updated, this while loop ends, left while loop starts
meurigp 1:97ac723959f2 189 }
meurigp 2:663b9aadf00c 190 if (joystick.direction == RIGHT) {
meurigp 1:97ac723959f2 191 currentDirection = right; // direction enum updated, this while loop ends, right while loop starts
meurigp 1:97ac723959f2 192 }
meurigp 0:fcb5a32bc2fc 193 }
meurigp 0:fcb5a32bc2fc 194 }
meurigp 2:663b9aadf00c 195 if (joystick.direction == DOWN) {
meurigp 0:fcb5a32bc2fc 196 if (currentDirection != up) {
meurigp 0:fcb5a32bc2fc 197 currentDirection = down;
meurigp 0:fcb5a32bc2fc 198 }
meurigp 0:fcb5a32bc2fc 199 while (currentDirection == down) {
meurigp 0:fcb5a32bc2fc 200 lcd.clear();
meurigp 2:663b9aadf00c 201 j += 2;
meurigp 2:663b9aadf00c 202 lcd.drawRect(i,j,1,1,1); // snake head
meurigp 2:663b9aadf00c 203 lcd.drawRect(randomX,randomY,1,1,1); // food
meurigp 2:663b9aadf00c 204 if (i == randomX && j == randomY) {
meurigp 2:663b9aadf00c 205 randomX = rand() % 83 + 1; // randomX in the range 1 to 81
meurigp 2:663b9aadf00c 206 randomY = rand() % 47 + 1; // randomY in the range 1 to 47
meurigp 2:663b9aadf00c 207 randomXoddEven = randomX%2; // find out whether odd or even
meurigp 2:663b9aadf00c 208 randomYoddEven = randomY%2;
meurigp 2:663b9aadf00c 209 generateFood();
meurigp 2:663b9aadf00c 210 }
meurigp 0:fcb5a32bc2fc 211 wait(1.0);
meurigp 2:663b9aadf00c 212 if (joystick.direction == LEFT) {
meurigp 1:97ac723959f2 213 currentDirection = left; // direction enum updated, this while loop ends, left while loop starts
meurigp 1:97ac723959f2 214 }
meurigp 2:663b9aadf00c 215 if (joystick.direction == RIGHT) {
meurigp 1:97ac723959f2 216 currentDirection = right; // direction enum updated, this while loop ends, right while loop starts
meurigp 1:97ac723959f2 217 }
meurigp 0:fcb5a32bc2fc 218 }
meurigp 0:fcb5a32bc2fc 219 }
meurigp 1:97ac723959f2 220
meurigp 0:fcb5a32bc2fc 221
meurigp 0:fcb5a32bc2fc 222
meurigp 0:fcb5a32bc2fc 223 }
meurigp 2:663b9aadf00c 224 // put the MCU to sleep until an interrupt wakes it up
meurigp 2:663b9aadf00c 225 sleep();
meurigp 0:fcb5a32bc2fc 226 }
meurigp 0:fcb5a32bc2fc 227 }
meurigp 0:fcb5a32bc2fc 228
meurigp 0:fcb5a32bc2fc 229 // read default positions of the joystick to calibrate later readings
meurigp 0:fcb5a32bc2fc 230 void calibrateJoystick()
meurigp 0:fcb5a32bc2fc 231 {
meurigp 0:fcb5a32bc2fc 232 button.mode(PullDown);
meurigp 0:fcb5a32bc2fc 233 // must not move during calibration
meurigp 0:fcb5a32bc2fc 234 joystick.x0 = xPot; // initial positions in the range 0.0 to 1.0 (0.5 if centred exactly)
meurigp 0:fcb5a32bc2fc 235 joystick.y0 = yPot;
meurigp 0:fcb5a32bc2fc 236 }
meurigp 0:fcb5a32bc2fc 237 void updateJoystick()
meurigp 0:fcb5a32bc2fc 238 {
meurigp 0:fcb5a32bc2fc 239 // read current joystick values relative to calibrated values (in range -0.5 to 0.5, 0.0 is centred)
meurigp 0:fcb5a32bc2fc 240 joystick.x = xPot - joystick.x0;
meurigp 0:fcb5a32bc2fc 241 joystick.y = yPot - joystick.y0;
meurigp 0:fcb5a32bc2fc 242 // read button state
meurigp 0:fcb5a32bc2fc 243 joystick.button = button;
meurigp 0:fcb5a32bc2fc 244
meurigp 0:fcb5a32bc2fc 245 // calculate direction depending on x,y values
meurigp 0:fcb5a32bc2fc 246 // tolerance allows a little lee-way in case joystick not exactly in the stated direction
meurigp 0:fcb5a32bc2fc 247 if ( fabs(joystick.y) < DIRECTION_TOLERANCE && fabs(joystick.x) < DIRECTION_TOLERANCE) {
meurigp 0:fcb5a32bc2fc 248 joystick.direction = CENTRE;
meurigp 0:fcb5a32bc2fc 249 } else if ( joystick.y > DIRECTION_TOLERANCE && fabs(joystick.x) < DIRECTION_TOLERANCE) {
meurigp 0:fcb5a32bc2fc 250 joystick.direction = UP;
meurigp 0:fcb5a32bc2fc 251 } else if ( joystick.y < DIRECTION_TOLERANCE && fabs(joystick.x) < DIRECTION_TOLERANCE) {
meurigp 0:fcb5a32bc2fc 252 joystick.direction = DOWN;
meurigp 0:fcb5a32bc2fc 253 } else if ( joystick.x > DIRECTION_TOLERANCE && fabs(joystick.y) < DIRECTION_TOLERANCE) {
meurigp 0:fcb5a32bc2fc 254 joystick.direction = RIGHT;
meurigp 0:fcb5a32bc2fc 255 } else if ( joystick.x < DIRECTION_TOLERANCE && fabs(joystick.y) < DIRECTION_TOLERANCE) {
meurigp 0:fcb5a32bc2fc 256 joystick.direction = LEFT;
meurigp 0:fcb5a32bc2fc 257 } else {
meurigp 0:fcb5a32bc2fc 258 joystick.direction = UNKNOWN;
meurigp 0:fcb5a32bc2fc 259 }
meurigp 0:fcb5a32bc2fc 260
meurigp 0:fcb5a32bc2fc 261 // set flag for printing
meurigp 0:fcb5a32bc2fc 262 printFlag = 1;
meurigp 0:fcb5a32bc2fc 263 }
meurigp 1:97ac723959f2 264
meurigp 2:663b9aadf00c 265 void generateFood()
meurigp 1:97ac723959f2 266 {
meurigp 2:663b9aadf00c 267 while (randomXoddEven ==0 || randomYoddEven ==0 || lcd.getPixel(randomX,randomY) >= 1) { // do while x or y is even or pixel is on
meurigp 2:663b9aadf00c 268
meurigp 2:663b9aadf00c 269 randomX = rand() % 83 + 1; // randomX in the range 1 to 81
meurigp 2:663b9aadf00c 270 randomY = rand() % 47 + 1; // randomY in the range 1 to 47
meurigp 2:663b9aadf00c 271
meurigp 2:663b9aadf00c 272 serial.printf("X = %i\n",randomX); // debug
meurigp 2:663b9aadf00c 273 serial.printf("Y = %i\n\n",randomY);
meurigp 2:663b9aadf00c 274
meurigp 2:663b9aadf00c 275 randomXoddEven = randomX%2; // find out whether odd or even
meurigp 2:663b9aadf00c 276 randomYoddEven = randomY%2;
meurigp 2:663b9aadf00c 277 }
meurigp 2:663b9aadf00c 278
meurigp 2:663b9aadf00c 279 lcd.drawRect(randomX,randomY,1,1,1);
meurigp 1:97ac723959f2 280
meurigp 1:97ac723959f2 281 }
meurigp 1:97ac723959f2 282
meurigp 1:97ac723959f2 283
meurigp 0:fcb5a32bc2fc 284