Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 7 of 7

Thread: Teensy 3.1 vs FT2606 Capacitance Touch Driver (2.8" TFT)

  1. #1

    Teensy 3.1 vs FT6206 Capacitance Touch Driver (2.8" TFT)

    Hiya fellow Teensy Fans

    I've been battling with my new Adafruit 2.8" TFT with Capacitance Touch.

    I've got it working perfectly with the optimised ILI9341 T3 Library which takes full advantage of the Teensy's super fast SPI. Stunning speed difference so thanks so much for the work put in to that guys! (all my projects rely on non-blocking / max speed for animations etc so essential for me!)

    However...

    Really can't seem to get the capacitance touch screen side of it working. And what's more, there doesnt seem to be anything at all about this combination of teensy and FT6206working together. I've scoured the net (including YouTube), so here I am, asking for help

    Anyone know why the Teensy won't play ball with it? I've got the shield version of this display so I've tested it on my UNO with seamless (but slow) success so the touch & display are all working as normal with the UNO..

    Here is the default touch test sketch running on the UNO with some love
    Click image for larger version. 

Name:	photo 3.jpg 
Views:	534 
Size:	181.3 KB 
ID:	3165

    And this is showing the screen running on the Teensy (I made up a custom UNO proto-shield matching the UNO pins).
    Click image for larger version. 

Name:	photo 4.jpg 
Views:	1967 
Size:	206.1 KB 
ID:	3166

    Obviously I'm running my own test sketch on the Teensy above just to get the library etc working for the display side of things (which is running great).. Just touch not happy, but here's the standard touch sketch you get for the capacitance version: (Please note, i'm using the optimised display drivers and sdFat libraries, but this sketch should run, but just can't get past the touch initiation part).

    Code:
    /***************************************************
      This is our touchscreen painting example for the Adafruit ILI9341
      captouch shield
      ----> http://www.adafruit.com/products/1947
    
      Check out the links above for our tutorials and wiring diagrams
    
      Adafruit invests time and resources providing this open source code,
      please support Adafruit and open-source hardware by purchasing
      products from Adafruit!
    
      Written by Limor Fried/Ladyada for Adafruit Industries.
      MIT license, all text above must be included in any redistribution
     ****************************************************/
    
    
    #include <Adafruit_GFX.h>    // Core graphics library
    #include <SPI.h>       // this is needed for display
    #include <SdFat.h>
    #include <ILI9341_t3.h> // Hardware-specific library
    #include <Wire.h>      // this is needed for FT6206
    #include <Adafruit_FT6206.h>
    
    // The FT6206 uses hardware I2C (SCL/SDA)
    Adafruit_FT6206 ctp = Adafruit_FT6206();
    
    // TFT display and SD card will share the hardware SPI interface.
    // Hardware SPI pins are specific to the Arduino board type and
    // cannot be remapped to alternate pins.  For Arduino Uno,
    // Duemilanove, etc., pin 11 = MOSI, pin 12 = MISO, pin 13 = SCK.
    
    #define TFT_DC  9
    #define TFT_CS 10
    ILI9341_t3 tft = ILI9341_t3(TFT_CS, TFT_DC);
    
    #define SD_CS 4
    const uint8_t spiSpeed = SPI_HALF_SPEED;
    // Serial streams
    
    
    Sd2Card card;
    SdVolume volume;
    SdFile root;
    
    // Size of the color selection boxes and the paintbrush size
    #define BOXSIZE 40
    #define PENRADIUS 3
    int oldcolor, currentcolor;
    
    void setup(void) {
      delay(2000);
      Serial.begin(115200);
    
      tft.begin();
      tft.fillScreen(ILI9341_BLACK);
      
      delay(1000);
      Serial.print("Initializing SD card...");
      if (!card.init(spiSpeed, SD_CS)) {
        Serial.println("failed!");
      }
      Serial.println("OK!");
    
      Serial.print("Initializing Volume...");
      if (!volume.init(&card)) {
        if (card.errorCode()) {
          Serial.println("Can't read the card.");
        } else {
          Serial.println("Can't find a valid FAT16/FAT32 partition.");
        }
      }
      Serial.println("OK!");
    
      Serial.print("Open Root...");
      if (!root.openRoot(&volume)) {
        Serial.println("Can't open root directory.");
      }
      Serial.println("OK!");
      tft.setRotation(3);
      
      bmpDraw("andology.bmp", 0, 0); 
      delay(2000);
      tft.fillScreen(ILI9341_BLACK);
      
      
    
      if (! ctp.begin(40)) {  // pass in 'sensitivity' coefficient
        Serial.println("Couldn't start FT6206 touchscreen controller");
        while (1);
      }
    
      Serial.println("Capacitive touchscreen started");
      
      tft.fillScreen(ILI9341_BLACK);
      
      // make the color selection boxes
      tft.fillRect(0, 0, BOXSIZE, BOXSIZE, ILI9341_RED);
      tft.fillRect(BOXSIZE, 0, BOXSIZE, BOXSIZE, ILI9341_YELLOW);
      tft.fillRect(BOXSIZE*2, 0, BOXSIZE, BOXSIZE, ILI9341_GREEN);
      tft.fillRect(BOXSIZE*3, 0, BOXSIZE, BOXSIZE, ILI9341_CYAN);
      tft.fillRect(BOXSIZE*4, 0, BOXSIZE, BOXSIZE, ILI9341_BLUE);
      tft.fillRect(BOXSIZE*5, 0, BOXSIZE, BOXSIZE, ILI9341_MAGENTA);
     
      // select the current color 'red'
      tft.drawRect(0, 0, BOXSIZE, BOXSIZE, ILI9341_WHITE);
      currentcolor = ILI9341_RED;
    }
    
    void loop() {
      // Wait for a touch
      if (! ctp.touched()) {
        return;
      }
    
      // Retrieve a point  
      TS_Point p = ctp.getPoint();
      
     /*
      // Print out raw data from screen touch controller
      Serial.print("X = "); Serial.print(p.x);
      Serial.print("\tY = "); Serial.print(p.y);
      Serial.print(" -> ");
     */
    
      // flip it around to match the screen.
      p.x = map(p.x, 0, 240, 240, 0);
      p.y = map(p.y, 0, 320, 320, 0);
    
      // Print out the remapped (rotated) coordinates
      Serial.print("("); Serial.print(p.x);
      Serial.print(", "); Serial.print(p.y);
      Serial.println(")");
      
    
      if (p.y < BOXSIZE) {
         oldcolor = currentcolor;
    
         if (p.x < BOXSIZE) { 
           currentcolor = ILI9341_RED; 
           tft.drawRect(0, 0, BOXSIZE, BOXSIZE, ILI9341_WHITE);
         } else if (p.x < BOXSIZE*2) {
           currentcolor = ILI9341_YELLOW;
           tft.drawRect(BOXSIZE, 0, BOXSIZE, BOXSIZE, ILI9341_WHITE);
         } else if (p.x < BOXSIZE*3) {
           currentcolor = ILI9341_GREEN;
           tft.drawRect(BOXSIZE*2, 0, BOXSIZE, BOXSIZE, ILI9341_WHITE);
         } else if (p.x < BOXSIZE*4) {
           currentcolor = ILI9341_CYAN;
           tft.drawRect(BOXSIZE*3, 0, BOXSIZE, BOXSIZE, ILI9341_WHITE);
         } else if (p.x < BOXSIZE*5) {
           currentcolor = ILI9341_BLUE;
           tft.drawRect(BOXSIZE*4, 0, BOXSIZE, BOXSIZE, ILI9341_WHITE);
         } else if (p.x <= BOXSIZE*6) {
           currentcolor = ILI9341_MAGENTA;
           tft.drawRect(BOXSIZE*5, 0, BOXSIZE, BOXSIZE, ILI9341_WHITE);
         }
    
         if (oldcolor != currentcolor) {
            if (oldcolor == ILI9341_RED) 
              tft.fillRect(0, 0, BOXSIZE, BOXSIZE, ILI9341_RED);
            if (oldcolor == ILI9341_YELLOW) 
              tft.fillRect(BOXSIZE, 0, BOXSIZE, BOXSIZE, ILI9341_YELLOW);
            if (oldcolor == ILI9341_GREEN) 
              tft.fillRect(BOXSIZE*2, 0, BOXSIZE, BOXSIZE, ILI9341_GREEN);
            if (oldcolor == ILI9341_CYAN) 
              tft.fillRect(BOXSIZE*3, 0, BOXSIZE, BOXSIZE, ILI9341_CYAN);
            if (oldcolor == ILI9341_BLUE) 
              tft.fillRect(BOXSIZE*4, 0, BOXSIZE, BOXSIZE, ILI9341_BLUE);
            if (oldcolor == ILI9341_MAGENTA) 
              tft.fillRect(BOXSIZE*5, 0, BOXSIZE, BOXSIZE, ILI9341_MAGENTA);
         }
      }
      if (((p.y-PENRADIUS) > BOXSIZE) && ((p.y+PENRADIUS) < tft.height())) {
        tft.fillCircle(p.x, p.y, PENRADIUS, currentcolor);
      }
    }
    
    // This function opens a Windows Bitmap (BMP) file and
    // displays it at the given coordinates.  It's sped up
    // by reading many pixels worth of data at a time
    // (rather than pixel by pixel).  Increasing the buffer
    // size takes more of the Arduino's precious RAM but
    // makes loading a little faster.  20 pixels seems a
    // good balance.
    
    #define BUFFPIXEL 80
    
    void bmpDraw(char *filename, uint8_t x, uint16_t y) {
    
      SdFile   bmpFile;
      int      bmpWidth, bmpHeight;   // W+H in pixels
      uint8_t  bmpDepth;              // Bit depth (currently must be 24)
      uint32_t bmpImageoffset;        // Start of image data in file
      uint32_t rowSize;               // Not always = bmpWidth; may have padding
      uint8_t  sdbuffer[3*BUFFPIXEL]; // pixel buffer (R+G+B per pixel)
      uint8_t  buffidx = sizeof(sdbuffer); // Current position in sdbuffer
      boolean  goodBmp = false;       // Set to true on valid header parse
      boolean  flip    = true;        // BMP is stored bottom-to-top
      int      w, h, row, col;
      uint8_t  r, g, b;
      uint32_t pos = 0, startTime = millis();
      FatPos_t fatpos;
      if((x >= tft.width()) || (y >= tft.height())) return;
    
      Serial.println();
      Serial.print(F("Loading image '"));
      Serial.print(filename);
      Serial.println('\'');
    
      // Open requested file on SD card
      if (!bmpFile.open(&root, filename, O_READ)) {
        Serial.print(F("File not found"));
        return;
      }
    
      // Parse BMP header
      if(read16(bmpFile) == 0x4D42) { // BMP signature
        Serial.print(F("File size: ")); Serial.println(read32(bmpFile));
        (void)read32(bmpFile); // Read & ignore creator bytes
        bmpImageoffset = read32(bmpFile); // Start of image data
        Serial.print(F("Image Offset: ")); Serial.println(bmpImageoffset, DEC);
        // Read DIB header
        Serial.print(F("Header size: ")); Serial.println(read32(bmpFile));
        bmpWidth  = read32(bmpFile);
        bmpHeight = read32(bmpFile);
        if(read16(bmpFile) == 1) { // # planes -- must be '1'
          bmpDepth = read16(bmpFile); // bits per pixel
          Serial.print(F("Bit Depth: ")); Serial.println(bmpDepth);
          if((bmpDepth == 24) && (read32(bmpFile) == 0)) { // 0 = uncompressed
    
            goodBmp = true; // Supported BMP format -- proceed!
            Serial.print(F("Image size: "));
            Serial.print(bmpWidth);
            Serial.print('x');
            Serial.println(bmpHeight);
    
            // BMP rows are padded (if needed) to 4-byte boundary
            rowSize = (bmpWidth * 3 + 3) & ~3;
    
            // If bmpHeight is negative, image is in top-down order.
            // This is not canon but has been observed in the wild.
            if(bmpHeight < 0) {
              bmpHeight = -bmpHeight;
              flip      = false;
            }
    
            // Crop area to be loaded
            w = bmpWidth;
            h = bmpHeight;
            if((x+w-1) >= tft.width())  w = tft.width()  - x;
            if((y+h-1) >= tft.height()) h = tft.height() - y;
    
            // Set TFT address window to clipped image bounds
            tft.setAddrWindow(x, y, x+w-1, y+h-1);
    
            for (row=0; row<h; row++) { // For each scanline...
    
              // Seek to start of scan line.  It might seem labor-
              // intensive to be doing this on every line, but this
              // method covers a lot of gritty details like cropping
              // and scanline padding.  Also, the seek only takes
              // place if the file position actually needs to change
              // (avoids a lot of cluster math in SD library).
              if(flip) // Bitmap is stored bottom-to-top order (normal BMP)
                pos = bmpImageoffset + (bmpHeight - 1 - row) * rowSize;
              else     // Bitmap is stored top-to-bottom
                pos = bmpImageoffset + row * rowSize;
              bmpFile.getpos(&fatpos);   // Need seek?
              if(fatpos.position != pos) { // Need seek?
                bmpFile.seekSet(pos);
                buffidx = sizeof(sdbuffer); // Force buffer reload
              }
    
              for (col=0; col<w; col++) { // For each pixel...
                // Time to read more pixel data?
                if (buffidx >= sizeof(sdbuffer)) { // Indeed
                  bmpFile.read(sdbuffer, sizeof(sdbuffer));
                  buffidx = 0; // Set index to beginning
                }
    
                // Convert pixel from BMP to TFT format, push to display
                b = sdbuffer[buffidx++];
                g = sdbuffer[buffidx++];
                r = sdbuffer[buffidx++];
                tft.pushColor(tft.color565(r,g,b));
              } // end pixel
            } // end scanline
            Serial.print(F("Loaded in "));
            Serial.print(millis() - startTime);
            Serial.println(" ms");
          } // end goodBmp
        }
      }
    
      bmpFile.close();
      if(!goodBmp) Serial.println(F("BMP format not recognized."));
    }
    
    // These read 16- and 32-bit types from the SD card file.
    // BMP data is stored little-endian, Arduino is little-endian too.
    // May need to reverse subscript order if porting elsewhere.
    
    uint16_t read16(SdFile &f) {
      uint16_t result;
      ((uint8_t *)&result)[0] = f.read(); // LSB
      ((uint8_t *)&result)[1] = f.read(); // MSB
      return result;
    }
    
    uint32_t read32(SdFile &f) {
      uint32_t result;
      ((uint8_t *)&result)[0] = f.read(); // LSB
      ((uint8_t *)&result)[1] = f.read();
      ((uint8_t *)&result)[2] = f.read();
      ((uint8_t *)&result)[3] = f.read(); // MSB
      return result;
    }
    When I run it, I get this back through the Serial:

    Code:
    Initializing SD card...OK!
    Initializing Volume...OK!
    Open Root...OK!
    
    Loading image 'andology.bmp'
    File size: 230454
    Image Offset: 54
    Header size: 40
    Bit Depth: 24
    Image size: 320x240
    Loaded in 623 ms
    Couldn't start FT6206 touchscreen controller
    I'm just using standard pinouts and example straight outta the library so we'll assume everything is as it should be in terms of pinouts / connections and the like..

    Also, note the use of the SdFat.h library. Took me ages to get that working, standard adafruit load bitmap also doesnt seem to work but after much experimentation, that library seems to work best for dealing with bitmaps on the teensy etc..

    Most probably an i2C issue with this touch screen but not sure where to start. Thanks for any guidance or fixes or hints

    Cheers

    Andy
    Last edited by Andology; 12-22-2014 at 04:05 AM.

  2. #2
    Member
    Join Date
    Jul 2013
    Location
    Colorado
    Posts
    86
    I got the Breakout Board version of the same capacitive touch screen and did manage to get it to work, however I was struggling a bit with it for a while. I am running a T3.1 with PJRC Audio board. After a little copy paste from various examples I was able to get the system running with the touch screen and graphics and sound. See the example below. I have only tried to access the SD card on the Audio board. It's definitely convenient to have a touch screen, now I need to get it all working smoothly.

    To get touch working I used A5 (D19) for SCL and A4 (D18) for SDA, the display is connected with alternate pins for Audio / graphics devices per the webpage here:

    http://www.pjrc.com/store/display_ili9341.html

    Code:
    /***************************************************
     This is a modified example to test the Teensy 3.1 with audioshield and the 
     2.8" TFT capactive touchscreen 
     https://www.adafruit.com/product/2090
     
     Still much to do however this demo will play a wav file and allows
     touch updates during song play (interrupts playback however)
     - Fretless_Kb
     
     
     // Original Text
      This is our GFX example for the Adafruit ILI9341 Breakout and Shield
      ----> http://www.adafruit.com/products/1651
    
      Check out the links above for our tutorials and wiring diagrams
      These displays use SPI to communicate, 4 or 5 pins are required to
      interface (RST is optional)
      Adafruit invests time and resources providing this open source code,
      please support Adafruit and open-source hardware by purchasing
      products from Adafruit!
    
      Written by Limor Fried/Ladyada for Adafruit Industries.
      MIT license, all text above must be included in any redistribution
     ****************************************************/
    
    #include <Audio.h>
    #include <Wire.h>
    #include <SD.h>
    #include "SPI.h"
    #include "ILI9341_t3.h"
    #include <Adafruit_FT6206.h>
    
    
    // The FT6206 uses hardware I2C (SCL/SDA)
    Adafruit_FT6206 ctp = Adafruit_FT6206();
    
    
    // For the Adafruit shield, these are the default.
    #define TFT_DC  20 // 9 basic  20 alt for soundcard
    #define TFT_CS 21 // 10 basic  21 alt for soundcard
    
    // Use hardware SPI (on Uno, #13, #12, #11) and the above for CS/DC
    ILI9341_t3 tft = ILI9341_t3(TFT_CS, TFT_DC);
    
    // GUItool: begin automatically generated code
    AudioPlaySdWav           playWav1;       //xy=154,78
    AudioOutputI2S           i2s1;           //xy=334,89
    AudioConnection          patchCord1(playWav1, 0, i2s1, 0);
    AudioConnection          patchCord2(playWav1, 1, i2s1, 1);
    AudioControlSGTL5000     sgtl5000_1;     //xy=240,153
    // GUItool: end automatically generated code
    
    
    void setup() 
    {
      SPI.setMOSI(7);
      SPI.setSCK(14);
    
      Serial.begin(115200);
      //while (!Serial) ; // wait for Arduino Serial Monitor
    
      tft.begin();
      tft.fillScreen(ILI9341_BLACK);
      tft.setTextColor(ILI9341_GREEN);
      tft.setTextSize(3);
    
      if (! ctp.begin(40)) 
      {  // pass in 'sensitivity' coefficient
        Serial.println("Couldn't start FT6206 touchscreen controller");
        tft.println("Couldn't start FT6206 touchscreen controller");
        while (1);
      }
      
      tft.println("Touch Screen to Begin ...");
      while ( !ctp.touched() ) 
      {
        delay(10);
      } 
      
      if (!(SD.begin(10))) 
      {
        // stop here, but print a message repetitively
        tft.fillScreen(ILI9341_BLACK);
        tft.setTextColor(ILI9341_RED);
        tft.setTextSize(2);
      
        while (1) 
        {
          tft.println("Unable to access the SD card");
          delay(500);
        }
      }
      tft.fillScreen(ILI9341_BLACK);
      tft.setTextColor(ILI9341_GREEN);
      tft.setTextSize(2);
    
      AudioMemory(5);
      sgtl5000_1.enable();
      sgtl5000_1.volume(0.5);
    }
    
    void touchView () 
    {
      if ( ctp.touched()) 
      {
        // Retrieve a point  
        TS_Point p = ctp.getPoint();      
        // flip it around to match the screen.
        p.x = map(p.x, 0, 240, 240, 0);
        p.y = map(p.y, 0, 320, 320, 0);
        tft.fillScreen(ILI9341_BLACK);
        if(p.x<50) p.x = 50;
        if(p.x>180) p.x=180;
        if(p.y>300) p.y=300;
        
        tft.setTextSize(2);
        tft.setTextColor(ILI9341_RED);
        tft.setCursor(180-p.x,300-p.y);
        tft.print("("); tft.print(p.x);
        tft.print(", "); tft.print(p.y);
        tft.println(")");
      }
    }
    
    int stepTime = 0;
    
    void playFile(const char *filename) {
      tft.print("Playing file: ");
      tft.println(filename);
    
      // Start playing the file.  This sketch continues to
      // run while the file plays.
      playWav1.play(filename);
    
      // A brief delay for the library read WAV info
      delay(5);
    
      // Simply wait for the file to finish playing.
      while (playWav1.isPlaying()) 
      {
        touchView ();
        // uncomment these lines if you audio shield
        // has the optional volume pot soldered
        float vol = analogRead(15);
        vol = vol / 1024;
        sgtl5000_1.volume(vol);
      }
    }
    
    
    void loop(void) {
      // Wait for a touch
      playFile("SDTEST4.WAV");
      delay(25);
    
    }
    I was always double / triple checking my connections. often would have 1 wire out of place as I re-configured and tested with the various graphics displays I have.

    I am interested to know if you got yours to work.

  3. #3
    Hiya, thanks for your reply, and sorry for the delay in mine, holidays / illness and a little failing confidence in these support forums as I never seem to get replies or help for some reason no matter how specific I try to be (poor me)

    Anyway, yeah, I can get the screen working, that's no probs, with all the Spi hardware mods etc associated with the _t3 library..

    But touch screen, still nothing on the teensy.. So it's specifically a teensy issue since uno / nano etc no probs..

    I'm wondering if you ever got yours working with the sd card onboard tft loading bit maps? Coz that's where you'll perhaps see the issue..

    I need to be able to use the sdfat library as I am now successfully to load bitmaps (the original adafruit library does not work on the teensy) and I also need to use the capacitance touch.. It seems since the sdfat uses i2c along with the touch, this is where things won't play together..

    Unless I'm missing something..

    Either gonna lose the screen, or lose the teensy. Since they won't play, and no one else seems to be able to get them working together either...

    Very disappointing..

    Thanks anyway for your help

    Cheers

    Andy

  4. #4
    Senior Member HWGuy's Avatar
    Join Date
    Nov 2012
    Posts
    262
    Where did you connect the SCL/SDA wires on the shield? A4/A5 or to the SCL/SDA pins. For A4 and A5 you have to close the two solder jumper.

  5. #5
    ... Wow... That was easy

    Something about the adafruit support pages did / but didn't make that clear at all since I was sure the default config was A4/A5 off the shield... (None of my uno boards have those 2 pins up the top even labeled as SCL/SDA, so didn't even realise they were used!) learn something new every day, if not, it's been a wasted day!

    Well pointed out, and despite having tried other pins in my frustration was chasing my tail with the jumper closed / up closed anyway... Yay. Thank you dude..

    I've only briefly tested and looks like the touch isn't actually drawing where I'm touching but looks like it's just cords flipped 90 degrees so that's fine, as long as it can actually "see" the touch data, I can play!

    Happy new year to all, and happy teensy'ing!

    Cheers

    Andy

  6. #6
    Hi Andy
    Please note;
    The LCD has a 2.8" 4-wire resistive touch screen glued onto it. You can use this for detecting finger-presses, stylus', etc. Normally, you'll need 4 pins to talk to the touch panel but we decided to go all snazzy and put a dedicated touch screen driver onto the shield. The driver shares the SPI pins with the TFT and SD card, so only one extra pin is needed (digital #8) This allows you to query the controller when you're ready to read touchscreen data, and saves 3 pins...
    Read and test ; https://learn.adafruit.com/adafruit-...een-paint-demo
    Good luck !
    Mike

  7. #7
    Junior Member
    Join Date
    May 2013
    Posts
    18
    Hi
    if possible, please tell me the name of this Font, from your post, please see the pictureName:  photo 4.jpg
Views: 42
Size:  1.9 KB

Posting Permissions

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