Mini Project LCD Maze
Overview
We have created a maze where player control uses accelerometer input. It uses an MBed ARM microcontroller, an accelerometer over I2C, and an lcd screen for display.
Code was written in C++ on the Mbed cloud compiler. Using a main loop and several conditional statements and a binary array to create the map. The different game states are:
- Intro / loading map
- Play state
- Win state
Components
- mbed NXP LPC1768 Microcontroller
- MMA8452q accelerometer
MBed Pin | MMA8542q Signal Name |
---|---|
VO | 3.3v |
SDA | SDA |
SCL | SCL |
Gnd | Gnd |
(100 Ohm Resistors in series on I2C line )
- uLCD-144-G2 128 BY 128 Smart Color LCD
MBed Pin | LCD Signal Name |
---|---|
VU | 5v |
Gnd | Gnd |
TX | RX |
RX | TX |
p29 | Reset |
Source Code
/* For the orientation of our accelerometer: +y -> move left -y -> move right +x -> move up -x -> move down It appears that a good threshold to begin actual movements would be around +-0.35 */ #include "mbed.h" #include "uLCD_4DGL.h" //LCD #include "MMA8452.h" //Accelerometer //This is so ugly it's not even funny... but I'm limited by memory right now... and std::vectors are taking up a lot of memory int fullMazeArray[50][100] = { {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}, //row1 {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}, //row2 {....} // Rows 3-50 }; //LCD Screen uLCD_4DGL uLCD(p28, p27, p29); // create a global lcd object //DO NOT MOVE --V THIS NEEDS TO BE HERE Serial pc(USBTX,USBRX); //OUTSIDE OF MAIN FOR MMA LIBRARY TO WORK void drawMaze(); //Declare the drawMaze function, defined below main //Accelerometer axis double x = 0,y = 0,z = 0; //Start location is at row: 45, column 27 int playerLocation[2] = {45, 27}; int currentPlayerRow; int currentPlayerCol; int main() { //Go ahead and initialize all the accelerometer details. MMA8452 acc(p9, p10, 40000); acc.setBitDepth(MMA8452::BIT_DEPTH_12); acc.setDynamicRange(MMA8452::DYNAMIC_RANGE_4G); acc.setDataRate(MMA8452::RATE_100); //Set LCD baudrate uLCD.baudrate(3000000); //Draw the maze to the screen drawMaze(); uLCD.pixel(playerLocation[1], playerLocation[0], RED); //Winning location (Blue): row: 5-9 column: 83-87 bool solved = false; //Puzze is solved flag. while(!solved) { if(!acc.isXYZReady()) { wait(0.01); continue; } acc.readXYZGravity(&x,&y,&z); //FUTURE: To make better, switch statement possibly bool flag = false; //TODO: Remove if(y > 0.35){ //Move left //Save the current location of the player. So that we can rewrite that pixel to background color currentPlayerRow = playerLocation[0]; currentPlayerCol = playerLocation[1]; //Using the current player location, determine first if the spot to the left is out of bounds if((currentPlayerCol-1) >= 0){ //This is checking the left wall //Then determine the spot to the left if it's not a wall if(!(fullMazeArray[currentPlayerRow][currentPlayerCol-1] == 1)){ //Either moveable area, or solution area //If it isn't, update playerLocation[]/draw playerLocation/draw old currentPlayerLocs/update currentPlayerLocs playerLocation[1] = currentPlayerCol-1; uLCD.pixel(playerLocation[1], playerLocation[0], RED); uLCD.pixel(currentPlayerCol, currentPlayerRow, WHITE); currentPlayerCol = currentPlayerCol-1; //If the spot is a two, solved = true; if(fullMazeArray[currentPlayerRow][currentPlayerCol] == 2){ solved = true; } }else{ //It's a wall } }else{ //Not a valid loc } } if(y < -0.35){ //Move right //Save the current location of the player. So that we can rewrite that pixel to background color currentPlayerRow = playerLocation[0]; currentPlayerCol = playerLocation[1]; if((currentPlayerCol+1) < 100){ //This is checking the right wall if(!(fullMazeArray[currentPlayerRow][currentPlayerCol+1] == 1)){ //Either moveable area, or solution area //If it isn't, update playerLocation[]/draw playerLocation/draw old currentPlayerLocs/update currentPlayerLocs playerLocation[1] = currentPlayerCol+1; uLCD.pixel(playerLocation[1], playerLocation[0], RED); uLCD.pixel(currentPlayerCol, currentPlayerRow, WHITE); currentPlayerCol = currentPlayerCol+1; //If the spot is a two, solved = true; if(fullMazeArray[currentPlayerRow][currentPlayerCol] == 2){ solved = true; } }else{ //It's a wall } }else{ //Not a valid loc } } if(x > 0.35){ //Move up //Save the current location of the player. So that we can rewrite that pixel to background color currentPlayerRow = playerLocation[0]; currentPlayerCol = playerLocation[1]; if((currentPlayerRow-1) >= 0){ //This is checking the upper wall if(!(fullMazeArray[currentPlayerRow-1][currentPlayerCol] == 1)){ //Either moveable area, or solution area //If it isn't, update playerLocation[]/draw playerLocation/draw old currentPlayerLocs/update currentPlayerLocs playerLocation[0] = currentPlayerRow-1; uLCD.pixel(playerLocation[1], playerLocation[0], RED); uLCD.pixel(currentPlayerCol, currentPlayerRow, WHITE); currentPlayerRow = currentPlayerRow-1; //If the spot is a two, solved = true; if(fullMazeArray[currentPlayerRow][currentPlayerCol] == 2){ solved = true; } }else{ //It's a wall } }else{ //Not a valid loc } } if(x < -0.35){ //Move down //Save the current location of the player. So that we can rewrite that pixel to background color currentPlayerRow = playerLocation[0]; currentPlayerCol = playerLocation[1]; if((currentPlayerRow+1) < 100){ //This is checking the bottom wall if(!(fullMazeArray[currentPlayerRow+1][currentPlayerCol] == 1)){ //Either moveable area, or solution area //If it isn't, update playerLocation[]/draw playerLocation/draw old currentPlayerLocs/update currentPlayerLocs playerLocation[0] = currentPlayerRow+1; uLCD.pixel(playerLocation[1], playerLocation[0], RED); uLCD.pixel(currentPlayerCol, currentPlayerRow, WHITE); currentPlayerRow = currentPlayerRow+1; //If the spot is a two, solved = true; if(fullMazeArray[currentPlayerRow][currentPlayerCol] == 2){ solved = true; } }else{ //It's a wall } }else{ //Not a valid loc } } wait(0.125); //Delay for appropriate game speed } uLCD.locate(0,7); uLCD.printf("WINNER!!!"); } void drawMaze(){ int i, j; //Indexes into array for (i = 0; i<50; i++){ for(j = 0; j<100; j++){ //array[row][column] if(fullMazeArray[i][j] == 1){ //A 1 for our definition is a wall uLCD.pixel(j,i,GREEN); }else if(fullMazeArray[i][j] == 2){ //Else a 2 is the solution uLCD.pixel(j,i,BLUE); }else{ //Else a 0 is empty space uLCD.pixel(j,i,WHITE); } } } }
References
http://developer.mbed.org/users/ashleymills/code/MMA8452/file/dfb0f6a7a455/MMA8452.cpp Accelerometer http://developer.mbed.org/users/4180_1/notebook/ulcd-144-g2-128-by-128-color-lcd/ Lcd Screen
Please log in to post comments.