Curtis Mattull
/
PANEL_GUI_hello_world
basic functional test of FT810 LCD via SPI
Diff: main.cpp
- Revision:
- 13:8f23699b9c9f
- Parent:
- 11:f6a146b62579
- Child:
- 14:52a03b4a0365
--- a/main.cpp Tue Apr 05 15:02:48 2016 +0000 +++ b/main.cpp Tue Apr 05 19:56:46 2016 +0000 @@ -11,9 +11,9 @@ ** two different colored liquids. Another purpose of this program is to also read back feedback from the two ITVs, a PF3W flow meter, ** and a PSE pressure sensor. The program also interfaces with an HMI controlled by a FT810 LCD driver. The interface controls the hardware ** and displays graphics. This program was designed for the Teensy and to control the Closed Loop Controller Brew Panel prototype board. -** +** ** Notes : The limitations of the VERTEX2II program forced us to create a bandage when trying to write images past pixel 511. The range of VERTEX2II is 0 to 511 - so in order to draw an image further away we had to use the translate command. +** so in order to draw an image further away we had to use the translate command. ** ** Todo : */ @@ -46,9 +46,10 @@ unsigned int CalVal0, CalVal1, CalVal2, CalVal3, CalVal4, curX, curY, pasX, pasY; // touchscreen calibration data and swiping variables. float PSEpressure, PFWflowrate = 0.0; // variables to store data used in calculating flow and pressure float ITVpressure1_feedback, ITVpressure2_feedback, ITVpressure1_user_input, ITVpressure2_user_input = 0.0; // variables to store data thats used in calculating the output and input pressure for the ITVs +float ITVpressure1_input_scaled, ITVpressure2_input_scaled = 0.0; float ITV1_pre, ITV1_fcal, ITV2_pre, ITV2_fcal, PFW_pre, PFW_fcal, PSE_pre, PSE_fcal = 0.0; // moving average filter variables -static float avg1 = 0.05; // filter value for new samples -static float avg2 = 0.95; // filter value previous samples +static float avg1 = 0.15; // filter value for new samples +static float avg2 = 0.85; // filter value previous samples uint16_t ITVpressure1_input_raw, ITVpressure2_input_raw = 0; // stores the raw 16 bit reads for the ITVs int16_t velocity, distance, touched, location, paslocation; // variables to handle the swiping and multiple pages char buffer[50]; // temporary buffer for writing characters to the LCD @@ -66,7 +67,7 @@ TFT.DLstart(); // start a new display command list TFT.DL(CLEAR_COLOR_RGB(255,255,255)); // set the clear color to white TFT.DL(CLEAR(1,1,1)); // clear buffers -> color buffer,stencil buffer, tag buffer - + TFT.DL(COLOR_RGB(0x00,0x7C,0xC4)); // generate border in SMC blue, all functions are in 1/16 pixel format TFT.DL(BEGIN(LINES)); TFT.DL(LINE_WIDTH(8 * 16)); @@ -139,12 +140,12 @@ TFT.DL(COLOR_RGB(0x00,0x7C,0xC4)); // set color to SMC blue for the text TFT.Text(265, 200, 31, 0, "ITV 1 Pressure"); // title block for screen TFT.DL(BEGIN(RECTS)); // draw rounded rectangle in SMC blue to act as background for where the feedback will be written - TFT.DL(VERTEX2F(300*16,265*16)); + TFT.DL(VERTEX2F(300*16,265*16)); TFT.DL(VERTEX2F(505*16,330*16)); TFT.DL(END()); ITVpressure1_feedback = (ITVpressure1_feedback_raw.read_u16() - 9430) * (70.0) / (48430 - 9430) + 0; // calibration and scaling math for the ITV feedback, 48430 = 20mA, 9430 = 4mA - ITV1_fcal = ITVpressure1_feedback; // moving average filter - ITV1_fcal *= avg1; + ITV1_fcal = ITVpressure1_feedback; // moving average filter + ITV1_fcal *= avg1; ITV1_fcal += ITV1_pre * avg2; ITV1_pre = ITV1_fcal; ITVpressure1_feedback = ITV1_fcal; // store the filtered value in the feedback variable @@ -152,7 +153,7 @@ sprintf(buffer, "%.1f", ITVpressure1_feedback); // write the feedback pressure to the screen TFT.Text(325,275,31,0,buffer); TFT.Text(415, 275, 31, 0, " PSI"); // write the units to the screen - + TFT.DL(COLOR_RGB(255,255,255)); // controls the color of the slider bar in RGB format TFT.FgColor(COLOR_RGB(0,124,196)); // foreground color set to SMC blue in RGB format TFT.BgColor(COLOR_RGB(0,124,196)); // background color set to SMC blue in RGB format @@ -165,7 +166,7 @@ /*ITV 2 and PF3W Screen Display*/ TFT.DL(COLOR_RGB(255,255,255)); // set background color to white TFT.DL(VERTEX_TRANSLATE_X(location* 16)+12800); // translate screen writes by 12800 which is a 1/16th pixel format, this creates page 2 of the screen - TFT.DL(BEGIN(BITMAPS)); // draw a bitmap that stores the second screens images + TFT.DL(BEGIN(BITMAPS)); // draw a bitmap that stores the second screens images TFT.DL(VERTEX2II(30,75,3,0)); // write PF3W_1 image to the LCD TFT.DL(VERTEX_TRANSLATE_X((149+location)*16)+12800); // translate right 149 pixels for third image, location controls what page the screen is on TFT.DL(VERTEX2II(411,75,4,0)); // write PF3W_2 image to the LCD @@ -178,7 +179,7 @@ TFT.DL(VERTEX2F(300*16,265*16)); TFT.DL(VERTEX2F(505*16,330*16)); TFT.DL(END()); - + ITVpressure2_feedback = (ITVpressure2_feedback_raw.read_u16()- 9365) * (70.0) / (48420 - 9365) + 0; // calibration and scaling math for the ITV feedback, 48420 = 20mA, 9365 = 4mA ITV2_fcal = ITVpressure2_feedback; // moving average filter ITV2_fcal *= avg1; @@ -188,7 +189,7 @@ TFT.DL(COLOR_RGB(255,255,255)); // set color for text to white sprintf(buffer, "%.1f", ITVpressure2_feedback); // write feedback to screen in white TFT.Text(325,275,31,0,buffer); - TFT.Text(415, 275, 31, 0, " PSI"); // write the units to the screen + TFT.Text(415, 275, 31, 0, " PSI"); // write the units to the screen TFT.DL(COLOR_RGB(255,255,255)); // controls the color of the slider bar in RGB format TFT.FgColor(COLOR_RGB(0,124,196)); // foreground color set to SMC blue in RGB format TFT.BgColor(COLOR_RGB(0,124,196)); // background color set to SMC blue in RGB format @@ -214,7 +215,7 @@ /***************************************************************************************************/ /***************************************************************************************************/ - /*ISE Screen Display*/ + /*PSE Screen Display*/ TFT.DL(COLOR_RGB(255,255,255)); // set the background for page 3 to white TFT.DL(VERTEX_TRANSLATE_X(location* 16)+25600); // translate screen writes by 25600 which is a 1/16th pixel format, this creates page 3 of the screen TFT.DL(BEGIN(BITMAPS)); // create bitmap to draw images on LCD @@ -248,7 +249,7 @@ TFT.Number(20, 450, 26, 0, distance); // write distance value to screen TFT.Number(80, 450, 26, 0, velocity); // write velocity to screen #endif - + #ifdef Debug_Touch_File // debug the touch up load TFT.DL(COLOR_RGB(0,0,0)); // set text color to black int j; // loop counter @@ -264,17 +265,17 @@ } /****************************************************************************/ -/* This function displays the error screen when an SD card isn't detected */ +/* This function displays the error screen */ /* the function causes the screen to flash yellow and writes text to the LCD*/ /****************************************************************************/ -void error_screen_SD() +void error_screen(ft_char8_t *str1, ft_char8_t *str2) { TFT.DLstart(); // start a new display command list TFT.DL(CLEAR_COLOR_RGB(255,242,0)); // clear the screen and set the background to yellow TFT.DL(CLEAR(1,1,1)); // clear buffers -> color buffer,stencil buffer, tag buffer TFT.DL(COLOR_RGB(0,0,0)); - TFT.Text((TFT.DispWidth/2), 170, 31, OPT_CENTERX, "Error!"); // draw Text with font 31 - TFT.Text((TFT.DispWidth/2), 215, 31, OPT_CENTERX, "Insert SD Card!"); // draw Text with font 31 + TFT.Text((TFT.DispWidth/2), 170, 31, OPT_CENTERX, str1); // draw Text with font 31 + TFT.Text((TFT.DispWidth/2), 215, 31, OPT_CENTERX, str2); // draw Text with font 31 TFT.DL(DISPLAY()); // display the image TFT.Swap(); // swap the current display list TFT.Flush_Co_Buffer(); // download the command list into fifo @@ -285,8 +286,8 @@ TFT.DL(CLEAR_COLOR_RGB(255,255,255)); // set clear color to white TFT.DL(CLEAR(1,1,1)); // clear buffers -> color buffer,stencil buffer, tag buffer; TFT.DL(COLOR_RGB(0,0,0)); - TFT.Text((TFT.DispWidth/2), 170, 31, OPT_CENTERX, "Error!"); // draw Text with font 31 - TFT.Text((TFT.DispWidth/2), 215, 31, OPT_CENTERX, "Insert SD Card!"); // draw Text with font 31 + TFT.Text((TFT.DispWidth/2), 170, 31, OPT_CENTERX, str1); // draw Text with font 31 + TFT.Text((TFT.DispWidth/2), 215, 31, OPT_CENTERX, str2); // draw Text with font 31 TFT.DL(DISPLAY()); // display the image TFT.Swap(); // swap the current display list TFT.Flush_Co_Buffer(); // download the command list into fifo @@ -302,7 +303,7 @@ { int i = 0; // loop counter while(card_present.read()) { // checks for SD card, if not present hold program until a SD card is inserted - error_screen_SD(); // write error screen to LCD + error_screen("Error!","Insert SD card!"); // write error screen to LCD } FILE *fp = fopen("/sd/TCal/TCalData.txt", "a"); // open touchscreen calibration data from SD card fp= fopen("/sd/TCal/TCalData.txt", "r"); @@ -354,6 +355,22 @@ } /****************************************************************************/ +/* Function that checks for a inadequate supply pressure and displays */ +/* an error */ +/****************************************************************************/ +void SupplyPressure_Check(float check1, float check2) +{ + while(((PSEpressure*145.0377) < (check1 - 10)) || ((PSEpressure*145.0377) < (check2 - 10))) { + dac1.write_u12(0); // turn off ITVs + dac2.write_u12(0); + error_screen("Supply pressure too low!", ""); // display error + PSEpressure = (PSEpressure_raw.read_u16() - 10440) * (1.0) / (52350 - 10440) + 0; // check for supply pressure + } + dac1.write_u12(ITVpressure1_input_raw); // restore ITV pressure + dac2.write_u12(ITVpressure2_input_raw); +} + +/****************************************************************************/ /* Main function that tracks all of the touchscreen data and updates the */ /* screen accordingly */ /****************************************************************************/ @@ -368,80 +385,71 @@ TFT.MemWrite(REG_ROTATE, 1); // rotate screen TFT.Rotate(1); - Start_Screen("Starting..."); // show start screen + SupplyPressure_Check(0,0); // check for any supply pressure touchscreen_Calibration(); // load touchscreen calibration data initialize_Images(); // load and initialize images - + Start_Screen("Starting..."); // show start screen + TFT.Track(200, 400, 375, 50, 1); // track sliders TFT.Track(200, 400, 375, 50, 2); TFT.Flush_Co_Buffer(); // download the command list into fifo TFT.WaitCmdfifo_empty(); // wait till coprocessor completes the operation - + while(1) { - curY = TFT.Rd32(REG_TOUCH_SCREEN_XY)& 0xffff; // touch positions - curX = TFT.Rd32(REG_TOUCH_SCREEN_XY)>>16; + curY = TFT.Rd32(REG_TOUCH_SCREEN_XY)& 0xffff; // get the current touch screen position + curX = TFT.Rd32(REG_TOUCH_SCREEN_XY)>>16; // if not touch the results are 0x8000 for x and y ft_uint8_t tagval = 0; // initialize return tag value TrackRegisterVal = TFT.Rd32(REG_TRACKER); // check if one of the two tracking fields is touched tagval = TrackRegisterVal & 0xff; // store return tag value // check what tag was touched - if(1 == tagval) { // tag value for ITV1 slider touch + if(1 == tagval) { // tag value for ITV1 slider touch ITVpressure1_user_input = (TrackRegisterVal>>20) * (2356.0/4095); // calculate new slider value so that the slider updates graphically ITVpressure1_input_raw = (TrackRegisterVal>>20) * (2356.0/4095) + 590; // calculate raw 12 bit input number, includes calibration number to never go above 20mA dac1.write_u12(ITVpressure1_input_raw); // write 12 bit number to DAC to fire the ITV - } - + ITVpressure1_input_scaled = (ITVpressure1_input_raw-590)*(70.0)/(4095)+0; + } + else if(2 == tagval) { // tag value for ITV2 slider touch ITVpressure2_user_input = (TrackRegisterVal>>20) * (2386.0/4095); // calculate new slider value so that the slider updates graphically ITVpressure2_input_raw = (TrackRegisterVal>>20) * (2386.0/4095) + 585; // calculate raw 12 bit input number, includes calibration number to never go above 20mA dac2.write_u12(ITVpressure2_input_raw); // write 12 bit number to DAC to fire the ITV - } - - else if (200 == tagval) { + ITVpressure2_input_scaled = (ITVpressure2_input_raw-590)*(70.0)/(4095)+0; + } + + else if (200 == tagval) { // tag for the reprogram button that works by exiting the program which cases the teensy to load the bootloader break; - } else if(curX !=0x8000 && touched>0) { - touched++; - distance = curX - pasX; - location = (int16_t)paslocation + distance; + } else if(curX !=0x8000 && touched>0) { // If the sceen is being touched and has been touched before and is not on a tag + touched++; // touched is used to determine how long the screen has beed touched for and if it is currently being touched + distance = curX - pasX; // find the swipe distance in pixels + location = (int16_t)paslocation + distance; // add the distance of the swipe to the location so the screen moves as you swipe - - } - - else if(curX !=0x8000 && !touched) { + } else if(curX !=0x8000 && !touched) { // If the screen is being touched but was not the pervious time through the loop then this is the starting point of the swipe touched++; pasX = curX; - // - } - - else if(curX ==0x8000 && touched) { - velocity = distance/touched; - paslocation = location; - touched=0; - - - } - - else { + } else if(curX ==0x8000 && touched) { // Not being touched currently but was touched last time through the loop + velocity = distance/touched; // Now that the swipe is finished we can calculate the velocity from the distance and time touched + paslocation = location; // Store Location data away + touched=0; // Reset for the next touch + // If not being touched + } else { //page 4 location - if (location < - 2300 && location > -2500) { - if (velocity) { - velocity = (location + 2400)/-5; - location += (int16_t) velocity; + if (location < - 2300 && location > -2500) { // If you are close to the edge of the fourth Page + if (velocity) { // and you have some velocity + velocity = (location + 2400)/-5; // adjust velocity based on how close to the edge + location += (int16_t) velocity; // move the location at the speed of velocity paslocation = location; - } - else { + } else { // velocity will become zero as you get closer to the edge when this happens finish the move location = -2400; } - } //page 3 location - else if (location < - 1500 && location > -1700) { + else if (location < - 1500 && location > -1700) { // repeat for each page if (velocity) { velocity = (location + 1600)/-5; location += (int16_t) velocity; paslocation = location; - } - else { + } else { location = -1600; } @@ -452,48 +460,42 @@ velocity = (location + 800)/-5; location += (int16_t) velocity; paslocation = location; - } - else { + } else { location = -800; } //page 1 - } - else if (location > -100 && location < 100) { + } else if (location > -100 && location < 100) { if (velocity) { velocity = location/-5; location += (int16_t) velocity; paslocation = location; - } - else { + } else { location = 0; + } //no page 0 - } else if (location >60) { - velocity = -10; + } else if (location >60) { // Do not allow the page screen to go to -1 page + velocity = -10; // Change the velocity to return location += (int16_t) velocity; paslocation = location; - //no page 5 - } - else if (location <-1700) { - velocity = 10; + //no page 4 + } else if (location <-1700) { // Do not allow the page screen to go pass top page + velocity = 10; // Change the velocity to return location += (int16_t) velocity; paslocation = location; //between pages - } - else if (velocity) { + } else if (velocity) { // if the page is not at edge but has velocity location += (int16_t) velocity; paslocation = location; - //acceleration between pages - if (velocity >0) { - velocity+= 2; - } - else { + if (velocity >0) { // acceleration between pages so it does not take forever + velocity+= 2; // increase velocity + } else { velocity-= 2; } } } - + SupplyPressure_Check(ITVpressure1_input_scaled, ITVpressure2_input_scaled); // check to see if theres enough supply pressure for the ITVs Main_Screen(); // paint new screen TFT.Sleep(10); // wait 10ms for next time to repaint the screen } // end of display loop