Forum Rule: Always post complete source code & details to reproduce any issue!
Page 1 of 6 1 2 3 ... LastLast
Results 1 to 25 of 127

Thread: ILI9341 and XPT2046 for Teensy Touchscreen 320x240 display

  1. #1
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    7,358

    ILI9341 and XPT2046 for Teensy Touchscreen 320x240 display

    I got some of these PJRC displays that are in common use - mine wired up as indicated on these pages:

    Color 320x240 Touchscreen, 2.8 inch, ILI9341 Controller

    > this unit is the same smaller screen controller but without the XPT2046 TOUCH controller:
    Color 320x240 Display, 2.2 inch, ILI9341 Controller

    My current example set of Touch enabled ILI9341 sketches:
    https://github.com/Defragster/XPT2046_Touch_Examples

    There are two other active threads with Touch posts - hoping to merge activity on this to here from:
    2.8 ILI9341 restive touch miso not connected ?

    Highly optimized ILI9341 (320x240 TFT color display) library

  2. #2
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    7,358
    <edit>: Last update 1/1/2016
    From GitHub ReadMe::

    Examples using the Teensy XPT2046_Touchscreen

    MARK3 examples are the latest. ButtonCode moved to separate file. Button mapping struct evolved. Stored the Mapping Data in 'sketch'.h header file so it isn't always in the way.

    The examples here develop a uniform structured way to implement and handle TOUCH BUTTONS

    There is interrupt awareness in PJRC XPT2046_Touchscreen library starting in TeensyDuino 1.27b2: \hardware\teensy\avr\libraries\XPT2046_Touchscreen

    Purged some older samples - it was an evolving project - started buttons - started in sketch interrupts - moved interrupt code to core library - if you are looking start with the MARK3 and any later examples. Any code with attachInterrupt is deprecatated with the release of TeensyDuino 1.27

    Feedback or questions at: https://forum.pjrc.com/threads/31634...20x240-display.

    If you get a compile error on "XPT2046_Touchscreen ts(CS_PIN, TIRQ_PIN);" you don't have the interrupt aware code, comment that line and remove comment from the other line: //XPT2046_Touchscreen ts(CS_PIN); // Param 2 - NULL - No interrupts and TeensyDuino version 1.26 libs

    To use on Teensy LC you must use the Adafruit_ILI9341 library not the ILI9341_t3 library, and "Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC);"
    Last edited by defragster; 01-03-2016 at 11:29 PM.

  3. #3
    Senior Member
    Join Date
    Oct 2015
    Posts
    227
    Much thanks for your hard work.

    Touch_Test works fine with my Teensy 3.2 and your code from GitHub.
    onoffbutton works great also.
    TouchPaint works but I'm sure correctly...as I draw lines, in the same color, pixels color up outside of the line I'm drawing. Other times the line draws for about an inch and then stops coloring as I continue to move my plastic pencil tip. I don't need the capabilities in this sketch but thought I'd report my findings anyway.

    Touch_Test and onoffbutton sketches I need to dive into and learn how they are working. I need to display text on my screen and some buttons with text labels on them...the buttons I need to be able to touch and detect. So that's what I'll be looking over in your sketches.

    Much thanks again.

  4. #4
    Senior Member
    Join Date
    Oct 2013
    Posts
    253
    @rfresh737 did you have the serial monitor up while you used touchpaint? If not try it with a monitor window open and let me know what happens.

  5. #5
    Senior Member
    Join Date
    Oct 2015
    Posts
    227
    With the serial window open it worked fine!!!

  6. #6
    Senior Member
    Join Date
    Oct 2013
    Posts
    253
    @defragster see I wasn't crazy

  7. #7
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    7,358
    @cartere: I don't see a note on which doesn't work without the Serial Monitor open? When I ran off battery with no usb - what I tried worked.

    Also I 'hid' the odd behavior in the buttons on TouchPaint - but it is odd with x,y not as expected. I didn't look at that - somebody did on another thread - if that fix applies to touch paint here let me know and I'll turn it around. When I did the debug version it got in the way - but I just dealt with it.

    @rfresh737 - the interrupt code is having an issue with losing touch I didn't see for a long time. But you say 'TouchPaint' - I see that uses the interrupt - not sure when I did that as it does not have the backup timer when interrupt not provided. I wanted to get these cleaned up before starting this thread - but the other two threads were getting too many hits to track - so I did it and put all code in one place - not sure what is what just now, thanks for the post.

    The OnOffButton is the best so far as far as where the button 'language' is headed - but uses polling. I saw a post about the button hits streaming in - that is expected because the touch is still happening. That is for the user code to deal with I think as hiding ongoing touches would end up bothering other uses: like a VOL UP and VOL DOWN button could time the length of the button and adjust the volume. Also Frank wants a potentiometer like slider that would track the user adjusting edge to edge on the button and the returned value could be important to track in real time.

    Had a windstorm here - been running house on a generator the last 24 hours now - a bit of added distraction.

  8. #8
    Senior Member
    Join Date
    Oct 2015
    Posts
    227
    @defragster

    In the button structure definition, what is the 7th parameter for? TS_FBUTN, TS_TOGON + 1, TS_TOGOFF +1 etc. etc.

    EDIT: the 5th and 6th parameters are colors for the buttons but it looks like one is for when the button has the focus and the other color for when it doesn't have the focus?
    Last edited by rfresh737; 11-18-2015 at 11:53 PM.

  9. #9
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    7,358
    Looking at : GitHub\XPT2046_Touch_Examples\onoffbutton - struct below. That needs to be cleaned up, was supposed to have added elements by now.

    ... I started to make a simple button - then there was another button type - then another - so I overloaded the fields without making it right in order to support ever more button styles going forward.

    fgc - is forground color for text
    bgc is the button background fill color. { the union .togval was a quick fix where FRAME button are just a border connecting the indexed sub-buttons }
    info should become two values - now that is ButtonType tracking toggle button state and the index number to its owner frame

    That kludge is TOGGLE specific - where a FRAME holds two TOGGLE sides. For simple touch select buttons that isn't used.

    Code:
    //        { tx, ty, ww, hh, fgc, {bgc_togval}, info, text[8], bId }    << Struct looks like this

  10. #10
    Senior Member
    Join Date
    Oct 2015
    Posts
    227
    I see...my button requirement is dead simple: I just need to paint a button with text on it and be able to touch it and then have my code do some thing after detecting the touch...so I don't need to use the FRAME toggle structure.

    Just curious, does your button code support round corner buttons or just square buttons at this time?

    EDIT: BTW I don't know how important this is or if it even matters, but when I touch the Clr button, the whole screen refreshes...when I touch Hi! it just toggles back nicely without the whole screen refreshing.

    Thanks...
    Last edited by rfresh737; 11-19-2015 at 05:46 AM.

  11. #11
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    7,358
    Right now all the frames are square. It could do a rounded rectangle easily enough - of course then you have to define the corner radius.

    But the hit test area should be a rectangle - that would need to include the fill area outside the rounded corners

  12. #12
    Senior Member
    Join Date
    Oct 2015
    Posts
    227
    Yeah...I can live with square buttons.

    I'm trying to use your code and start off by making just one button and then detecting a touch on it.

    1. So below here I am defining one button. It displays correctly in the x,y location. The fill color is working but the text fgc is not...no matter what colors I try, it doesn't change the text color.

    2. The touch area is off...I think because I am using rotation #3. I don't need to rotate the display. I can actually touch in the lower right corner and see the serial window display print the results of the touch. But my button is in the upper left corner of the screen!

    3. My text is short, only "PFD", is there anyway I can center that text in the button face?

    4. For clarification, TS_FBUTN defines this item as a stand alone button?

    Code:
    TS_BUTTON buttons[] = {
      {10, 25, 100, 50, ILI9341_BLACK, ILI9341_CYAN, TS_FBUTN, "PFD", 200 },
    /*  {10, 80, 100, 50, ILI9341_BLACK, 0, TS_FRAME + 1, "???", 101 },
      {10, 80, 50, 50, ILI9341_RED, ILI9341_BLUE, TS_TOGON + 1, "ROT", 1 }, {60, 80, 50, 50, ILI9341_GREEN, ILI9341_BLUE, TS_TOGOFF + 1, "SIT", 51 },
      {10, 135, 100, 50, ILI9341_RED, 1, TS_FRAME + 2, "???", 102 },
      {60, 135, 50, 50, ILI9341_ORANGE, ILI9341_BLACK, TS_TOGOFF + 2, "yyy", 2 }, {10, 135, 50, 50, ILI9341_CYAN, ILI9341_BLACK, TS_TOGON + 2, "xxx", 52 },
      {115, 25, 50, 105, ILI9341_YELLOW, 0, TS_FRAME + 3, "???", 103 },
      {115, 25, 50, 55, ILI9341_CYAN, ILI9341_BLACK, TS_TOGOFF + 3, "Clr", 3 }, {115, 80, 50, 50, ILI9341_CYAN, ILI9341_NAVY, TS_TOGON + 3, "Hi!", 53 },
      {165, 25, 50, 105, ILI9341_CYAN, ILI9341_PINK, TS_FBUTN, "Dbo", 201 },
      {115, 135, 100, 50, ILI9341_BLACK, ILI9341_DARKCYAN, TS_FBUTN, "BOUNCE", 202 },
      */
    };
    Last edited by rfresh737; 11-19-2015 at 02:23 AM.

  13. #13
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    7,358
    opps - That is a BUGBUG - the frame border is one color FBC and the Frame Fill color - the button text is indeed always hardcoded as WHITE.

    I've been away from buttons too long . . .

    Code:
            tft.setTextColor(ILI9341_WHITE);  // BUGBUG - this to come from struct!
            tft.setTextSize(2);  // BUGBUG - this to come from struct!
            tft.println(buttons[ii].text);
    I should clean that up and the overloaded toggle .... the interrupt coding has been longer than I thought

  14. #14
    Senior Member
    Join Date
    Oct 2015
    Posts
    227
    I'm having difficulty finding the API documentation for the TFT graphics functions such as fillRoundRect(), drawRect(), fillCircle() etc.

    I want to read up on the arguments...what they are, etc.

    Does anyone where I can find the technical docs for these kinds of graphics calls?

    Thanks...

  15. #15
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    7,358
    All I've ever seen is this: "\hardware\teensy\avr\libraries\ILI9341_t3\ILI9341 _t3.cpp" and the associated header file. Then look for 'r' to be radius.

    There may be something more where it came from before being T3 tweaked.

    I thought you could live without rounded buttons?

    <edit> @rfresh737 - I could make a quick change to use FGC on the FRAME and the text - that almost makes sense?
    Last edited by defragster; 11-19-2015 at 07:15 AM.

  16. #16
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    7,358
    Updated onoffbutton1 with text color as FGC and made a rounded button with radius half the height - draws right but changed button behavior in loop()???

    Code:
              tft.fillRoundRect(buttons[ii].tx, buttons[ii].ty, buttons[ii].ww, buttons[ii].hh,buttons[ii].hh/2, buttons[ii].bgc);

  17. #17
    Senior Member
    Join Date
    Oct 2015
    Posts
    227
    >I thought you could live without rounded buttons?

    Yes, I can...square buttons are fine...I'm just trying to learn about the other graphics functions, how they work, etc.

    I'm still trying to figure out what that 5th argument is for in tft.drawRoundRect(x, y, w, h, 5, color) ?

    Thanks for making that change in onoffbutton1 for controlling the text color.

  18. #18
    Good morning rfresh.

    I had the same question the other day for myself. I went back to the documentation that Henning put together for the TFT and TFT Button libraries and found an answer that worked for me. The 5th argument should be the radius desired for the rounded rectangle function. It isn't there for the drawRect function as of course the corner radius is a square.
    Matadormac

  19. #19
    Senior Member
    Join Date
    Oct 2015
    Posts
    227
    BTW is there a color chart somewhere so I can see what colors I have to choose from?

  20. #20
    From the keywords.txt file of the ILI9341_t3 library Paul contributed I found this list and have used it for my buttons. I don't know of a color swatch matching for each but I guess setting it up on your display wouldn't be too difficult.

    ILI9341_BLACK LITERAL1
    ILI9341_NAVY LITERAL1
    ILI9341_DARKGREEN LITERAL1
    ILI9341_DARKCYAN LITERAL1
    ILI9341_MAROON LITERAL1
    ILI9341_PURPLE LITERAL1
    ILI9341_OLIVE LITERAL1
    ILI9341_LIGHTGREY LITERAL1
    ILI9341_DARKGREY LITERAL1
    ILI9341_BLUE LITERAL1
    ILI9341_GREEN LITERAL1
    ILI9341_CYAN LITERAL1
    ILI9341_RED LITERAL1
    ILI9341_MAGENTA LITERAL1
    ILI9341_YELLOW LITERAL1
    ILI9341_WHITE LITERAL1
    ILI9341_ORANGE LITERAL1
    ILI9341_GREENYELLOW LITERAL1
    ILI9341_PINK LITERAL1

  21. #21
    Senior Member
    Join Date
    Oct 2015
    Posts
    227
    Thanks...I think I'll work on making a display showing all of these colors...

  22. #22
    Senior Member
    Join Date
    Oct 2015
    Posts
    227
    OK...here is my sketch.

    This code will paint 19 squares on the TFT LCD screen, with each square displaying a different color.

    Use the index number to associate the actual color name.

    If there are more colors please let me know and I will modify the sketch to show them.

    Code:
    /*******************************************************************
      This sletch displays all the (known to me at this time)
      Colors for the Color 320x240 TFT Display, ILI9341 Controller Chip.
      Screen URL Link: https://www.pjrc.com/store/display_ili9341.html
      Developed using a Teensy 3.2 Board
      Written by Ralph Freshour
      Version 1.0 11/19/2015
    
      Index     Color Name
      1 ILI9341_BLACK
      2 ILI9341_NAVY
      3 ILI9341_DARKGREEN
      4 ILI9341_DARKCYAN
      5 ILI9341_MAROON
    
      6 ILI9341_PURPLE
      7 ILI9341_OLIVE
      8 ILI9341_LIGHTGREY
      9 ILI9341_DARKGREY
      10 ILI9341_BLUE
    
      11 ILI9341_GREEN
      12 ILI9341_CYAN
      13 ILI9341_RED
      14 ILI9341_MAGENTA
      15 ILI9341_YELLOW
    
      16 ILI9341_WHITE
      17 ILI9341_ORANGE
      18 ILI9341_GREENYELLOW
      19 ILI9341_PINK
    *******************************************************************/
    
    #include "SPI.h"
    #include "ILI9341_t3.h"
    
    // For the Adafruit shield, these are the default.
    #define TFT_DC  9
    #define TFT_CS 10
    
    // Use hardware SPI (on Uno, #13, #12, #11) and the above for CS/DC
    ILI9341_t3 tft = ILI9341_t3(TFT_CS, TFT_DC);
    
    int intButtonRadius = 5;  
      
    void setup()
    {
      tft.begin();
      tft.setRotation(3); // normal landscape orientation
      tft.fillScreen(ILI9341_WHITE);
      //Serial.begin(9600);
      // Note: Serial Window prints are working but not really needed so I have remmed them out
      //while (!Serial) ; // wait for Arduino Serial Monitor
      //Serial.println("Color LCD Samples Started!"); 
      paint_Color_Samples();
      //Serial.println("Done!");
    }
    
    void loop(void)
    {
      // nothing to do here really
    }
    
    /**************************************************************************
      This function paints 19 color samples with an index number because there is
      not enough room to paint the color name in most cases.
    ***************************************************************************/
    void paint_Color_Samples()
    {
      int int1Left = 15;
      int int1Top = 5;
      int int2Top = 65;  
      int int3Top = 125;  
      int int4Top = 185;  
      int int1Width = 50;    
      int int1Height = 50;  
      int int1TextLeft = 0;
      int int1TextTop = int1Top + 10;
      int int2TextTop = int2Top + 10;
      int int3TextTop = int3Top + 10;
      int int4TextTop = int4Top + 10;
          
      tft.setRotation(3); // normal landscape orientation
      tft.fillScreen(ILI9341_WHITE);
      tft.setTextSize(2);
    
      // Row 1
      tft.fillRoundRect(int1Left, int1Top, int1Width, int1Height, 0, ILI9341_BLACK);
      tft.setCursor(int1TextLeft+34, int1TextTop+8);
      tft.setTextColor(ILI9341_WHITE);
      tft.println("1");
    
      tft.fillRoundRect(int1Left + 60, int1Top, int1Width, int1Height, 0, ILI9341_NAVY);
      tft.setCursor(int1TextLeft+94, int1TextTop+8);
      tft.setTextColor(ILI9341_WHITE);
      tft.println("2");
    
      tft.fillRoundRect(int1Left + 120, int1Top, int1Width, int1Height, 0, ILI9341_DARKGREEN);
      tft.setCursor(int1TextLeft+154, int1TextTop+8);
      tft.setTextColor(ILI9341_WHITE);
      tft.println("3");
    
      tft.fillRoundRect(int1Left + 180, int1Top, int1Width, int1Height, 0, ILI9341_DARKCYAN);
      tft.setCursor(int1TextLeft+214, int1TextTop+8);
      tft.setTextColor(ILI9341_WHITE);
      tft.println("4");
    
      tft.fillRoundRect(int1Left + 240, int1Top, int1Width, int1Height, 0, ILI9341_MAROON);
      tft.setCursor(int1TextLeft+274, int1TextTop+8);
      tft.setTextColor(ILI9341_WHITE);
      tft.println("5");
    
    
    
      // Row 2
      tft.fillRoundRect(int1Left, int2Top, int1Width, int1Height, 0, ILI9341_PURPLE);
      tft.setCursor(int1TextLeft+34, int2TextTop+8);
      tft.setTextColor(ILI9341_WHITE);
      tft.println("6");
    
      tft.fillRoundRect(int1Left + 60, int2Top, int1Width, int1Height, 0, ILI9341_OLIVE);
      tft.setCursor(int1TextLeft+94, int2TextTop+8);
      tft.setTextColor(ILI9341_WHITE);
      tft.println("7");
    
      tft.fillRoundRect(int1Left + 120, int2Top, int1Width, int1Height, 0, ILI9341_LIGHTGREY);
      tft.setCursor(int1TextLeft+154, int2TextTop+8);
      tft.setTextColor(ILI9341_BLACK);
      tft.println("8");
    
      tft.fillRoundRect(int1Left + 180, int2Top, int1Width, int1Height, 0, ILI9341_DARKGREY);
      tft.setCursor(int1TextLeft+214, int2TextTop+8);
      tft.setTextColor(ILI9341_WHITE);
      tft.println("9");
    
      tft.fillRoundRect(int1Left + 240, int2Top, int1Width, int1Height, 0, ILI9341_BLUE);
      tft.setCursor(int1TextLeft+268, int2TextTop+8);
      tft.setTextColor(ILI9341_WHITE);
      tft.println("10");
    
    
    
      // Row 3
      tft.fillRoundRect(int1Left, int3Top, int1Width, int1Height, 0, ILI9341_GREEN);
      tft.setCursor(int1TextLeft+28, int3TextTop+8);
      tft.setTextColor(ILI9341_BLACK);
      tft.println("11");
    
      tft.fillRoundRect(int1Left + 60, int3Top, int1Width, int1Height, 0, ILI9341_CYAN);
      tft.setCursor(int1TextLeft+88, int3TextTop+8);
      tft.setTextColor(ILI9341_BLACK);
      tft.println("12");
    
      tft.fillRoundRect(int1Left + 120, int3Top, int1Width, int1Height, 0, ILI9341_RED);
      tft.setCursor(int1TextLeft+148, int3TextTop+8);
      tft.setTextColor(ILI9341_WHITE);
      tft.println("13");
    
      tft.fillRoundRect(int1Left + 180, int3Top, int1Width, int1Height, 0, ILI9341_MAGENTA);
      tft.setCursor(int1TextLeft+208, int3TextTop+8);
      tft.setTextColor(ILI9341_BLACK);
      tft.println("14");
    
      tft.fillRoundRect(int1Left + 240, int3Top, int1Width, int1Height, 0, ILI9341_YELLOW);
      tft.setCursor(int1TextLeft+268, int3TextTop+8);
      tft.setTextColor(ILI9341_BLACK);
      tft.println("15");
    
    
    
      // Row 4
      tft.fillRoundRect(int1Left, int4Top, int1Width, int1Height, 0, ILI9341_WHITE);
      tft.setCursor(int1TextLeft+28, int4TextTop+8);
      tft.setTextColor(ILI9341_BLACK);
      tft.println("16");
    
      tft.fillRoundRect(int1Left + 60, int4Top, int1Width, int1Height, 0, ILI9341_ORANGE);
      tft.setCursor(int1TextLeft+88, int4TextTop+8);
      tft.setTextColor(ILI9341_BLACK);
      tft.println("17");
    
      tft.fillRoundRect(int1Left + 120, int4Top, int1Width, int1Height, 0, ILI9341_GREENYELLOW);
      tft.setCursor(int1TextLeft+148, int4TextTop+8);
      tft.setTextColor(ILI9341_BLACK);
      tft.println("18");
    
      tft.fillRoundRect(int1Left + 180, int4Top, int1Width, int1Height, 0, ILI9341_PINK);
      tft.setCursor(int1TextLeft+208, int4TextTop+8);
      tft.setTextColor(ILI9341_BLACK);
      tft.println("19");
    
    }

  23. #23
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    7,358
    Colors are an RGB variant -
    From the source it maps like this 5 bits, 6 bits, 5 bits
    > color565(uint8_t r, uint8_t g, uint8_t b)
    @rfresh - I worked on cleaning my button code - added struct elements - a bit but ran out of time getting the slider detection. If you did your post #22 'programmatically' it would take less space - at the same time you could USB PRINT the formatted structure details to put them into a button structure. I saw why the rounded button I got to draw wasn't active - but that fix is held up in my structure rewrite.
    Last edited by defragster; 11-21-2015 at 06:29 AM. Reason: RGB colors color565()

  24. #24
    Senior Member
    Join Date
    Oct 2015
    Posts
    227
    >If you did your post #22 'programmatically' it would take less space.

    How does one do it that way?

    >you could USB PRINT the formatted structure details to put them into a button structure.

    Right...but I wanted to do it in a very simple manner so other newbies could follow it easier. But I do like your button structure idea. I'll hold off a bit downloading your new button code until you get more time to finish it. Thanks.

  25. #25
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    7,358
    @rfresh - gotta run - new phone waiting on me . . .

    You'd need to put the colors in an array : Numbers work to use them but would be cryptic in the structure - so maybe the text names too for USB output.

    Then have two loops - to replicate what you have - a quick attempt - you need to adjust for setcursor as noted

    Code:
    kk=0; // index for the color array
    for ( ii=int1Left; ii<300; ii+=60 )
      for (jj=int1Top; jj<240; jj+=60)
    {
      tft.fillRoundRect( ii , jj , int1Width, int1Height, 0, ILI9341_BLACK);
      tft.setCursor( ii + ???, jj + ??? );  // EDIT THIS FOR TEXT OFFSET from ii, jj
      tft.setTextColor(array_colors[ kk ]);
      kk++;
      tft.println(kk);
    }

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •