Sample TFT to KL25Z program.
Dependencies: SPI_STMPE610 TFT_fonts UniGraphic mbed
Fork of TFT_test_frdm-kl25z by
maze.cpp
- Committer:
- Rhyme
- Date:
- 2015-08-08
- Revision:
- 3:34d8706e1614
File content as of revision 3:34d8706e1614:
/** maze_vt100 a simple maze using UniGraphic and MMA8451Q libraries */ #include "mbed.h" #include "MMA8451Q.h" #include <ILI9341.h> #include "Arial12x12.h" #include "Arial24x23.h" #include "Arial28x28.h" #include "Arial43x48_numb.h" #include "maze.h" #define CELL_W 10 #define CELL_H 10 #define CELL_S 5 #define CELL_R 4 #define LEFT_OFFSET 20 #define TOP_OFFSET 20 #define DIR_STAY 0 #define DIR_UP 1 #define DIR_DOWN 2 #define DIR_RIGHT 3 #define DIR_LEFT 4 #define MMA8451_I2C_ADDRESS (0x1D<<1) typedef struct _pos { int x ; int y ; } pos_type ; extern MMA8451Q *acc ; extern ILI9341 TFT ; extern DigitalOut backlight ; float threshold = 0.2 ; /** Check if two pos_type values are same * @param pos_type a * @param pos_type b * @returns if a and b are same position */ bool isSame(pos_type a, pos_type b) { return((a.x == b.x)&&(a.y == b.y)) ; } /** Draw the maze defined in the "maze.h" * @param pos_type *current actually the start point * @param pos_type *goal the position of the goal * @note those params are actually returned by this function */ void drawTFTMaze(pos_type *current, pos_type *goal) { int x, y, i, j ; TFT.BusEnable(true) ; backlight = 0 ; TFT.foreground(White) ; TFT.background(Black) ; TFT.cls() ; for (j = 0 ; j < MAZE_H ; j++ ) { for (i = 0 ; i < MAZE_W ; i++ ) { x = i * CELL_W + LEFT_OFFSET ; y = j * CELL_H + TOP_OFFSET ; switch(maze[j][i]) { case 0: // path TFT.fillrect(x, y, x+CELL_W-1, y+CELL_H-1, Black) ; break ; case 1: // wall TFT.fillrect(x, y, x+CELL_W-1, y+CELL_H-1, DarkGrey) ; break ; case 2: // Start point TFT.fillcircle(x+CELL_S, y+CELL_S, CELL_R, Green) ; current->x = i ; current->y = j ; break ; case 3: // Goal TFT.fillcircle(x+CELL_S, y+CELL_S, CELL_R, Red) ; goal->x = i ; goal->y = j ; break ; default: // should not be here break ; } } } backlight = 1 ; TFT.BusEnable(false) ; } /** Filter out too little move * @param float in returned value from the acc * @returns float result filtered value of in */ float filterVal(float in) { float result = 0.0 ; if ((-threshold > in)||(in > threshold)) { result = in ; } return( result ) ; } /** Decide which direction to go * @param float res[] acc value of x, y * @returns int direction to move */ int getDirection(float res[]) { float dx, dy ; int direction = DIR_STAY ; dx = filterVal(res[0]) ; dy = filterVal(res[1]) ; if ((dx*dx) > (dy*dy)) { // holizontal move if (dx > 0.0) { direction = DIR_DOWN ; } else if (dx < 0.0) { direction = DIR_UP ; } } else { // vertical move if (dy > 0.0) { direction = DIR_RIGHT ; } else if (dy < 0.0) { direction = DIR_LEFT ; } } return(direction) ; } /** Get next positon to move to * @param pos_type current where we are now * @param int direction which way we'd like to move * @returns the candidate positon for the next move */ pos_type getNext(pos_type current, int direction) { pos_type next = current ; switch(direction) { case DIR_STAY: break ; case DIR_UP: if (next.y > 0) { next.y-- ; } break ; case DIR_DOWN: if (next.y < (MAZE_H - 1)) { next.y++ ; } break ; case DIR_RIGHT: if (next.x < (MAZE_W - 1)) { next.x++ ; } break ; case DIR_LEFT: if (next.x > 0) { next.x-- ; } break ; default: break ; } return( next ) ; } /** Notice of the goal */ void showGoal(void) { int x0, y0, x1, y1 ; x0 = ((MAZE_W/2)-4) * CELL_W + LEFT_OFFSET ; y0 = ((MAZE_H/2)-1) * CELL_H + TOP_OFFSET ; x1 = ((MAZE_W/2)+4) * CELL_W + LEFT_OFFSET ; y1 = ((MAZE_H/2)+1) * CELL_H + TOP_OFFSET ; TFT.BusEnable(true) ; // TFT.set_font((unsigned char*) Arial12x12); TFT.set_font((unsigned char*) Terminal6x8) ; TFT.fillrect(x0, y0, x1, y1, Blue) ; TFT.rect(x0,y0,x1,y1, Yellow) ; TFT.foreground(Red) ; TFT.background(Blue) ; x0 = ((MAZE_W/2) - 2) * CELL_W + LEFT_OFFSET ; y0 = (MAZE_H/2) * CELL_H - 3 + TOP_OFFSET ; TFT.locate(x0, y0) ; TFT.printf("G O A L") ; TFT.foreground(Yellow) ; TFT.background(Black) ; TFT.locate(30, 300) ; // TFT.printf("Use FRDM touch slider") ; TFT.printf(" Retry! ") ; TFT.locate(5, 300) ; TFT.printf("<< Prev") ; TFT.locate(180, 300) ; TFT.printf("Next >>") ; TFT.BusEnable(false) ; } /** Check if we can move to the next position * @param pos_type next the position we'd like to move next * @returns if the position is empty (movable) */ bool checkMove(pos_type next) { bool result = false ; switch(maze[next.y][next.x]) { case POS_PATH: case POS_GOAL: result = true ; break ; case POS_START: case POS_WALL: default: result = false ; break ; } return( result ) ; } /** main a simple maze program */ void doMaze(void) { float res[3] ; pos_type current, next, goal ; int direction = DIR_STAY ; int x, y ; drawTFTMaze(¤t, &goal) ; for (;;) { acc->getAccAllAxis(res) ; direction = getDirection(res) ; next = getNext(current, direction) ; if ((!isSame(current, next)) && checkMove(next)) { TFT.BusEnable(true) ; x = current.x * CELL_W + LEFT_OFFSET ; y = current.y * CELL_H + TOP_OFFSET ; TFT.fillrect(x, y, x+CELL_W-1, y+CELL_H-1, Black) ; x = next.x * CELL_W + LEFT_OFFSET ; y = next.y * CELL_H + TOP_OFFSET ; TFT.fillcircle(x+CELL_S, y+CELL_S, CELL_R, Green) ; TFT.BusEnable(false) ; current = next ; if (isSame(next, goal)) { break ; // goal in! } } wait(0.1) ; } showGoal() ; }