Sample TFT to KL25Z program.
Dependencies: SPI_STMPE610 TFT_fonts UniGraphic mbed
Fork of TFT_test_frdm-kl25z by
Diff: maze.cpp
- Revision:
- 3:34d8706e1614
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/maze.cpp Sat Aug 08 12:07:56 2015 +0000 @@ -0,0 +1,255 @@ +/** 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() ; +}