My simple maze program with UniGraphic library version.

Dependencies:   MMA8451Q UniGraphic mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 /** maze_vt100 a simple maze using UniGraphic and MMA8451Q libraries
00002  */
00003 #include "mbed.h"
00004 #include "MMA8451Q.h"
00005 #include <ILI9341.h>
00006 #include "Arial12x12.h"
00007 #include "Arial24x23.h"
00008 #include "Arial28x28.h"
00009 #include "Arial43x48_numb.h"
00010 #include "maze.h"
00011 
00012 #if   defined (TARGET_KL25Z) 
00013 #define PIN_MOSI        PTD2
00014 #define PIN_MISO        PTD3 
00015 #define PIN_SCLK        PTD1 
00016 #define PIN_CS_TFT      PTD0 
00017 #define PIN_DC_TFT      PTD5 
00018 #define PIN_BL_TFT      PTC9 
00019 #define PIN_CS_SD       PTA4 
00020 #define PIN_CS_TSC      PTA13
00021 #define PIN_TSC_INTR    PTC9
00022 #define PIN_RESET_TFT   PTB10
00023 #else
00024   #error TARGET NOT DEFINED
00025 #endif
00026 
00027 #define DIR_STAY  0
00028 #define DIR_UP    1
00029 #define DIR_DOWN  2
00030 #define DIR_RIGHT 3 
00031 #define DIR_LEFT  4
00032 
00033 #define MMA8451_I2C_ADDRESS (0x1D<<1)
00034 
00035 typedef struct _pos {
00036     int x ;
00037     int y ;
00038 } pos_type ;
00039 
00040 MMA8451Q acc(PTE25, PTE24, MMA8451_I2C_ADDRESS) ;
00041 float threshold = 0.2 ;
00042 
00043 DigitalOut backlight(PTA12) ;
00044 ILI9341 TFT(SPI_8, 10000000, 
00045     PIN_MOSI, PIN_MISO,  PIN_SCLK, 
00046     PIN_CS_TFT, PIN_RESET_TFT, PIN_DC_TFT, "Adafruit2.8") ;
00047 
00048 /** Check if two pos_type values are same
00049  * @param pos_type a
00050  * @param pos_type b
00051  * @returns if a and b are same position
00052  */
00053 bool isSame(pos_type a, pos_type b)
00054 {
00055     return((a.x == b.x)&&(a.y == b.y)) ;
00056 }
00057 
00058 /** Draw the maze defined in the "maze.h"
00059  * @param pos_type *current actually the start point
00060  * @param pos_type *goal the position of the goal
00061  * @note those params are actually returned by this function
00062  */
00063 void drawTFTMaze(pos_type *current, pos_type *goal)
00064 {
00065     int x, y, i, j ;
00066     TFT.BusEnable(true) ;
00067     
00068     backlight = 0 ;
00069     for (j = 0 ; j < MAZE_H ; j++ ) {
00070         for (i = 0 ; i < MAZE_W ; i++ ) {
00071             x = i * 10 ;
00072             y = j * 10 ;
00073             switch(maze[j][i]) {
00074             case 0: // path
00075                 TFT.fillrect(x, y, x+9, y+9, Black) ;
00076                 break ;
00077             case 1: // wall
00078                 TFT.fillrect(x, y, x+9, y+9, DarkGrey) ;
00079                 break ;
00080             case 2: // Start point
00081                 TFT.fillcircle(x+5, y+4, 4, Green) ;
00082                 current->x = i ;
00083                 current->y = j ;
00084                 break ;
00085             case 3: // Goal
00086                 TFT.fillcircle(x+5, y+4, 4, Red) ;
00087                 goal->x = i ;
00088                 goal->y = j ;
00089                 break ;
00090             default: // should not be here
00091                 break ;
00092             }
00093         }
00094     }
00095     backlight = 1 ;
00096     TFT.BusEnable(false) ;
00097 }
00098 
00099 /** Filter out too little move 
00100  * @param float in returned value from the acc
00101  * @returns float result filtered value of in
00102  */
00103 float filterVal(float in)
00104 {
00105     float result = 0.0 ;
00106     if ((-threshold > in)||(in > threshold)) {
00107         result = in ;
00108     }
00109     return( result ) ;
00110 }
00111 
00112 /** Decide which direction to go
00113  * @param float res[] acc value of x, y 
00114  * @returns int direction to move 
00115  */
00116 int getDirection(float res[])
00117 {
00118     float dx, dy ;
00119     int direction = DIR_STAY ;
00120     dx = filterVal(res[0]) ;
00121     dy = filterVal(res[1]) ;
00122 
00123     if ((dx*dx) > (dy*dy)) { // holizontal move
00124         if (dx > 0.0) {
00125             direction = DIR_DOWN ;
00126         } else if (dx < 0.0) {
00127             direction = DIR_UP ;
00128         }
00129     } else { // vertical move
00130         if (dy > 0.0) {
00131             direction = DIR_RIGHT ;
00132         } else if (dy < 0.0) {
00133             direction = DIR_LEFT ;
00134         }
00135     }
00136     return(direction) ;
00137 }
00138 
00139 /** Get next positon to move to
00140  * @param pos_type current where we are now
00141  * @param int direction which way we'd like to move
00142  * @returns the candidate positon for the next move
00143  */
00144 pos_type getNext(pos_type current, int direction) 
00145 {
00146     pos_type next = current ;
00147     switch(direction) {
00148     case DIR_STAY: 
00149         break ;
00150     case DIR_UP: 
00151         if (next.y > 0) { 
00152             next.y-- ; 
00153         }  
00154         break ;
00155     case DIR_DOWN: 
00156         if (next.y < (MAZE_H - 1)) { 
00157             next.y++ ; 
00158         } 
00159         break ;
00160     case DIR_RIGHT: 
00161         if (next.x < (MAZE_W - 1)) { 
00162             next.x++ ; 
00163         } 
00164         break ;
00165     case DIR_LEFT: 
00166         if (next.x > 0) { 
00167             next.x-- ; 
00168         } 
00169         break ;
00170     default: 
00171         break ;
00172     }
00173     return( next ) ;
00174 }
00175 
00176 /** Notice of the goal
00177  */
00178 void showGoal(void)
00179 {
00180     int x0, y0, x1, y1 ;
00181     x0 = ((MAZE_W/2)-4) * 10 ;
00182     y0 = ((MAZE_H/2)-1) * 10 ;
00183     x1 = ((MAZE_W/2)+4) * 10 ;
00184     y1 = ((MAZE_H/2)+1) * 10 ;
00185 
00186     TFT.BusEnable(true) ;
00187     TFT.fillrect(x0, y0, x1, y1, Blue) ;
00188     TFT.rect(x0,y0,x1,y1, Yellow) ;
00189     TFT.foreground(Red) ;
00190     TFT.background(Blue) ;
00191     x0 = ((MAZE_W/2) - 2) * 10 ;
00192     y0 = (MAZE_H/2) * 10 - 3 ;
00193     TFT.locate(x0, y0) ;
00194     TFT.printf("G O A L") ;
00195     TFT.BusEnable(false) ;
00196 }
00197 
00198 /** Check if we can move to the next position
00199  * @param pos_type next the position we'd like to move next
00200  * @returns if the position is empty (movable)
00201  */
00202 bool checkMove(pos_type next) 
00203 {
00204     bool result = false ;
00205     
00206     switch(maze[next.y][next.x]) {
00207     case POS_PATH:
00208     case POS_GOAL:
00209         result = true ;
00210         break ;
00211     case POS_START:
00212     case POS_WALL:
00213     default:
00214         result = false ;
00215         break ;
00216     } 
00217     return( result ) ;
00218 }
00219 
00220 /** main a simple maze program
00221  */
00222 int main() {
00223     float res[3] ;
00224     pos_type current, next, goal ;
00225     int direction = DIR_STAY ;
00226     int x, y ;
00227     
00228     drawTFTMaze(&current, &goal) ;
00229     
00230     for (;;) {
00231         acc.getAccAllAxis(res) ;
00232         direction = getDirection(res) ;
00233         next = getNext(current, direction) ;
00234         if ((!isSame(current, next)) && checkMove(next)) {
00235            TFT.BusEnable(true) ;
00236            x = current.x * 10 ;
00237            y = current.y * 10 ;
00238            TFT.fillrect(x, y, x+9, y+9, Black) ;
00239            x = next.x * 10 ;
00240            y = next.y * 10 ;
00241            TFT.fillcircle(x+5, y+5, 4, Green) ; 
00242            TFT.BusEnable(false) ;
00243            current = next ;
00244            if (isSame(next, goal)) {
00245              break ; // goal in!
00246            }
00247         }
00248         wait(0.1) ;
00249     }
00250     showGoal() ;
00251     for (;;) {
00252         // wait for ever for reset
00253     }
00254 }