Simple test program for FRDM-KL25Z and Adafruit 2.8" TFT display. For the touch sensor, only polling mode is implemented.
Dependencies: MMA8451Q SPI_STMPE610 TSI UniGraphic mbed
This program was to test Adafruit 2.8" TFT with touch with FRDM-KL25Z.
After download the binary to the FRDM-KL25Z and push the reset button ,
a simple welcome message will be displayed.
このプログラムは私が秋月で購入した Adafruit 2.8" TFT
http://akizukidenshi.com/catalog/g/gM-07747/
をFRDM-KL25Z で試すために書いたものです。
ダウンロード後にFRDM-KL25Zのリセットスイッチを押すと
最初の画面が表示されます。
Now using UniGraphic library.
And the problem of remaining previous screen is gone. ;-)
For a little bonus, TS_Eyes and Maze are also included.
UniGraphic ライブラリ版になり、画面にごみが残るバグが治りました。
おまけに TS_Eyes と Maze も追加してあります。 (^ ^)v
If you push and keep the right side of the screen,
the screen will advance to the page2, which is a simple graph sample.
ここで画面の右側をしばらく押していると、次のページに移行します。
このページでは、簡単なグラフを表示する例を描画しています。
And if you do the same again, the program advances to the page3,
which is a data display page of MMA8451Q accelerometer mounted on
the FRDM-KL25Z.
さらに画面の右側をしばらく押していると、次のページに移行します。
ここでは、FRDM-KL25Zに搭載されている MMA8451Q という3軸の
加速度センサの値を表示しています。
And this is the last page of this program, so far, so if you
try to advance page, it will return to the first page.
このページが最後のページになっているので、さらにページ送りをすると
最初のページに戻ります。
maze.cpp@3:34d8706e1614, 2015-08-08 (annotated)
- Committer:
- Rhyme
- Date:
- Sat Aug 08 12:07:56 2015 +0000
- Revision:
- 3:34d8706e1614
UniGraphic lib version
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Rhyme | 3:34d8706e1614 | 1 | /** maze_vt100 a simple maze using UniGraphic and MMA8451Q libraries |
Rhyme | 3:34d8706e1614 | 2 | */ |
Rhyme | 3:34d8706e1614 | 3 | #include "mbed.h" |
Rhyme | 3:34d8706e1614 | 4 | #include "MMA8451Q.h" |
Rhyme | 3:34d8706e1614 | 5 | #include <ILI9341.h> |
Rhyme | 3:34d8706e1614 | 6 | #include "Arial12x12.h" |
Rhyme | 3:34d8706e1614 | 7 | #include "Arial24x23.h" |
Rhyme | 3:34d8706e1614 | 8 | #include "Arial28x28.h" |
Rhyme | 3:34d8706e1614 | 9 | #include "Arial43x48_numb.h" |
Rhyme | 3:34d8706e1614 | 10 | #include "maze.h" |
Rhyme | 3:34d8706e1614 | 11 | |
Rhyme | 3:34d8706e1614 | 12 | #define CELL_W 10 |
Rhyme | 3:34d8706e1614 | 13 | #define CELL_H 10 |
Rhyme | 3:34d8706e1614 | 14 | #define CELL_S 5 |
Rhyme | 3:34d8706e1614 | 15 | #define CELL_R 4 |
Rhyme | 3:34d8706e1614 | 16 | #define LEFT_OFFSET 20 |
Rhyme | 3:34d8706e1614 | 17 | #define TOP_OFFSET 20 |
Rhyme | 3:34d8706e1614 | 18 | |
Rhyme | 3:34d8706e1614 | 19 | #define DIR_STAY 0 |
Rhyme | 3:34d8706e1614 | 20 | #define DIR_UP 1 |
Rhyme | 3:34d8706e1614 | 21 | #define DIR_DOWN 2 |
Rhyme | 3:34d8706e1614 | 22 | #define DIR_RIGHT 3 |
Rhyme | 3:34d8706e1614 | 23 | #define DIR_LEFT 4 |
Rhyme | 3:34d8706e1614 | 24 | |
Rhyme | 3:34d8706e1614 | 25 | #define MMA8451_I2C_ADDRESS (0x1D<<1) |
Rhyme | 3:34d8706e1614 | 26 | |
Rhyme | 3:34d8706e1614 | 27 | typedef struct _pos { |
Rhyme | 3:34d8706e1614 | 28 | int x ; |
Rhyme | 3:34d8706e1614 | 29 | int y ; |
Rhyme | 3:34d8706e1614 | 30 | } pos_type ; |
Rhyme | 3:34d8706e1614 | 31 | |
Rhyme | 3:34d8706e1614 | 32 | extern MMA8451Q *acc ; |
Rhyme | 3:34d8706e1614 | 33 | extern ILI9341 TFT ; |
Rhyme | 3:34d8706e1614 | 34 | extern DigitalOut backlight ; |
Rhyme | 3:34d8706e1614 | 35 | float threshold = 0.2 ; |
Rhyme | 3:34d8706e1614 | 36 | |
Rhyme | 3:34d8706e1614 | 37 | /** Check if two pos_type values are same |
Rhyme | 3:34d8706e1614 | 38 | * @param pos_type a |
Rhyme | 3:34d8706e1614 | 39 | * @param pos_type b |
Rhyme | 3:34d8706e1614 | 40 | * @returns if a and b are same position |
Rhyme | 3:34d8706e1614 | 41 | */ |
Rhyme | 3:34d8706e1614 | 42 | bool isSame(pos_type a, pos_type b) |
Rhyme | 3:34d8706e1614 | 43 | { |
Rhyme | 3:34d8706e1614 | 44 | return((a.x == b.x)&&(a.y == b.y)) ; |
Rhyme | 3:34d8706e1614 | 45 | } |
Rhyme | 3:34d8706e1614 | 46 | |
Rhyme | 3:34d8706e1614 | 47 | /** Draw the maze defined in the "maze.h" |
Rhyme | 3:34d8706e1614 | 48 | * @param pos_type *current actually the start point |
Rhyme | 3:34d8706e1614 | 49 | * @param pos_type *goal the position of the goal |
Rhyme | 3:34d8706e1614 | 50 | * @note those params are actually returned by this function |
Rhyme | 3:34d8706e1614 | 51 | */ |
Rhyme | 3:34d8706e1614 | 52 | void drawTFTMaze(pos_type *current, pos_type *goal) |
Rhyme | 3:34d8706e1614 | 53 | { |
Rhyme | 3:34d8706e1614 | 54 | int x, y, i, j ; |
Rhyme | 3:34d8706e1614 | 55 | TFT.BusEnable(true) ; |
Rhyme | 3:34d8706e1614 | 56 | |
Rhyme | 3:34d8706e1614 | 57 | backlight = 0 ; |
Rhyme | 3:34d8706e1614 | 58 | TFT.foreground(White) ; |
Rhyme | 3:34d8706e1614 | 59 | TFT.background(Black) ; |
Rhyme | 3:34d8706e1614 | 60 | TFT.cls() ; |
Rhyme | 3:34d8706e1614 | 61 | for (j = 0 ; j < MAZE_H ; j++ ) { |
Rhyme | 3:34d8706e1614 | 62 | for (i = 0 ; i < MAZE_W ; i++ ) { |
Rhyme | 3:34d8706e1614 | 63 | x = i * CELL_W + LEFT_OFFSET ; |
Rhyme | 3:34d8706e1614 | 64 | y = j * CELL_H + TOP_OFFSET ; |
Rhyme | 3:34d8706e1614 | 65 | switch(maze[j][i]) { |
Rhyme | 3:34d8706e1614 | 66 | case 0: // path |
Rhyme | 3:34d8706e1614 | 67 | TFT.fillrect(x, y, x+CELL_W-1, y+CELL_H-1, Black) ; |
Rhyme | 3:34d8706e1614 | 68 | break ; |
Rhyme | 3:34d8706e1614 | 69 | case 1: // wall |
Rhyme | 3:34d8706e1614 | 70 | TFT.fillrect(x, y, x+CELL_W-1, y+CELL_H-1, DarkGrey) ; |
Rhyme | 3:34d8706e1614 | 71 | break ; |
Rhyme | 3:34d8706e1614 | 72 | case 2: // Start point |
Rhyme | 3:34d8706e1614 | 73 | TFT.fillcircle(x+CELL_S, y+CELL_S, CELL_R, Green) ; |
Rhyme | 3:34d8706e1614 | 74 | current->x = i ; |
Rhyme | 3:34d8706e1614 | 75 | current->y = j ; |
Rhyme | 3:34d8706e1614 | 76 | break ; |
Rhyme | 3:34d8706e1614 | 77 | case 3: // Goal |
Rhyme | 3:34d8706e1614 | 78 | TFT.fillcircle(x+CELL_S, y+CELL_S, CELL_R, Red) ; |
Rhyme | 3:34d8706e1614 | 79 | goal->x = i ; |
Rhyme | 3:34d8706e1614 | 80 | goal->y = j ; |
Rhyme | 3:34d8706e1614 | 81 | break ; |
Rhyme | 3:34d8706e1614 | 82 | default: // should not be here |
Rhyme | 3:34d8706e1614 | 83 | break ; |
Rhyme | 3:34d8706e1614 | 84 | } |
Rhyme | 3:34d8706e1614 | 85 | } |
Rhyme | 3:34d8706e1614 | 86 | } |
Rhyme | 3:34d8706e1614 | 87 | backlight = 1 ; |
Rhyme | 3:34d8706e1614 | 88 | TFT.BusEnable(false) ; |
Rhyme | 3:34d8706e1614 | 89 | } |
Rhyme | 3:34d8706e1614 | 90 | |
Rhyme | 3:34d8706e1614 | 91 | /** Filter out too little move |
Rhyme | 3:34d8706e1614 | 92 | * @param float in returned value from the acc |
Rhyme | 3:34d8706e1614 | 93 | * @returns float result filtered value of in |
Rhyme | 3:34d8706e1614 | 94 | */ |
Rhyme | 3:34d8706e1614 | 95 | float filterVal(float in) |
Rhyme | 3:34d8706e1614 | 96 | { |
Rhyme | 3:34d8706e1614 | 97 | float result = 0.0 ; |
Rhyme | 3:34d8706e1614 | 98 | if ((-threshold > in)||(in > threshold)) { |
Rhyme | 3:34d8706e1614 | 99 | result = in ; |
Rhyme | 3:34d8706e1614 | 100 | } |
Rhyme | 3:34d8706e1614 | 101 | return( result ) ; |
Rhyme | 3:34d8706e1614 | 102 | } |
Rhyme | 3:34d8706e1614 | 103 | |
Rhyme | 3:34d8706e1614 | 104 | /** Decide which direction to go |
Rhyme | 3:34d8706e1614 | 105 | * @param float res[] acc value of x, y |
Rhyme | 3:34d8706e1614 | 106 | * @returns int direction to move |
Rhyme | 3:34d8706e1614 | 107 | */ |
Rhyme | 3:34d8706e1614 | 108 | int getDirection(float res[]) |
Rhyme | 3:34d8706e1614 | 109 | { |
Rhyme | 3:34d8706e1614 | 110 | float dx, dy ; |
Rhyme | 3:34d8706e1614 | 111 | int direction = DIR_STAY ; |
Rhyme | 3:34d8706e1614 | 112 | dx = filterVal(res[0]) ; |
Rhyme | 3:34d8706e1614 | 113 | dy = filterVal(res[1]) ; |
Rhyme | 3:34d8706e1614 | 114 | |
Rhyme | 3:34d8706e1614 | 115 | if ((dx*dx) > (dy*dy)) { // holizontal move |
Rhyme | 3:34d8706e1614 | 116 | if (dx > 0.0) { |
Rhyme | 3:34d8706e1614 | 117 | direction = DIR_DOWN ; |
Rhyme | 3:34d8706e1614 | 118 | } else if (dx < 0.0) { |
Rhyme | 3:34d8706e1614 | 119 | direction = DIR_UP ; |
Rhyme | 3:34d8706e1614 | 120 | } |
Rhyme | 3:34d8706e1614 | 121 | } else { // vertical move |
Rhyme | 3:34d8706e1614 | 122 | if (dy > 0.0) { |
Rhyme | 3:34d8706e1614 | 123 | direction = DIR_RIGHT ; |
Rhyme | 3:34d8706e1614 | 124 | } else if (dy < 0.0) { |
Rhyme | 3:34d8706e1614 | 125 | direction = DIR_LEFT ; |
Rhyme | 3:34d8706e1614 | 126 | } |
Rhyme | 3:34d8706e1614 | 127 | } |
Rhyme | 3:34d8706e1614 | 128 | return(direction) ; |
Rhyme | 3:34d8706e1614 | 129 | } |
Rhyme | 3:34d8706e1614 | 130 | |
Rhyme | 3:34d8706e1614 | 131 | /** Get next positon to move to |
Rhyme | 3:34d8706e1614 | 132 | * @param pos_type current where we are now |
Rhyme | 3:34d8706e1614 | 133 | * @param int direction which way we'd like to move |
Rhyme | 3:34d8706e1614 | 134 | * @returns the candidate positon for the next move |
Rhyme | 3:34d8706e1614 | 135 | */ |
Rhyme | 3:34d8706e1614 | 136 | pos_type getNext(pos_type current, int direction) |
Rhyme | 3:34d8706e1614 | 137 | { |
Rhyme | 3:34d8706e1614 | 138 | pos_type next = current ; |
Rhyme | 3:34d8706e1614 | 139 | switch(direction) { |
Rhyme | 3:34d8706e1614 | 140 | case DIR_STAY: |
Rhyme | 3:34d8706e1614 | 141 | break ; |
Rhyme | 3:34d8706e1614 | 142 | case DIR_UP: |
Rhyme | 3:34d8706e1614 | 143 | if (next.y > 0) { |
Rhyme | 3:34d8706e1614 | 144 | next.y-- ; |
Rhyme | 3:34d8706e1614 | 145 | } |
Rhyme | 3:34d8706e1614 | 146 | break ; |
Rhyme | 3:34d8706e1614 | 147 | case DIR_DOWN: |
Rhyme | 3:34d8706e1614 | 148 | if (next.y < (MAZE_H - 1)) { |
Rhyme | 3:34d8706e1614 | 149 | next.y++ ; |
Rhyme | 3:34d8706e1614 | 150 | } |
Rhyme | 3:34d8706e1614 | 151 | break ; |
Rhyme | 3:34d8706e1614 | 152 | case DIR_RIGHT: |
Rhyme | 3:34d8706e1614 | 153 | if (next.x < (MAZE_W - 1)) { |
Rhyme | 3:34d8706e1614 | 154 | next.x++ ; |
Rhyme | 3:34d8706e1614 | 155 | } |
Rhyme | 3:34d8706e1614 | 156 | break ; |
Rhyme | 3:34d8706e1614 | 157 | case DIR_LEFT: |
Rhyme | 3:34d8706e1614 | 158 | if (next.x > 0) { |
Rhyme | 3:34d8706e1614 | 159 | next.x-- ; |
Rhyme | 3:34d8706e1614 | 160 | } |
Rhyme | 3:34d8706e1614 | 161 | break ; |
Rhyme | 3:34d8706e1614 | 162 | default: |
Rhyme | 3:34d8706e1614 | 163 | break ; |
Rhyme | 3:34d8706e1614 | 164 | } |
Rhyme | 3:34d8706e1614 | 165 | return( next ) ; |
Rhyme | 3:34d8706e1614 | 166 | } |
Rhyme | 3:34d8706e1614 | 167 | |
Rhyme | 3:34d8706e1614 | 168 | /** Notice of the goal |
Rhyme | 3:34d8706e1614 | 169 | */ |
Rhyme | 3:34d8706e1614 | 170 | void showGoal(void) |
Rhyme | 3:34d8706e1614 | 171 | { |
Rhyme | 3:34d8706e1614 | 172 | int x0, y0, x1, y1 ; |
Rhyme | 3:34d8706e1614 | 173 | x0 = ((MAZE_W/2)-4) * CELL_W + LEFT_OFFSET ; |
Rhyme | 3:34d8706e1614 | 174 | y0 = ((MAZE_H/2)-1) * CELL_H + TOP_OFFSET ; |
Rhyme | 3:34d8706e1614 | 175 | x1 = ((MAZE_W/2)+4) * CELL_W + LEFT_OFFSET ; |
Rhyme | 3:34d8706e1614 | 176 | y1 = ((MAZE_H/2)+1) * CELL_H + TOP_OFFSET ; |
Rhyme | 3:34d8706e1614 | 177 | |
Rhyme | 3:34d8706e1614 | 178 | TFT.BusEnable(true) ; |
Rhyme | 3:34d8706e1614 | 179 | // TFT.set_font((unsigned char*) Arial12x12); |
Rhyme | 3:34d8706e1614 | 180 | TFT.set_font((unsigned char*) Terminal6x8) ; |
Rhyme | 3:34d8706e1614 | 181 | TFT.fillrect(x0, y0, x1, y1, Blue) ; |
Rhyme | 3:34d8706e1614 | 182 | TFT.rect(x0,y0,x1,y1, Yellow) ; |
Rhyme | 3:34d8706e1614 | 183 | TFT.foreground(Red) ; |
Rhyme | 3:34d8706e1614 | 184 | TFT.background(Blue) ; |
Rhyme | 3:34d8706e1614 | 185 | x0 = ((MAZE_W/2) - 2) * CELL_W + LEFT_OFFSET ; |
Rhyme | 3:34d8706e1614 | 186 | y0 = (MAZE_H/2) * CELL_H - 3 + TOP_OFFSET ; |
Rhyme | 3:34d8706e1614 | 187 | TFT.locate(x0, y0) ; |
Rhyme | 3:34d8706e1614 | 188 | TFT.printf("G O A L") ; |
Rhyme | 3:34d8706e1614 | 189 | TFT.foreground(Yellow) ; |
Rhyme | 3:34d8706e1614 | 190 | TFT.background(Black) ; |
Rhyme | 3:34d8706e1614 | 191 | TFT.locate(30, 300) ; |
Rhyme | 3:34d8706e1614 | 192 | // TFT.printf("Use FRDM touch slider") ; |
Rhyme | 3:34d8706e1614 | 193 | TFT.printf(" Retry! ") ; |
Rhyme | 3:34d8706e1614 | 194 | TFT.locate(5, 300) ; |
Rhyme | 3:34d8706e1614 | 195 | TFT.printf("<< Prev") ; |
Rhyme | 3:34d8706e1614 | 196 | TFT.locate(180, 300) ; |
Rhyme | 3:34d8706e1614 | 197 | TFT.printf("Next >>") ; |
Rhyme | 3:34d8706e1614 | 198 | TFT.BusEnable(false) ; |
Rhyme | 3:34d8706e1614 | 199 | } |
Rhyme | 3:34d8706e1614 | 200 | |
Rhyme | 3:34d8706e1614 | 201 | /** Check if we can move to the next position |
Rhyme | 3:34d8706e1614 | 202 | * @param pos_type next the position we'd like to move next |
Rhyme | 3:34d8706e1614 | 203 | * @returns if the position is empty (movable) |
Rhyme | 3:34d8706e1614 | 204 | */ |
Rhyme | 3:34d8706e1614 | 205 | bool checkMove(pos_type next) |
Rhyme | 3:34d8706e1614 | 206 | { |
Rhyme | 3:34d8706e1614 | 207 | bool result = false ; |
Rhyme | 3:34d8706e1614 | 208 | |
Rhyme | 3:34d8706e1614 | 209 | switch(maze[next.y][next.x]) { |
Rhyme | 3:34d8706e1614 | 210 | case POS_PATH: |
Rhyme | 3:34d8706e1614 | 211 | case POS_GOAL: |
Rhyme | 3:34d8706e1614 | 212 | result = true ; |
Rhyme | 3:34d8706e1614 | 213 | break ; |
Rhyme | 3:34d8706e1614 | 214 | case POS_START: |
Rhyme | 3:34d8706e1614 | 215 | case POS_WALL: |
Rhyme | 3:34d8706e1614 | 216 | default: |
Rhyme | 3:34d8706e1614 | 217 | result = false ; |
Rhyme | 3:34d8706e1614 | 218 | break ; |
Rhyme | 3:34d8706e1614 | 219 | } |
Rhyme | 3:34d8706e1614 | 220 | return( result ) ; |
Rhyme | 3:34d8706e1614 | 221 | } |
Rhyme | 3:34d8706e1614 | 222 | |
Rhyme | 3:34d8706e1614 | 223 | /** main a simple maze program |
Rhyme | 3:34d8706e1614 | 224 | */ |
Rhyme | 3:34d8706e1614 | 225 | void doMaze(void) |
Rhyme | 3:34d8706e1614 | 226 | { |
Rhyme | 3:34d8706e1614 | 227 | float res[3] ; |
Rhyme | 3:34d8706e1614 | 228 | pos_type current, next, goal ; |
Rhyme | 3:34d8706e1614 | 229 | int direction = DIR_STAY ; |
Rhyme | 3:34d8706e1614 | 230 | int x, y ; |
Rhyme | 3:34d8706e1614 | 231 | |
Rhyme | 3:34d8706e1614 | 232 | drawTFTMaze(¤t, &goal) ; |
Rhyme | 3:34d8706e1614 | 233 | |
Rhyme | 3:34d8706e1614 | 234 | for (;;) { |
Rhyme | 3:34d8706e1614 | 235 | acc->getAccAllAxis(res) ; |
Rhyme | 3:34d8706e1614 | 236 | direction = getDirection(res) ; |
Rhyme | 3:34d8706e1614 | 237 | next = getNext(current, direction) ; |
Rhyme | 3:34d8706e1614 | 238 | if ((!isSame(current, next)) && checkMove(next)) { |
Rhyme | 3:34d8706e1614 | 239 | TFT.BusEnable(true) ; |
Rhyme | 3:34d8706e1614 | 240 | x = current.x * CELL_W + LEFT_OFFSET ; |
Rhyme | 3:34d8706e1614 | 241 | y = current.y * CELL_H + TOP_OFFSET ; |
Rhyme | 3:34d8706e1614 | 242 | TFT.fillrect(x, y, x+CELL_W-1, y+CELL_H-1, Black) ; |
Rhyme | 3:34d8706e1614 | 243 | x = next.x * CELL_W + LEFT_OFFSET ; |
Rhyme | 3:34d8706e1614 | 244 | y = next.y * CELL_H + TOP_OFFSET ; |
Rhyme | 3:34d8706e1614 | 245 | TFT.fillcircle(x+CELL_S, y+CELL_S, CELL_R, Green) ; |
Rhyme | 3:34d8706e1614 | 246 | TFT.BusEnable(false) ; |
Rhyme | 3:34d8706e1614 | 247 | current = next ; |
Rhyme | 3:34d8706e1614 | 248 | if (isSame(next, goal)) { |
Rhyme | 3:34d8706e1614 | 249 | break ; // goal in! |
Rhyme | 3:34d8706e1614 | 250 | } |
Rhyme | 3:34d8706e1614 | 251 | } |
Rhyme | 3:34d8706e1614 | 252 | wait(0.1) ; |
Rhyme | 3:34d8706e1614 | 253 | } |
Rhyme | 3:34d8706e1614 | 254 | showGoal() ; |
Rhyme | 3:34d8706e1614 | 255 | } |