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.
