Works

Dependencies:   BMP180 BNO055_fusion Fonts GPSISR HTU21D SDFileSystem UniGraphic mbed uGUI

Fork of Bicycl_Computer_NUCLEO-F411RE by Darren Ulrich

Committer:
trevieze
Date:
Mon Feb 27 22:37:44 2017 +0000
Revision:
11:869a102dd31c
Parent:
10:a3cb458d7b1c
Child:
12:49600de70963
Changes made in Keil Compiler. Diaplay is mostly functional.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Rhyme 0:cd5e3d371b54 1 /* mbed main.cpp to test adafruit 2.8" TFT LCD shiled w Touchscreen
Rhyme 0:cd5e3d371b54 2 * Copyright (c) 2014, 2015 Motoo Tanaka @ Design Methodology Lab
Rhyme 0:cd5e3d371b54 3 *
Rhyme 0:cd5e3d371b54 4 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
Rhyme 0:cd5e3d371b54 5 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
Rhyme 0:cd5e3d371b54 6 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
Rhyme 0:cd5e3d371b54 7 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
Rhyme 0:cd5e3d371b54 8 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
Rhyme 0:cd5e3d371b54 9 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
Rhyme 0:cd5e3d371b54 10 * THE SOFTWARE.
Rhyme 0:cd5e3d371b54 11 */
Rhyme 0:cd5e3d371b54 12
Rhyme 0:cd5e3d371b54 13 /*
Rhyme 0:cd5e3d371b54 14 * Note: This program is derived from the SeeeStudioTFTv2 program.
Rhyme 0:cd5e3d371b54 15 * Although both program share same ILI9341 TFT driver,
Rhyme 0:cd5e3d371b54 16 * the touch sensor was not same with the Display I purchased from Akizuki.
Rhyme 0:cd5e3d371b54 17 * http://akizukidenshi.com/catalog/g/gM-07747/
Rhyme 0:cd5e3d371b54 18 * The touch sensor on the display is STMPE610,
Rhyme 0:cd5e3d371b54 19 * so I hacked the minimum spi driver for it (polling mode only).
Rhyme 0:cd5e3d371b54 20 */
Rhyme 0:cd5e3d371b54 21
Rhyme 0:cd5e3d371b54 22 #include "mbed.h"
Rhyme 0:cd5e3d371b54 23 #include <math.h>
Rhyme 0:cd5e3d371b54 24 #include "ILI9341.h"
trevieze 2:c5085faf2aa5 25 #include "SeeedStudioTFTv2.h"
trevieze 6:6eb4b9322931 26 #include "BNO055.h"
trevieze 6:6eb4b9322931 27 #include "HTU21D.h"
trevieze 6:6eb4b9322931 28 #include "BMP180.h"
trevieze 8:8aa9cdab4a07 29 #include "SDFileSystem.h"
trevieze 8:8aa9cdab4a07 30 #include "GPSISR.h"
trevieze 9:855884782f67 31
trevieze 6:6eb4b9322931 32
trevieze 11:869a102dd31c 33 #include "ArialR16x17.h"
trevieze 11:869a102dd31c 34 #include "Arial24x23i.h"
trevieze 11:869a102dd31c 35 #include "Arial28x28.h"
trevieze 11:869a102dd31c 36 #include "Neu44x36.h"
trevieze 11:869a102dd31c 37 #include "SCProSB31x55.h"
Rhyme 0:cd5e3d371b54 38 #include "Arial12x12.h"
trevieze 11:869a102dd31c 39 #include "ArialR20x20.h"
Rhyme 0:cd5e3d371b54 40
trevieze 8:8aa9cdab4a07 41 //#define PIN_CS_TSC PA_9
trevieze 8:8aa9cdab4a07 42 //#define PIN_TSC_INTR PA_8
Rhyme 0:cd5e3d371b54 43 #define PIN_RESET_TFT PC_13 /* place holder */
trevieze 8:8aa9cdab4a07 44 //ILI9341 SPI PINS
trevieze 1:e265e7245ab8 45 #define PIN_XP A3
trevieze 1:e265e7245ab8 46 #define PIN_XM A1
trevieze 1:e265e7245ab8 47 #define PIN_YP A2
trevieze 1:e265e7245ab8 48 #define PIN_YM A0
trevieze 8:8aa9cdab4a07 49 #define PIN_MOSI_SPI1 D11 //SPI 1 MOSI
trevieze 8:8aa9cdab4a07 50 #define PIN_MISO_SPI1 D12 //SPI 1 MISO
trevieze 8:8aa9cdab4a07 51 #define PIN_SCLK_SPI1 D13 //SPI 1 SLCK
trevieze 8:8aa9cdab4a07 52 #define PIN_CS_SPI1 D5 // SPI CS D10 Was D5
trevieze 1:e265e7245ab8 53 #define PIN_DC_TFT D6
trevieze 1:e265e7245ab8 54 #define PIN_CS_SD D4
trevieze 6:6eb4b9322931 55 #define PIN_RESET D7
trevieze 8:8aa9cdab4a07 56 // SD Card on GPS shield PINS
trevieze 8:8aa9cdab4a07 57 #define PIN_MOSI_SPI3 PB_15 //SPI 1 MOSI
trevieze 8:8aa9cdab4a07 58 #define PIN_MISO_SPI3 PB_14 //SPI 1 MISO
trevieze 8:8aa9cdab4a07 59 #define PIN_SCLK_SPI3 PB_13 //SPI 1 SLCK
trevieze 8:8aa9cdab4a07 60 #define PIN_CS_SPI3 D2 // SPI CS
trevieze 8:8aa9cdab4a07 61 #define PIN_RX_GPS PA_12 //GPS Shield RX pin
trevieze 8:8aa9cdab4a07 62 #define PIN_TX_GPS PA_11 //GPS Shield TX pin
trevieze 8:8aa9cdab4a07 63
trevieze 11:869a102dd31c 64 #define PI 3.14159265358979f
trevieze 11:869a102dd31c 65
trevieze 6:6eb4b9322931 66
trevieze 6:6eb4b9322931 67 BNO055_ID_INF_TypeDef bno055_id_inf;
trevieze 6:6eb4b9322931 68 BNO055_EULER_TypeDef euler_angles;
trevieze 6:6eb4b9322931 69 BNO055_QUATERNION_TypeDef quaternion;
trevieze 6:6eb4b9322931 70 BNO055_LIN_ACC_TypeDef linear_acc;
trevieze 6:6eb4b9322931 71 BNO055_GRAVITY_TypeDef gravity;
trevieze 6:6eb4b9322931 72 BNO055_TEMPERATURE_TypeDef chip_temp;
trevieze 1:e265e7245ab8 73
Rhyme 0:cd5e3d371b54 74 #define DEVICE_NAME "F411RE"
Rhyme 0:cd5e3d371b54 75
Rhyme 0:cd5e3d371b54 76 #ifndef TARGET_NECLEO_F411RE
Rhyme 0:cd5e3d371b54 77 #define TARGET_NECLEO_F411RE
Rhyme 0:cd5e3d371b54 78 #endif
Rhyme 0:cd5e3d371b54 79
trevieze 7:b78ff34209e5 80 //DigitalOut backlight(PB_3) ;
trevieze 6:6eb4b9322931 81 // DigitalOut tsc_cs(PA_9, 1) ;
trevieze 6:6eb4b9322931 82 // DigitalOut tft_cs(PB_6, 1) ;
Rhyme 0:cd5e3d371b54 83
trevieze 8:8aa9cdab4a07 84 Serial pc(USBTX, USBRX);
trevieze 8:8aa9cdab4a07 85
trevieze 6:6eb4b9322931 86 // Display
Rhyme 0:cd5e3d371b54 87 ILI9341 TFT(SPI_8, 10000000,
trevieze 8:8aa9cdab4a07 88 PIN_MOSI_SPI1, PIN_MISO_SPI1, PIN_SCLK_SPI1,
trevieze 8:8aa9cdab4a07 89 PIN_CS_SPI1, PIN_RESET_TFT, PIN_DC_TFT, "Adafruit2.8") ;
trevieze 6:6eb4b9322931 90
trevieze 6:6eb4b9322931 91 // TouchScreen
trevieze 2:c5085faf2aa5 92 TouchScreen TSC(PIN_XP, PIN_XM, PIN_YP, PIN_YM);
Rhyme 0:cd5e3d371b54 93
trevieze 6:6eb4b9322931 94 // 3 Axis IMU
trevieze 7:b78ff34209e5 95 BNO055 imu(I2C_SDA, I2C_SCL, PIN_RESET); // Reset =D7, addr = BNO055_G_CHIP_ADDR, mode = MODE_NDOF <- as default
trevieze 6:6eb4b9322931 96
trevieze 6:6eb4b9322931 97 // Humidity and Temperature
trevieze 11:869a102dd31c 98 HTU21D humid(I2C_SDA, I2C_SCL);
trevieze 6:6eb4b9322931 99
trevieze 6:6eb4b9322931 100 // Pressure
trevieze 7:b78ff34209e5 101 BMP180 bmp180(I2C_SDA, I2C_SCL);
trevieze 6:6eb4b9322931 102
trevieze 8:8aa9cdab4a07 103 // SD Card Reader On Adafruit GPS Shield
trevieze 8:8aa9cdab4a07 104 SDFileSystem sd(PIN_MOSI_SPI3, PIN_MISO_SPI3, PIN_SCLK_SPI3, PIN_CS_SPI3, "sd"); // the pinout on the mbed Cool Components workshop board
trevieze 8:8aa9cdab4a07 105
trevieze 9:855884782f67 106 // Set up serial interrupe service handler for gps characters.
trevieze 8:8aa9cdab4a07 107 GPS MyGPS(PIN_TX_GPS,PIN_RX_GPS, 9600);
trevieze 9:855884782f67 108
trevieze 11:869a102dd31c 109 void Draw_Compass_Rose(void);
trevieze 11:869a102dd31c 110 void arrow(int x2, int y2, int x1, int y1, int alength, int awidth, int colour);
Rhyme 0:cd5e3d371b54 111
trevieze 11:869a102dd31c 112 const int centreX = 120;
trevieze 11:869a102dd31c 113 const int centreY = 150;
trevieze 11:869a102dd31c 114 const int radius = 40;
Rhyme 0:cd5e3d371b54 115
Rhyme 0:cd5e3d371b54 116 int main()
Rhyme 0:cd5e3d371b54 117 {
trevieze 10:a3cb458d7b1c 118 TFT.BusEnable(true) ;
trevieze 10:a3cb458d7b1c 119 TFT.FastWindow(true) ;
trevieze 10:a3cb458d7b1c 120 wait(0.1);
trevieze 10:a3cb458d7b1c 121 TFT.cls();
trevieze 10:a3cb458d7b1c 122 wait(0.1);
trevieze 8:8aa9cdab4a07 123 Timer refresh_Timer; //sets up a timer for use in loop; how often do we print GPS info?
trevieze 10:a3cb458d7b1c 124 const int refresh_Time = 2000; //refresh time in ms
trevieze 8:8aa9cdab4a07 125 refresh_Timer.start(); //starts the clock on the timer
trevieze 8:8aa9cdab4a07 126 //backlight = 0 ;
trevieze 11:869a102dd31c 127 TFT.set_font((unsigned char*) Arial24x23i);
trevieze 10:a3cb458d7b1c 128 TFT.fillrect(2, 2, 237, 317, White);
trevieze 10:a3cb458d7b1c 129 TFT.foreground(Blue);
trevieze 10:a3cb458d7b1c 130 TFT.background(White);
trevieze 10:a3cb458d7b1c 131 wait(0.1);
trevieze 10:a3cb458d7b1c 132
trevieze 11:869a102dd31c 133 Draw_Compass_Rose();
trevieze 11:869a102dd31c 134
trevieze 8:8aa9cdab4a07 135 while (1) {
trevieze 11:869a102dd31c 136
trevieze 11:869a102dd31c 137 TFT.set_font((unsigned char*) ArialR20x20);
trevieze 11:869a102dd31c 138 //check if we recieved a new message from GPS, if so, attempt to parse it,
trevieze 8:8aa9cdab4a07 139 if (refresh_Timer.read_ms() >= refresh_Time) {
trevieze 8:8aa9cdab4a07 140 refresh_Timer.reset();
trevieze 10:a3cb458d7b1c 141
trevieze 11:869a102dd31c 142 if (bmp180.init() != 0) {
trevieze 11:869a102dd31c 143 //pc.printf("Error communicating with BMP180\n");
trevieze 11:869a102dd31c 144 } else {
trevieze 11:869a102dd31c 145 //pc.printf("Initialized BMP180\n");
trevieze 11:869a102dd31c 146 bmp180.startTemperature();
trevieze 11:869a102dd31c 147 wait(0.1); // Wait for conversion to complete
trevieze 11:869a102dd31c 148 float temp;
trevieze 11:869a102dd31c 149 if(bmp180.getTemperature(&temp) != 0) {
trevieze 11:869a102dd31c 150 //pc.printf("Error getting temperature\n");
trevieze 11:869a102dd31c 151 }
trevieze 11:869a102dd31c 152 //pc.printf("Temperature is : %f", temp);
trevieze 11:869a102dd31c 153 TFT.locate(4, 26) ;
trevieze 11:869a102dd31c 154 TFT.printf("%.1fF", ((temp* 9.0) / 5.0 + 32));
trevieze 11:869a102dd31c 155 }
trevieze 11:869a102dd31c 156 int ftemp = humid.sample_ftemp();
trevieze 11:869a102dd31c 157 int humidity = humid.sample_humid();
trevieze 11:869a102dd31c 158 TFT.locate(140, 26) ;
trevieze 11:869a102dd31c 159 TFT.printf("%d%%RH",humidity);
trevieze 11:869a102dd31c 160 //pc.printf("HTU21D Temp: %d",ftemp);
trevieze 11:869a102dd31c 161 //pc.printf("HTU21D Humidity: %d",humidity);
trevieze 11:869a102dd31c 162
trevieze 11:869a102dd31c 163
trevieze 11:869a102dd31c 164 if (imu.chip_ready() == 0){
trevieze 11:869a102dd31c 165 pc.printf("Bosch BNO055 is NOT avirable!!\r\n");
trevieze 11:869a102dd31c 166 } else {
trevieze 11:869a102dd31c 167 printf("Cal %d", imu.read_calib_status());
trevieze 11:869a102dd31c 168 if (imu.read_calib_status() > 0x0){
trevieze 11:869a102dd31c 169 TFT.foreground(White);
trevieze 11:869a102dd31c 170 TFT.locate(4, 260) ;
trevieze 11:869a102dd31c 171 TFT.printf("No Data");
trevieze 11:869a102dd31c 172 TFT.foreground(Blue);
trevieze 11:869a102dd31c 173 imu.get_Euler_Angles(&euler_angles);
trevieze 11:869a102dd31c 174 imu.get_quaternion(&quaternion);
trevieze 11:869a102dd31c 175 TFT.locate(4, 260) ;
trevieze 11:869a102dd31c 176 TFT.printf("%.1f",euler_angles.h);
trevieze 11:869a102dd31c 177 //pc.printf("H %.1f",euler_angles.h);
trevieze 11:869a102dd31c 178 //pc.printf("R %.1f",euler_angles.r);
trevieze 11:869a102dd31c 179 //pc.printf("P %.1f",euler_angles.p);
trevieze 11:869a102dd31c 180
trevieze 11:869a102dd31c 181 } else {
trevieze 11:869a102dd31c 182 TFT.locate(4, 260) ;
trevieze 11:869a102dd31c 183 TFT.printf("No Data");
trevieze 11:869a102dd31c 184 }
trevieze 11:869a102dd31c 185 }
trevieze 11:869a102dd31c 186
trevieze 11:869a102dd31c 187 float last_dx;
trevieze 11:869a102dd31c 188 float last_dy;
trevieze 11:869a102dd31c 189 float angle = int(euler_angles.h * 180/PI); // Convert radians to degrees for more a more usual result
trevieze 11:869a102dd31c 190 // For the screen -X = up and +X = down and -Y = left and +Y = right, so does not follow coordinate conventions
trevieze 11:869a102dd31c 191 float dx = (0.7*radius * cos((angle-90)*PI/180)) + centreX; // calculate X position for the screen coordinates - can be confusing!
trevieze 11:869a102dd31c 192 float dy = (0.7*radius * sin((angle-90)*PI/180)) + centreY; // calculate Y position for the screen coordinates - can be confusing!
trevieze 11:869a102dd31c 193 arrow(last_dx,last_dy, centreX, centreY, 2,2,White); // Erase last arrow
trevieze 11:869a102dd31c 194 arrow(dx,dy, centreX, centreY, 2, 2,Blue); // Draw arrow in new position
trevieze 11:869a102dd31c 195 last_dx = dx;
trevieze 11:869a102dd31c 196 last_dy = dy;
trevieze 11:869a102dd31c 197
trevieze 11:869a102dd31c 198
trevieze 10:a3cb458d7b1c 199 if (MyGPS.dataready()) {
trevieze 10:a3cb458d7b1c 200 MyGPS.read();
trevieze 11:869a102dd31c 201 //pc.printf("NMEA has valid data");
trevieze 11:869a102dd31c 202 //pc.printf("Sats : %d \n", MyGPS.buffer.satellites);
trevieze 11:869a102dd31c 203 //pc.printf("%d-%d-%d\n", MyGPS.buffer.month, MyGPS.buffer.day, MyGPS.buffer.year);
trevieze 11:869a102dd31c 204 //pc.printf("%d:%d:%d\n", MyGPS.buffer.hours, MyGPS.buffer.minutes, MyGPS.buffer.seconds);
trevieze 10:a3cb458d7b1c 205
trevieze 11:869a102dd31c 206 TFT.foreground(White);
trevieze 11:869a102dd31c 207 TFT.locate(4, 2) ;
trevieze 11:869a102dd31c 208 TFT.printf("No Data");
trevieze 11:869a102dd31c 209 TFT.foreground(Blue);
trevieze 11:869a102dd31c 210 TFT.locate(4, 2) ;
trevieze 10:a3cb458d7b1c 211 TFT.printf("%d-%d-%d", MyGPS.buffer.month, MyGPS.buffer.day, MyGPS.buffer.year);
trevieze 11:869a102dd31c 212 TFT.locate(140, 2) ;
trevieze 10:a3cb458d7b1c 213 TFT.printf("%d:%d:%d", MyGPS.buffer.hours, MyGPS.buffer.minutes, MyGPS.buffer.seconds);
trevieze 11:869a102dd31c 214 TFT.locate(140, 260) ;
trevieze 11:869a102dd31c 215 TFT.printf("%.1fft", MyGPS.buffer.altitude/0.3048);
trevieze 11:869a102dd31c 216 TFT.locate(4, 280) ;
trevieze 11:869a102dd31c 217 int degree;
trevieze 11:869a102dd31c 218 int minutes;
trevieze 11:869a102dd31c 219 int seconds;
trevieze 11:869a102dd31c 220 degree = (int)MyGPS.buffer.longitude;
trevieze 11:869a102dd31c 221 minutes = (int) ( (MyGPS.buffer.longitude - (double)degree) * 60.0);
trevieze 11:869a102dd31c 222 seconds = (int) ( (MyGPS.buffer.longitude - (double)degree - (double)minutes / 60.0) * 60.0 * 60.0 );
trevieze 11:869a102dd31c 223 TFT.printf("%d %d' %d\"lon", degree, minutes,seconds);
trevieze 11:869a102dd31c 224 TFT.locate(4, 300) ;
trevieze 11:869a102dd31c 225 degree = (int)MyGPS.buffer.latitude;
trevieze 11:869a102dd31c 226 minutes = (int) ( (MyGPS.buffer.latitude - (double)degree) * 60.0);
trevieze 11:869a102dd31c 227 seconds = (int) ( (MyGPS.buffer.latitude - (double)degree - (double)minutes / 60.0) * 60.0 * 60.0 );
trevieze 11:869a102dd31c 228 TFT.printf("%d %d' %d\"lat", degree, minutes,seconds);
trevieze 11:869a102dd31c 229 TFT.set_font((unsigned char*) SCProSB31x55);
trevieze 11:869a102dd31c 230 TFT.locate(120, 200) ;
trevieze 11:869a102dd31c 231 TFT.printf("%.1f", MyGPS.buffer.speed);
trevieze 10:a3cb458d7b1c 232
trevieze 9:855884782f67 233 }
trevieze 9:855884782f67 234 else {
trevieze 11:869a102dd31c 235 TFT.locate(4, 2) ;
trevieze 11:869a102dd31c 236 TFT.printf("No Data");
trevieze 11:869a102dd31c 237 //pc.printf("NMEA has no valid data");
trevieze 9:855884782f67 238 }
trevieze 8:8aa9cdab4a07 239 }
trevieze 8:8aa9cdab4a07 240 }
trevieze 11:869a102dd31c 241 }
trevieze 11:869a102dd31c 242
trevieze 11:869a102dd31c 243 void arrow(int x2, int y2, int x1, int y1, int alength, int awidth, int colour) {
trevieze 11:869a102dd31c 244 float distance;
trevieze 11:869a102dd31c 245 int dx, dy, x2o,y2o,x3,y3,x4,y4,k;
trevieze 11:869a102dd31c 246 distance = sqrt(pow((double)(x1 - x2),2) + pow((double)(y1 - y2), 2));
trevieze 11:869a102dd31c 247 dx = x2 + (x1 - x2) * alength / distance;
trevieze 11:869a102dd31c 248 dy = y2 + (y1 - y2) * alength / distance;
trevieze 11:869a102dd31c 249 k = awidth / alength;
trevieze 11:869a102dd31c 250 x2o = x2 - dx;
trevieze 11:869a102dd31c 251 y2o = dy - y2;
trevieze 11:869a102dd31c 252 x3 = y2o * k + dx;
trevieze 11:869a102dd31c 253 y3 = x2o * k + dy;
trevieze 11:869a102dd31c 254 x4 = dx - y2o * k;
trevieze 11:869a102dd31c 255 y4 = dy - x2o * k;
trevieze 11:869a102dd31c 256 TFT.line(x1, y1, x2, y2, colour);
trevieze 11:869a102dd31c 257 TFT.line(x1, y1, dx, dy, colour);
trevieze 11:869a102dd31c 258 TFT.line(x3, y3, x4, y4, colour);
trevieze 11:869a102dd31c 259 TFT.line(x3, y3, x2, y2, colour);
trevieze 11:869a102dd31c 260 TFT.line(x2, y2, x4, y4, colour);
trevieze 11:869a102dd31c 261 }
Rhyme 0:cd5e3d371b54 262
trevieze 11:869a102dd31c 263 void Draw_Compass_Rose(void) {
trevieze 11:869a102dd31c 264 int dxo, dyo, dxi, dyi;
trevieze 11:869a102dd31c 265 TFT.circle(centreX,centreY,radius,Blue); // Draw compass circle
trevieze 11:869a102dd31c 266 for (float i = 0; i <360; i = i + 22.5) {
trevieze 11:869a102dd31c 267 dxo = radius * cos(i*3.14/180);
trevieze 11:869a102dd31c 268 dyo = radius * sin(i*3.14/180);
trevieze 11:869a102dd31c 269 dxi = dxo * 0.95;
trevieze 11:869a102dd31c 270 dyi = dyo * 0.95;
trevieze 11:869a102dd31c 271 TFT.line(dxi+centreX,dyi+centreY,dxo+centreX,dyo+centreY,Blue);
trevieze 11:869a102dd31c 272 }
trevieze 11:869a102dd31c 273 TFT.set_font((unsigned char*) Arial12x12);
trevieze 11:869a102dd31c 274 TFT.foreground(Blue);
trevieze 11:869a102dd31c 275 TFT.background(White);
trevieze 11:869a102dd31c 276 TFT.locate((centreX-2),(centreY-24));
trevieze 11:869a102dd31c 277 TFT.printf("N");
trevieze 11:869a102dd31c 278 TFT.locate((centreX-2),(centreY+17));
trevieze 11:869a102dd31c 279 TFT.printf("S");
trevieze 11:869a102dd31c 280 TFT.locate((centreX+19),(centreY-3));
trevieze 11:869a102dd31c 281 TFT.printf("E");
trevieze 11:869a102dd31c 282 TFT.locate((centreX-23),(centreY-3));
trevieze 11:869a102dd31c 283 TFT.printf("W");
trevieze 10:a3cb458d7b1c 284 }