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.

http://image.bayimg.com/cac8c520471e3a172d44580c8e233cb76283ccf2.jpg

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

http://i.imgur.com/k6BIRPc.png

  • mbed NXP LPC1768 Microcontroller
  • MMA8452q accelerometer
MBed PinMMA8542q Signal Name
VO3.3v
SDASDA
SCLSCL
GndGnd

(100 Ohm Resistors in series on I2C line )

  • uLCD-144-G2 128 BY 128 Smart Color LCD
MBed PinLCD Signal Name
VU5v
GndGnd
TXRX
RXTX
p29Reset

128 by 128 Color Smart LCD with serial interface and SD card slot

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.