My first mbed-os 5.x test project with MAX32630FTHR and Adafruit 2.4" TFT with touch.
Dependencies: BMI160 SPI_STMPE610 USBDevice UniGraphic max32630fthr
My first test program of mbed-os 5.x, using MAX32630FTHR and Adafruit 2.4" TFT with Touch.
On 22-Sep-2017 Monitoring both Acc and Gyr added to the screen 3 Controlling the backlight via STMPE610 GPIO-2 added
maze.cpp@3:43de31beea45, 2017-09-22 (annotated)
- Committer:
- Rhyme
- Date:
- Fri Sep 22 05:35:56 2017 +0000
- Revision:
- 3:43de31beea45
- Parent:
- 0:a4d7417f7672
some backlight control added
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Rhyme | 0:a4d7417f7672 | 1 | /** maze_vt100 a simple maze using UniGraphic and MMA8451Q libraries |
Rhyme | 0:a4d7417f7672 | 2 | */ |
Rhyme | 0:a4d7417f7672 | 3 | #include "mbed.h" |
Rhyme | 0:a4d7417f7672 | 4 | #include "BMI160.h" |
Rhyme | 0:a4d7417f7672 | 5 | // #include "MMA8451Q.h" |
Rhyme | 0:a4d7417f7672 | 6 | #include <ILI9341.h> |
Rhyme | 0:a4d7417f7672 | 7 | #include "Arial12x12.h" |
Rhyme | 0:a4d7417f7672 | 8 | #include "Arial24x23.h" |
Rhyme | 0:a4d7417f7672 | 9 | #include "Arial28x28.h" |
Rhyme | 0:a4d7417f7672 | 10 | #include "Arial43x48_numb.h" |
Rhyme | 0:a4d7417f7672 | 11 | #include "maze.h" |
Rhyme | 0:a4d7417f7672 | 12 | |
Rhyme | 0:a4d7417f7672 | 13 | #define CELL_W 10 |
Rhyme | 0:a4d7417f7672 | 14 | #define CELL_H 10 |
Rhyme | 0:a4d7417f7672 | 15 | #define CELL_S 5 |
Rhyme | 0:a4d7417f7672 | 16 | #define CELL_R 4 |
Rhyme | 0:a4d7417f7672 | 17 | #define LEFT_OFFSET 20 |
Rhyme | 0:a4d7417f7672 | 18 | #define TOP_OFFSET 20 |
Rhyme | 0:a4d7417f7672 | 19 | |
Rhyme | 0:a4d7417f7672 | 20 | #define DIR_STAY 0 |
Rhyme | 0:a4d7417f7672 | 21 | #define DIR_UP 1 |
Rhyme | 0:a4d7417f7672 | 22 | #define DIR_DOWN 2 |
Rhyme | 0:a4d7417f7672 | 23 | #define DIR_RIGHT 3 |
Rhyme | 0:a4d7417f7672 | 24 | #define DIR_LEFT 4 |
Rhyme | 0:a4d7417f7672 | 25 | |
Rhyme | 0:a4d7417f7672 | 26 | #define MMA8451_I2C_ADDRESS (0x1D<<1) |
Rhyme | 0:a4d7417f7672 | 27 | |
Rhyme | 0:a4d7417f7672 | 28 | typedef struct _pos { |
Rhyme | 0:a4d7417f7672 | 29 | int x ; |
Rhyme | 0:a4d7417f7672 | 30 | int y ; |
Rhyme | 0:a4d7417f7672 | 31 | } pos_type ; |
Rhyme | 0:a4d7417f7672 | 32 | |
Rhyme | 0:a4d7417f7672 | 33 | extern BMI160 *acc ; |
Rhyme | 0:a4d7417f7672 | 34 | extern ILI9341 *tft ; |
Rhyme | 0:a4d7417f7672 | 35 | // extern DigitalOut backlight ; |
Rhyme | 0:a4d7417f7672 | 36 | float threshold = 0.2 ; |
Rhyme | 0:a4d7417f7672 | 37 | |
Rhyme | 0:a4d7417f7672 | 38 | /** Check if two pos_type values are same |
Rhyme | 0:a4d7417f7672 | 39 | * @param pos_type a |
Rhyme | 0:a4d7417f7672 | 40 | * @param pos_type b |
Rhyme | 0:a4d7417f7672 | 41 | * @returns if a and b are same position |
Rhyme | 0:a4d7417f7672 | 42 | */ |
Rhyme | 0:a4d7417f7672 | 43 | bool isSame(pos_type a, pos_type b) |
Rhyme | 0:a4d7417f7672 | 44 | { |
Rhyme | 0:a4d7417f7672 | 45 | return((a.x == b.x)&&(a.y == b.y)) ; |
Rhyme | 0:a4d7417f7672 | 46 | } |
Rhyme | 0:a4d7417f7672 | 47 | |
Rhyme | 0:a4d7417f7672 | 48 | /** Draw the maze defined in the "maze.h" |
Rhyme | 0:a4d7417f7672 | 49 | * @param pos_type *current actually the start point |
Rhyme | 0:a4d7417f7672 | 50 | * @param pos_type *goal the position of the goal |
Rhyme | 0:a4d7417f7672 | 51 | * @note those params are actually returned by this function |
Rhyme | 0:a4d7417f7672 | 52 | */ |
Rhyme | 0:a4d7417f7672 | 53 | void drawTFTMaze(pos_type *current, pos_type *goal) |
Rhyme | 0:a4d7417f7672 | 54 | { |
Rhyme | 0:a4d7417f7672 | 55 | int x, y, i, j ; |
Rhyme | 0:a4d7417f7672 | 56 | tft->BusEnable(true) ; |
Rhyme | 0:a4d7417f7672 | 57 | |
Rhyme | 0:a4d7417f7672 | 58 | // backlight = 0 ; |
Rhyme | 0:a4d7417f7672 | 59 | tft->foreground(White) ; |
Rhyme | 0:a4d7417f7672 | 60 | tft->background(Black) ; |
Rhyme | 0:a4d7417f7672 | 61 | tft->cls() ; |
Rhyme | 0:a4d7417f7672 | 62 | for (j = 0 ; j < MAZE_H ; j++ ) { |
Rhyme | 0:a4d7417f7672 | 63 | for (i = 0 ; i < MAZE_W ; i++ ) { |
Rhyme | 0:a4d7417f7672 | 64 | x = i * CELL_W + LEFT_OFFSET ; |
Rhyme | 0:a4d7417f7672 | 65 | y = j * CELL_H + TOP_OFFSET ; |
Rhyme | 0:a4d7417f7672 | 66 | switch(maze[j][i]) { |
Rhyme | 0:a4d7417f7672 | 67 | case 0: // path |
Rhyme | 0:a4d7417f7672 | 68 | tft->fillrect(x, y, x+CELL_W-1, y+CELL_H-1, Black) ; |
Rhyme | 0:a4d7417f7672 | 69 | break ; |
Rhyme | 0:a4d7417f7672 | 70 | case 1: // wall |
Rhyme | 0:a4d7417f7672 | 71 | tft->fillrect(x, y, x+CELL_W-1, y+CELL_H-1, DarkGrey) ; |
Rhyme | 0:a4d7417f7672 | 72 | break ; |
Rhyme | 0:a4d7417f7672 | 73 | case 2: // Start point |
Rhyme | 0:a4d7417f7672 | 74 | tft->fillcircle(x+CELL_S, y+CELL_S, CELL_R, Green) ; |
Rhyme | 0:a4d7417f7672 | 75 | current->x = i ; |
Rhyme | 0:a4d7417f7672 | 76 | current->y = j ; |
Rhyme | 0:a4d7417f7672 | 77 | break ; |
Rhyme | 0:a4d7417f7672 | 78 | case 3: // Goal |
Rhyme | 0:a4d7417f7672 | 79 | tft->fillcircle(x+CELL_S, y+CELL_S, CELL_R, Red) ; |
Rhyme | 0:a4d7417f7672 | 80 | goal->x = i ; |
Rhyme | 0:a4d7417f7672 | 81 | goal->y = j ; |
Rhyme | 0:a4d7417f7672 | 82 | break ; |
Rhyme | 0:a4d7417f7672 | 83 | default: // should not be here |
Rhyme | 0:a4d7417f7672 | 84 | break ; |
Rhyme | 0:a4d7417f7672 | 85 | } |
Rhyme | 0:a4d7417f7672 | 86 | } |
Rhyme | 0:a4d7417f7672 | 87 | } |
Rhyme | 0:a4d7417f7672 | 88 | // backlight = 1 ; |
Rhyme | 0:a4d7417f7672 | 89 | tft->BusEnable(false) ; |
Rhyme | 0:a4d7417f7672 | 90 | } |
Rhyme | 0:a4d7417f7672 | 91 | |
Rhyme | 0:a4d7417f7672 | 92 | /** Filter out too little move |
Rhyme | 0:a4d7417f7672 | 93 | * @param float in returned value from the acc |
Rhyme | 0:a4d7417f7672 | 94 | * @returns float result filtered value of in |
Rhyme | 0:a4d7417f7672 | 95 | */ |
Rhyme | 0:a4d7417f7672 | 96 | float filterVal(float in) |
Rhyme | 0:a4d7417f7672 | 97 | { |
Rhyme | 0:a4d7417f7672 | 98 | float result = 0.0 ; |
Rhyme | 0:a4d7417f7672 | 99 | if ((-threshold > in)||(in > threshold)) { |
Rhyme | 0:a4d7417f7672 | 100 | result = in ; |
Rhyme | 0:a4d7417f7672 | 101 | } |
Rhyme | 0:a4d7417f7672 | 102 | return( result ) ; |
Rhyme | 0:a4d7417f7672 | 103 | } |
Rhyme | 0:a4d7417f7672 | 104 | |
Rhyme | 0:a4d7417f7672 | 105 | /** Decide which direction to go |
Rhyme | 0:a4d7417f7672 | 106 | * @param float res[] acc value of x, y |
Rhyme | 0:a4d7417f7672 | 107 | * @returns int direction to move |
Rhyme | 0:a4d7417f7672 | 108 | */ |
Rhyme | 0:a4d7417f7672 | 109 | int getDirection(float res[]) |
Rhyme | 0:a4d7417f7672 | 110 | { |
Rhyme | 0:a4d7417f7672 | 111 | float dx, dy ; |
Rhyme | 0:a4d7417f7672 | 112 | int direction = DIR_STAY ; |
Rhyme | 0:a4d7417f7672 | 113 | dy = filterVal(res[0]) ; /* was dx */ |
Rhyme | 0:a4d7417f7672 | 114 | dx = filterVal(res[1]) ; /* was dy */ |
Rhyme | 0:a4d7417f7672 | 115 | |
Rhyme | 0:a4d7417f7672 | 116 | if ((dx*dx) > (dy*dy)) { // holizontal move |
Rhyme | 0:a4d7417f7672 | 117 | if (dx > 0.0) { |
Rhyme | 0:a4d7417f7672 | 118 | direction = DIR_UP ; |
Rhyme | 0:a4d7417f7672 | 119 | } else if (dx < 0.0) { |
Rhyme | 0:a4d7417f7672 | 120 | direction = DIR_DOWN ; |
Rhyme | 0:a4d7417f7672 | 121 | } |
Rhyme | 0:a4d7417f7672 | 122 | } else { // vertical move |
Rhyme | 0:a4d7417f7672 | 123 | if (dy > 0.0) { |
Rhyme | 0:a4d7417f7672 | 124 | direction = DIR_LEFT ; |
Rhyme | 0:a4d7417f7672 | 125 | } else if (dy < 0.0) { |
Rhyme | 0:a4d7417f7672 | 126 | direction = DIR_RIGHT ; |
Rhyme | 0:a4d7417f7672 | 127 | } |
Rhyme | 0:a4d7417f7672 | 128 | } |
Rhyme | 0:a4d7417f7672 | 129 | return(direction) ; |
Rhyme | 0:a4d7417f7672 | 130 | } |
Rhyme | 0:a4d7417f7672 | 131 | |
Rhyme | 0:a4d7417f7672 | 132 | /** Get next positon to move to |
Rhyme | 0:a4d7417f7672 | 133 | * @param pos_type current where we are now |
Rhyme | 0:a4d7417f7672 | 134 | * @param int direction which way we'd like to move |
Rhyme | 0:a4d7417f7672 | 135 | * @returns the candidate positon for the next move |
Rhyme | 0:a4d7417f7672 | 136 | */ |
Rhyme | 0:a4d7417f7672 | 137 | pos_type getNext(pos_type current, int direction) |
Rhyme | 0:a4d7417f7672 | 138 | { |
Rhyme | 0:a4d7417f7672 | 139 | pos_type next = current ; |
Rhyme | 0:a4d7417f7672 | 140 | switch(direction) { |
Rhyme | 0:a4d7417f7672 | 141 | case DIR_STAY: |
Rhyme | 0:a4d7417f7672 | 142 | break ; |
Rhyme | 0:a4d7417f7672 | 143 | case DIR_UP: |
Rhyme | 0:a4d7417f7672 | 144 | if (next.y > 0) { |
Rhyme | 0:a4d7417f7672 | 145 | next.y-- ; |
Rhyme | 0:a4d7417f7672 | 146 | } |
Rhyme | 0:a4d7417f7672 | 147 | break ; |
Rhyme | 0:a4d7417f7672 | 148 | case DIR_DOWN: |
Rhyme | 0:a4d7417f7672 | 149 | if (next.y < (MAZE_H - 1)) { |
Rhyme | 0:a4d7417f7672 | 150 | next.y++ ; |
Rhyme | 0:a4d7417f7672 | 151 | } |
Rhyme | 0:a4d7417f7672 | 152 | break ; |
Rhyme | 0:a4d7417f7672 | 153 | case DIR_RIGHT: |
Rhyme | 0:a4d7417f7672 | 154 | if (next.x < (MAZE_W - 1)) { |
Rhyme | 0:a4d7417f7672 | 155 | next.x++ ; |
Rhyme | 0:a4d7417f7672 | 156 | } |
Rhyme | 0:a4d7417f7672 | 157 | break ; |
Rhyme | 0:a4d7417f7672 | 158 | case DIR_LEFT: |
Rhyme | 0:a4d7417f7672 | 159 | if (next.x > 0) { |
Rhyme | 0:a4d7417f7672 | 160 | next.x-- ; |
Rhyme | 0:a4d7417f7672 | 161 | } |
Rhyme | 0:a4d7417f7672 | 162 | break ; |
Rhyme | 0:a4d7417f7672 | 163 | default: |
Rhyme | 0:a4d7417f7672 | 164 | break ; |
Rhyme | 0:a4d7417f7672 | 165 | } |
Rhyme | 0:a4d7417f7672 | 166 | return( next ) ; |
Rhyme | 0:a4d7417f7672 | 167 | } |
Rhyme | 0:a4d7417f7672 | 168 | |
Rhyme | 0:a4d7417f7672 | 169 | /** Notice of the goal |
Rhyme | 0:a4d7417f7672 | 170 | */ |
Rhyme | 0:a4d7417f7672 | 171 | void showGoal(void) |
Rhyme | 0:a4d7417f7672 | 172 | { |
Rhyme | 0:a4d7417f7672 | 173 | int x0, y0, x1, y1 ; |
Rhyme | 0:a4d7417f7672 | 174 | x0 = ((MAZE_W/2)-4) * CELL_W + LEFT_OFFSET ; |
Rhyme | 0:a4d7417f7672 | 175 | y0 = ((MAZE_H/2)-1) * CELL_H + TOP_OFFSET ; |
Rhyme | 0:a4d7417f7672 | 176 | x1 = ((MAZE_W/2)+4) * CELL_W + LEFT_OFFSET ; |
Rhyme | 0:a4d7417f7672 | 177 | y1 = ((MAZE_H/2)+1) * CELL_H + TOP_OFFSET ; |
Rhyme | 0:a4d7417f7672 | 178 | |
Rhyme | 0:a4d7417f7672 | 179 | tft->BusEnable(true) ; |
Rhyme | 0:a4d7417f7672 | 180 | // tft->set_font((unsigned char*) Arial12x12); |
Rhyme | 0:a4d7417f7672 | 181 | tft->set_font((unsigned char*) Terminal6x8) ; |
Rhyme | 0:a4d7417f7672 | 182 | tft->fillrect(x0, y0, x1, y1, Blue) ; |
Rhyme | 0:a4d7417f7672 | 183 | tft->rect(x0,y0,x1,y1, Yellow) ; |
Rhyme | 0:a4d7417f7672 | 184 | tft->foreground(Red) ; |
Rhyme | 0:a4d7417f7672 | 185 | tft->background(Blue) ; |
Rhyme | 0:a4d7417f7672 | 186 | x0 = ((MAZE_W/2) - 2) * CELL_W + LEFT_OFFSET ; |
Rhyme | 0:a4d7417f7672 | 187 | y0 = (MAZE_H/2) * CELL_H - 3 + TOP_OFFSET ; |
Rhyme | 0:a4d7417f7672 | 188 | tft->locate(x0, y0) ; |
Rhyme | 0:a4d7417f7672 | 189 | tft->printf("G O A L") ; |
Rhyme | 0:a4d7417f7672 | 190 | tft->foreground(Yellow) ; |
Rhyme | 0:a4d7417f7672 | 191 | tft->background(Black) ; |
Rhyme | 0:a4d7417f7672 | 192 | tft->locate(30, 300) ; |
Rhyme | 0:a4d7417f7672 | 193 | // tft->printf("Use FRDM touch slider") ; |
Rhyme | 0:a4d7417f7672 | 194 | tft->printf(" Retry! ") ; |
Rhyme | 0:a4d7417f7672 | 195 | tft->locate(5, 300) ; |
Rhyme | 0:a4d7417f7672 | 196 | tft->printf("<< Prev") ; |
Rhyme | 0:a4d7417f7672 | 197 | tft->locate(180, 300) ; |
Rhyme | 0:a4d7417f7672 | 198 | tft->printf("Next >>") ; |
Rhyme | 0:a4d7417f7672 | 199 | tft->BusEnable(false) ; |
Rhyme | 0:a4d7417f7672 | 200 | } |
Rhyme | 0:a4d7417f7672 | 201 | |
Rhyme | 0:a4d7417f7672 | 202 | /** Check if we can move to the next position |
Rhyme | 0:a4d7417f7672 | 203 | * @param pos_type next the position we'd like to move next |
Rhyme | 0:a4d7417f7672 | 204 | * @returns if the position is empty (movable) |
Rhyme | 0:a4d7417f7672 | 205 | */ |
Rhyme | 0:a4d7417f7672 | 206 | bool checkMove(pos_type next) |
Rhyme | 0:a4d7417f7672 | 207 | { |
Rhyme | 0:a4d7417f7672 | 208 | bool result = false ; |
Rhyme | 0:a4d7417f7672 | 209 | |
Rhyme | 0:a4d7417f7672 | 210 | switch(maze[next.y][next.x]) { |
Rhyme | 0:a4d7417f7672 | 211 | case POS_PATH: |
Rhyme | 0:a4d7417f7672 | 212 | case POS_GOAL: |
Rhyme | 0:a4d7417f7672 | 213 | result = true ; |
Rhyme | 0:a4d7417f7672 | 214 | break ; |
Rhyme | 0:a4d7417f7672 | 215 | case POS_START: |
Rhyme | 0:a4d7417f7672 | 216 | case POS_WALL: |
Rhyme | 0:a4d7417f7672 | 217 | default: |
Rhyme | 0:a4d7417f7672 | 218 | result = false ; |
Rhyme | 0:a4d7417f7672 | 219 | break ; |
Rhyme | 0:a4d7417f7672 | 220 | } |
Rhyme | 0:a4d7417f7672 | 221 | return( result ) ; |
Rhyme | 0:a4d7417f7672 | 222 | } |
Rhyme | 0:a4d7417f7672 | 223 | |
Rhyme | 0:a4d7417f7672 | 224 | /** main a simple maze program |
Rhyme | 0:a4d7417f7672 | 225 | */ |
Rhyme | 0:a4d7417f7672 | 226 | void doMaze(void) |
Rhyme | 0:a4d7417f7672 | 227 | { |
Rhyme | 0:a4d7417f7672 | 228 | float res[3] ; |
Rhyme | 0:a4d7417f7672 | 229 | pos_type current, next, goal ; |
Rhyme | 0:a4d7417f7672 | 230 | int direction = DIR_STAY ; |
Rhyme | 0:a4d7417f7672 | 231 | int x, y ; |
Rhyme | 0:a4d7417f7672 | 232 | |
Rhyme | 0:a4d7417f7672 | 233 | drawTFTMaze(¤t, &goal) ; |
Rhyme | 0:a4d7417f7672 | 234 | |
Rhyme | 0:a4d7417f7672 | 235 | for (;;) { |
Rhyme | 0:a4d7417f7672 | 236 | // acc->getAccAllAxis(res) ; |
Rhyme | 0:a4d7417f7672 | 237 | acc->getAcc(res) ; |
Rhyme | 0:a4d7417f7672 | 238 | direction = getDirection(res) ; |
Rhyme | 0:a4d7417f7672 | 239 | next = getNext(current, direction) ; |
Rhyme | 0:a4d7417f7672 | 240 | if ((!isSame(current, next)) && checkMove(next)) { |
Rhyme | 0:a4d7417f7672 | 241 | tft->BusEnable(true) ; |
Rhyme | 0:a4d7417f7672 | 242 | x = current.x * CELL_W + LEFT_OFFSET ; |
Rhyme | 0:a4d7417f7672 | 243 | y = current.y * CELL_H + TOP_OFFSET ; |
Rhyme | 0:a4d7417f7672 | 244 | tft->fillrect(x, y, x+CELL_W-1, y+CELL_H-1, Black) ; |
Rhyme | 0:a4d7417f7672 | 245 | x = next.x * CELL_W + LEFT_OFFSET ; |
Rhyme | 0:a4d7417f7672 | 246 | y = next.y * CELL_H + TOP_OFFSET ; |
Rhyme | 0:a4d7417f7672 | 247 | tft->fillcircle(x+CELL_S, y+CELL_S, CELL_R, Green) ; |
Rhyme | 0:a4d7417f7672 | 248 | tft->BusEnable(false) ; |
Rhyme | 0:a4d7417f7672 | 249 | current = next ; |
Rhyme | 0:a4d7417f7672 | 250 | if (isSame(next, goal)) { |
Rhyme | 0:a4d7417f7672 | 251 | break ; // goal in! |
Rhyme | 0:a4d7417f7672 | 252 | } |
Rhyme | 0:a4d7417f7672 | 253 | } |
Rhyme | 0:a4d7417f7672 | 254 | wait(0.1) ; |
Rhyme | 0:a4d7417f7672 | 255 | } |
Rhyme | 0:a4d7417f7672 | 256 | showGoal() ; |
Rhyme | 0:a4d7417f7672 | 257 | } |