Works
Dependencies: BMP180 BNO055_fusion Fonts GPSISR HTU21D SDFileSystem UniGraphic mbed uGUI
Fork of Bicycl_Computer_NUCLEO-F411RE by
main.cpp
- Committer:
- trevieze
- Date:
- 2018-05-25
- Revision:
- 16:e81bd672196b
- Parent:
- 15:b174ec6e3ca0
File content as of revision 16:e81bd672196b:
/* mbed main.cpp to test adafruit 2.8" TFT LCD shiled w Touchscreen * Copyright (c) 2014, 2015 Motoo Tanaka @ Design Methodology Lab * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ /* * Note: This program is derived from the SeeeStudioTFTv2 program. * Although both program share same ILI9341 TFT driver, * the touch sensor was not same with the Display I purchased from Akizuki. * http://akizukidenshi.com/catalog/g/gM-07747/ * The touch sensor on the display is STMPE610, * so I hacked the minimum spi driver for it (polling mode only). */ #include "mbed.h" #include <math.h> #include "ILI9341.h" //#include "TFT.h" // Graphics GUI Library #include "ugui.h" #include "SeeedStudioTFTv2.h" #include "BNO055.h" #include "HTU21D.h" #include "BMP180.h" #include "SDFileSystem.h" #include "GPSISR.h" #include "nav.h" #include "ArialR16x17.h" #include "Arial24x23i.h" #include "Arial28x28.h" #include "Neu44x36.h" #include "SCProSB31x55.h" #include "Arial12x12.h" #include "ArialR20x20.h" //#define PIN_CS_TSC PA_9 //#define PIN_TSC_INTR PA_8 #define PIN_RESET_TFT PC_13 /* place holder */ //ILI9341 SPI PINS #define PIN_XP A3 #define PIN_XM A1 #define PIN_YP A2 #define PIN_YM A0 #define PIN_MOSI_SPI1 D11 //SPI 1 MOSI #define PIN_MISO_SPI1 D12 //SPI 1 MISO #define PIN_SCLK_SPI1 D13 //SPI 1 SLCK #define PIN_CS_SPI1 D5 // SPI CS D10 Was D5 #define PIN_DC_TFT D6 #define PIN_CS_SD D4 #define PIN_RESET D7 // SD Card on GPS shield PINS #define PIN_MOSI_SPI3 PB_15 //SPI 1 MOSI #define PIN_MISO_SPI3 PB_14 //SPI 1 MISO #define PIN_SCLK_SPI3 PB_13 //SPI 1 SLCK #define PIN_CS_SPI3 D2 // SPI CS #define PIN_RX_GPS PA_12 //GPS Shield RX pin #define PIN_TX_GPS PA_11 //GPS Shield TX pin #define PI 3.14159265358979f BNO055_ID_INF_TypeDef bno055_id_inf; BNO055_EULER_TypeDef euler_angles; BNO055_QUATERNION_TypeDef quaternion; BNO055_LIN_ACC_TypeDef linear_acc; BNO055_GRAVITY_TypeDef gravity; BNO055_TEMPERATURE_TypeDef chip_temp; #define DEVICE_NAME "F411RE" #ifndef TARGET_NECLEO_F411RE #define TARGET_NECLEO_F411RE #endif //DigitalOut backlight(PB_3) ; // DigitalOut tsc_cs(PA_9, 1) ; // DigitalOut tft_cs(PB_6, 1) ; /** Height of display using default orientation */ #define ILI9341_DEFAULT_HEIGHT 240 /** Width of display using default orientation */ #define ILI9341_DEFAULT_WIDTH 320 /** Height of display using swapped X/Y orientation */ #define ILI9341_SWITCH_XY_HEIGHT 320 /** Width of display using swapped X/Y orientation */ #define ILI9341_SWITCH_XY_WIDTH 240 Serial pc(USBTX, USBRX); // Display ILI9341 TFT(SPI_8, 20000000, PIN_MOSI_SPI1, PIN_MISO_SPI1, PIN_SCLK_SPI1, PIN_CS_SPI1, PIN_RESET_TFT, PIN_DC_TFT, "Adafruit2.8"); // TouchScreen TouchScreen TOUCH(PIN_XP, PIN_XM, PIN_YP, PIN_YM); // 3 Axis IMU BNO055 imu(I2C_SDA, I2C_SCL, PIN_RESET); // Reset =D7, addr = BNO055_G_CHIP_ADDR, mode = MODE_NDOF <- as default // Humidity and Temperature HTU21D humid(I2C_SDA, I2C_SCL); // Pressure BMP180 bmp180(I2C_SDA, I2C_SCL); // SD Card Reader On Adafruit GPS Shield SDFileSystem sd(PIN_MOSI_SPI3, PIN_MISO_SPI3, PIN_SCLK_SPI3, PIN_CS_SPI3, "sd"); // the pinout on the mbed Cool Components workshop board // Set up serial interrupe service handler for gps characters. GPS MyGPS(PIN_TX_GPS,PIN_RX_GPS, 9600); //Navigation Class. NAV nav; double plat = 42.826420; double plon = -84.219413; void Draw_Compass_Rose(void); void arrow(int x2, int y2, int x1, int y1, int alength, int awidth, int colour); void ili9341_pset(UG_S16 ul_x,UG_S16 ul_y, UG_COLOR ul_color); void window_1_callback( UG_MESSAGE* msg ); void window_2_callback( UG_MESSAGE* msg ); void window_3_callback( UG_MESSAGE* msg ); void cb1(void); const int centreX = 120; const int centreY = 150; const int radius = 40; float last_dx; float last_dy; int pageid = 1; bool pageinit = 0; #define PAGE1 1 #define PAGE2 2 #define PAGE3 3 UG_GUI gui; //Ticker to1; int main() { //to1.attach(&cb1, 2.0); TFT.BusEnable(true) ; TFT.FastWindow(true) ; wait(0.1); TFT.cls(); wait(0.1); UG_Init(&gui,ili9341_pset,ILI9341_DEFAULT_HEIGHT,ILI9341_DEFAULT_WIDTH); Timer refresh_Timer; //sets up a timer for use in loop; how often do we print GPS info? const int refresh_Time = 2000; //refresh time in ms refresh_Timer.start(); //starts the clock on the timer //backlight = 0 ; wait(0.1); // Draw_Compass_Rose(); /* Window 1 Bike Computer */ #define MAX_OBJECTS 10 UG_WINDOW window_1 ; /* Window */ UG_BUTTON button_1; /* Button container */ UG_BUTTON button_2; /* Button container */ UG_OBJECT obj_buff_wnd_1 [MAX_OBJECTS] ; /* Object buffer */ UG_WindowCreate ( &window_1 , obj_buff_wnd_1 , MAX_OBJECTS, window_1_callback); UG_WindowSetTitleTextFont ( &window_1 , &FONT_8X8 ) ; UG_WindowSetTitleText ( &window_1 , "Bike Computer" ) ; UG_WindowSetBackColor( &window_1 , C_GRAY ) ; UG_ButtonCreate (&window_1, &button_1, BTN_ID_0, 10 , 230 , 115 , 290 ); UG_ButtonCreate (&window_1, &button_2, BTN_ID_1, 125 , 230 , 225 , 290 ); UG_ButtonSetBackColor (&window_1 ,BTN_ID_0 , C_BLUE ) ; UG_ButtonSetForeColor (&window_1 ,BTN_ID_0 , C_WHITE ) ; UG_ButtonSetBackColor (&window_1 ,BTN_ID_1 , C_BLUE ) ; UG_ButtonSetForeColor (&window_1 ,BTN_ID_1 , C_WHITE ) ; UG_ButtonSetFont (&window_1 , BTN_ID_0 , &FONT_8X8) ; UG_ButtonSetFont (&window_1 , BTN_ID_1 , &FONT_8X8) ; UG_ButtonSetText (&window_1 , BTN_ID_0 , "Prev" ); UG_ButtonSetText (&window_1 , BTN_ID_1 , "Next" ); /* Window 2 e-Compass */ UG_WINDOW window_2 ; /* Window */ UG_BUTTON button_3; /* Button container */ UG_BUTTON button_4; /* Button container */ UG_OBJECT obj_buff_wnd_2 [MAX_OBJECTS] ; /* Object buffer */ UG_WindowCreate ( &window_2 , obj_buff_wnd_2 , MAX_OBJECTS, window_2_callback); UG_WindowSetTitleTextFont ( &window_2 , &FONT_8X8 ) ; UG_WindowSetTitleText ( &window_2 , "e-Compass" ) ; UG_WindowSetBackColor( &window_2 , C_GRAY ) ; UG_ButtonCreate (&window_2, &button_3, BTN_ID_2, 10 , 230 , 115 , 290 ); UG_ButtonCreate (&window_2, &button_4, BTN_ID_3, 125 , 230 , 225 , 290 ); UG_ButtonSetBackColor (&window_2 ,BTN_ID_2 , C_BLUE ) ; UG_ButtonSetForeColor (&window_2 ,BTN_ID_2 , C_WHITE ) ; UG_ButtonSetBackColor (&window_2 ,BTN_ID_3 , C_BLUE ) ; UG_ButtonSetForeColor (&window_2 ,BTN_ID_3 , C_WHITE ) ; UG_ButtonSetFont (&window_2 , BTN_ID_2 , &FONT_8X8) ; UG_ButtonSetFont (&window_2 , BTN_ID_3 , &FONT_8X8) ; UG_ButtonSetText (&window_2 , BTN_ID_2 , "Prev" ); UG_ButtonSetText (&window_2 , BTN_ID_3 , "Next" ); /* Window 3 GSP */ UG_WINDOW window_3 ; /* Window */ UG_BUTTON button_5; /* Button container */ UG_BUTTON button_6; /* Button container */ UG_OBJECT obj_buff_wnd_3 [MAX_OBJECTS] ; /* Object buffer */ UG_WindowCreate ( &window_3 , obj_buff_wnd_3 , MAX_OBJECTS, window_3_callback); UG_WindowSetTitleTextFont ( &window_3 , &FONT_8X8 ) ; UG_WindowSetTitleText ( &window_3 , "GPS Waypoints" ) ; UG_WindowSetBackColor( &window_3 , C_GRAY ) ; UG_ButtonCreate (&window_3, &button_5, BTN_ID_4, 10 , 230 , 115 , 290 ); UG_ButtonCreate (&window_3, &button_6, BTN_ID_5, 125 , 230 , 225 , 290 ); UG_ButtonSetBackColor (&window_3 ,BTN_ID_4 , C_BLUE ) ; UG_ButtonSetForeColor (&window_3 ,BTN_ID_4 , C_WHITE ) ; UG_ButtonSetBackColor (&window_3 ,BTN_ID_5 , C_BLUE ) ; UG_ButtonSetForeColor (&window_3 ,BTN_ID_5 , C_WHITE ) ; UG_ButtonSetFont (&window_3 , BTN_ID_4 , &FONT_8X8) ; UG_ButtonSetFont (&window_3 , BTN_ID_5 , &FONT_8X8) ; UG_ButtonSetText (&window_3 , BTN_ID_4 , "Prev" ); UG_ButtonSetText (&window_3 , BTN_ID_5 , "Next" ); /* Finally , show the window */ //UG_WindowShow(&window_1) ; //UG_WindowHide(&window_2); //UG_WindowHide(&window_3); //UG_Update(); while (1) { cb1(); TFT.set_font((unsigned char*) ArialR20x20); TFT.foreground(White); TFT.background(UG_WindowGetBackColor(&window_1)); //check if we recieved a new message from GPS, if so, attempt to parse it, if (refresh_Timer.read_ms() >= refresh_Time) { refresh_Timer.reset(); switch ( pageid ) { case PAGE1: { if (!pageinit) { UG_WindowHide(&window_2); UG_WindowHide(&window_3); UG_WindowShow(&window_1); UG_Update(); } pageinit = 1; if (bmp180.init() != 0) { //pc.printf("Error communicating with BMP180\n"); } else { //pc.printf("Initialized BMP180\n"); bmp180.startTemperature(); wait(0.1); // Wait for conversion to complete float temp; if(bmp180.getTemperature(&temp) != 0) { //pc.printf("Error getting temperature\n"); } TFT.locate(10, 50) ; TFT.printf("%.1fF", ((temp* 9.0) / 5.0 + 32)); } int ftemp = humid.sample_ftemp(); int humidity = humid.sample_humid(); TFT.locate(10, 72) ; TFT.printf("%d%%RH",humidity); if (MyGPS.dataready()) { MyGPS.read(); TFT.locate(10, 26) ; TFT.foreground(UG_WindowGetBackColor(&window_1)); TFT.printf("No GPS Data"); TFT.foreground(White); TFT.locate(10, 26) ; TFT.printf("%d:%d:%d", MyGPS.buffer.hours, MyGPS.buffer.minutes, MyGPS.buffer.seconds); TFT.locate(100, 26) ; TFT.printf("%d-%d-%d", MyGPS.buffer.month, MyGPS.buffer.day, MyGPS.buffer.year); TFT.set_font((unsigned char*) SCProSB31x55); TFT.locate(130, 180) ; TFT.printf("%.1f", MyGPS.buffer.speed); TFT.locate(10, 180) ; TFT.printf("%.1f", MyGPS.buffer.speed); //Cadence TFT.set_font((unsigned char*) ArialR20x20); //TFT.locate(10, 50) ; //double waypoint = nav.CalculateDistance(MyGPS.buffer.latitude,MyGPS.buffer.longitude,plat,plon)/double(1609.344); //TFT.printf("%.1fMI From Perry", waypoint); } else { TFT.locate(10, 26) ; TFT.printf("No GPS Data"); //pc.printf("NMEA has no valid data"); } break; } case PAGE2: { if (!pageinit) { UG_WindowHide(&window_1); UG_WindowHide(&window_3); UG_WindowShow(&window_2); UG_Update(); } pageinit = 1; break; } case PAGE3: { if (!pageinit) { UG_WindowHide(&window_1); UG_WindowHide(&window_2); UG_WindowShow(&window_3); UG_Update(); } pageinit = 1; break; } } } /* TFT.locate(140, 260) ; TFT.printf("%.1fft", MyGPS.buffer.altitude/0.3048); TFT.locate(4, 280) ; int degree; int minutes; int seconds; degree = (int)abs(MyGPS.buffer.longitude); minutes = (int) ( (abs(MyGPS.buffer.longitude) - (double)degree) * 60.0); seconds = (int) ( (abs(MyGPS.buffer.longitude) - (double)degree - (double)minutes / 60.0) * 60.0 * 60.0 ); TFT.printf("%d %d' %d\" %c lon", degree, minutes,seconds, MyGPS.buffer.lonc); TFT.locate(4, 300) ; TFT.locate(4, 300) ; degree = (int)abs(MyGPS.buffer.latitude); minutes = (int) ( (abs(MyGPS.buffer.latitude) - (double)degree) * 60.0); seconds = (int) ( (abs(MyGPS.buffer.latitude) - (double)degree - (double)minutes / 60.0) * 60.0 * 60.0 ); TFT.printf("%d %d' %d\" %c lat", degree, minutes,seconds, MyGPS.buffer.latc); //pc.printf("Dist to Perry %.4f ", nav.CalculateDistance(MyGPS.buffer.latitude,MyGPS.buffer.longitude,plat,plon)); } if (imu.chip_ready() == 0){ pc.printf("Bosch BNO055 is NOT avirable!!\r\n"); } else { if (imu.read_calib_status() > 0x0){ TFT.foreground(White); TFT.locate(4, 260) ; TFT.printf("No Data"); TFT.foreground(Blue); imu.get_Euler_Angles(&euler_angles); TFT.locate(4, 260) ; TFT.printf("%.1f @ %.1f",euler_angles.h, euler_angles.p); //pc.printf("H %d",(int)euler_angles.h); //pc.printf("R %.1f",euler_angles.r); //pc.printf("P %.1f",euler_angles.p); } else { TFT.locate(4, 260) ; TFT.printf("No Data"); } } float angle = euler_angles.h; // Convert radians to degrees for more a more usual result // For the screen -X = up and +X = down and -Y = left and +Y = right, so does not follow coordinate conventions float dx = (radius * cos((angle-90)*PI/180)) + centreX; // calculate X position for the screen coordinates - can be confusing! float dy = (radius * sin((angle-90)*PI/180)) + centreY; // calculate Y position for the screen coordinates - can be confusing! arrow(last_dx,last_dy, centreX, centreY, 2,2,White); // Erase last arrow arrow(dx,dy, centreX, centreY, 2, 2,Blue); // Draw arrow in new position last_dx = dx; last_dy = dy; } */ } } void arrow(int x2, int y2, int x1, int y1, int alength, int awidth, int colour) { float distance; int dx, dy, x2o,y2o,x3,y3,x4,y4,k; distance = sqrt(pow((double)(x1 - x2),2) + pow((double)(y1 - y2), 2)); dx = x2 + (x1 - x2) * alength / distance; dy = y2 + (y1 - y2) * alength / distance; k = awidth / alength; x2o = x2 - dx; y2o = dy - y2; x3 = y2o * k + dx; y3 = x2o * k + dy; x4 = dx - y2o * k; y4 = dy - x2o * k; TFT.line(x1, y1, x2, y2, colour); TFT.line(x1, y1, dx, dy, colour); TFT.line(x3, y3, x4, y4, colour); TFT.line(x3, y3, x2, y2, colour); TFT.line(x2, y2, x4, y4, colour); TFT.set_font((unsigned char*) Arial12x12); TFT.foreground(Blue); TFT.background(White); TFT.locate((centreX-2),(centreY-24)); TFT.printf("N"); TFT.locate((centreX-2),(centreY+17)); TFT.printf("S"); TFT.locate((centreX+19),(centreY-3)); TFT.printf("E"); TFT.locate((centreX-23),(centreY-3)); TFT.printf("W"); TFT.set_font((unsigned char*) ArialR20x20); } void Draw_Compass_Rose(void) { int dxo, dyo, dxi, dyi; TFT.circle(centreX,centreY,radius,Blue); // Draw compass circle for (float i = 0; i <360; i = i + 22.5) { dxo = radius * cos(i*3.14/180); dyo = radius * sin(i*3.14/180); dxi = dxo * 0.95; dyi = dyo * 0.95; TFT.line(dxi+centreX,dyi+centreY,dxo+centreX,dyo+centreY,Blue); } TFT.set_font((unsigned char*) Arial12x12); TFT.foreground(Blue); TFT.background(White); TFT.locate((centreX-2),(centreY-24)); TFT.printf("N"); TFT.locate((centreX-2),(centreY+17)); TFT.printf("S"); TFT.locate((centreX+19),(centreY-3)); TFT.printf("E"); TFT.locate((centreX-23),(centreY-3)); TFT.printf("W"); } void ili9341_pset(UG_S16 ul_x,UG_S16 ul_y, UG_COLOR ul_color) { TFT.pixel(ul_x, ul_y, ul_color); } void window_1_callback( UG_MESSAGE* msg ) { if ( msg->type == MSG_TYPE_OBJECT ) { if ( msg->id == OBJ_TYPE_BUTTON ) { switch ( msg->sub_id ) { case BTN_ID_0: { pageid--; if (pageid < 1) { pageid = 3; } pageinit = 0; break; } case BTN_ID_1: { pageid++; if (pageid > 3) { pageid = 1; } pageinit = 0; break; } } } } } void window_2_callback( UG_MESSAGE* msg ) { if ( msg->type == MSG_TYPE_OBJECT ) { if ( msg->id == OBJ_TYPE_BUTTON ) { switch ( msg->sub_id ) { case BTN_ID_2: { pageid--; if (pageid < 1) { pageid = 3; } pageinit = 0; break; } case BTN_ID_3: { pageid++; if (pageid > 3) { pageid = 1; } pageinit = 0; break; } } } } } void window_3_callback( UG_MESSAGE* msg ) { if ( msg->type == MSG_TYPE_OBJECT ) { if ( msg->id == OBJ_TYPE_BUTTON ) { switch ( msg->sub_id ) { case BTN_ID_4: { pageid--; if (pageid < 1) { pageid = 3; } pageinit = 0; break; } case BTN_ID_5: { pageid++; if (pageid > 3) { pageid = 1; } pageinit = 0; break; } } } } } void cb1(void) { point p; TOUCH.getTouch(p); if (p.z > __PRESURE) { UG_TouchUpdate ( p.x, p.y, TOUCH_STATE_PRESSED ) ; } else { UG_TouchUpdate (-1, -1, TOUCH_STATE_RELEASED ) ; } UG_Update(); }