element14 Community
element14 Community
    Register Log In
  • Site
  • Search
  • Log In Register
  • Community Hub
    Community Hub
    • What's New on element14
    • Feedback and Support
    • Benefits of Membership
    • Personal Blogs
    • Members Area
    • Achievement Levels
  • Learn
    Learn
    • Ask an Expert
    • eBooks
    • element14 presents
    • Learning Center
    • Tech Spotlight
    • STEM Academy
    • Webinars, Training and Events
    • Learning Groups
  • Technologies
    Technologies
    • 3D Printing
    • FPGA
    • Industrial Automation
    • Internet of Things
    • Power & Energy
    • Sensors
    • Technology Groups
  • Challenges & Projects
    Challenges & Projects
    • Design Challenges
    • element14 presents Projects
    • Project14
    • Arduino Projects
    • Raspberry Pi Projects
    • Project Groups
  • Products
    Products
    • Arduino
    • Avnet Boards Community
    • Dev Tools
    • Manufacturers
    • Multicomp Pro
    • Product Groups
    • Raspberry Pi
    • RoadTests & Reviews
  • About Us
  • Store
    Store
    • Visit Your Store
    • Choose another store...
      • Europe
      •  Austria (German)
      •  Belgium (Dutch, French)
      •  Bulgaria (Bulgarian)
      •  Czech Republic (Czech)
      •  Denmark (Danish)
      •  Estonia (Estonian)
      •  Finland (Finnish)
      •  France (French)
      •  Germany (German)
      •  Hungary (Hungarian)
      •  Ireland
      •  Israel
      •  Italy (Italian)
      •  Latvia (Latvian)
      •  
      •  Lithuania (Lithuanian)
      •  Netherlands (Dutch)
      •  Norway (Norwegian)
      •  Poland (Polish)
      •  Portugal (Portuguese)
      •  Romania (Romanian)
      •  Russia (Russian)
      •  Slovakia (Slovak)
      •  Slovenia (Slovenian)
      •  Spain (Spanish)
      •  Sweden (Swedish)
      •  Switzerland(German, French)
      •  Turkey (Turkish)
      •  United Kingdom
      • Asia Pacific
      •  Australia
      •  China
      •  Hong Kong
      •  India
      •  Korea (Korean)
      •  Malaysia
      •  New Zealand
      •  Philippines
      •  Singapore
      •  Taiwan
      •  Thailand (Thai)
      • Americas
      •  Brazil (Portuguese)
      •  Canada
      •  Mexico (Spanish)
      •  United States
      Can't find the country/region you're looking for? Visit our export site or find a local distributor.
  • Translate
  • Profile
  • Settings
Design for a Cause - Design Challenge
  • Challenges & Projects
  • Design Challenges
  • Design for a Cause - Design Challenge
  • More
  • Cancel
Design for a Cause - Design Challenge
Blog 5" TFT Display and Module RA8875
  • Blog
  • Forum
  • Documents
  • Polls
  • Files
  • Events
  • Mentions
  • Sub-Groups
  • Tags
  • More
  • Cancel
  • New
  • Share
  • More
  • Cancel
Group Actions
  • Group RSS
  • More
  • Cancel
Engagement
  • Author Author: roborob1266
  • Date Created: 24 Jul 2018 1:58 PM Date Created
  • Views 4755 views
  • Likes 7 likes
  • Comments 12 comments
  • ra8875
  • tft screen
  • wiring
  • design for a cause - design challenge
  • uno
  • arduino coding
  • mkr2uno
  • mkr1000
Related
Recommended

5" TFT Display and Module RA8875

roborob1266
roborob1266
24 Jul 2018

I received the Adafruit 5.0" 40-pin TFT Display 800x480 with Touchscreen PRODUCT ID: 1596 and the RA8875 Driver Board for 40-pin TFT Touch Displays 800 x 480 Max PRODUCT ID: 1590.

I had a hard time getting the display to work with the MKR1000 device so I checked the Adafruit website but no luck on the wiring diagrams or instructions.

I tried the Arduino website and no one had any information on how to wire it up. I tried Google and YouTube for any wiring videos.

I connected my Uno to the RA8875 module and put the jumper wires to the ports listed in the Arduino ino file for the ts_calibration and the TFT display lit up and I was able to get the touch readings!

So with doing that, I tried the MKR2UNO module and wired it as I did with my Uno and it didn't work.

Not be defeated, I looked at the MKR2UNO schematics and compared Pin to Pin with how I had it connected to the Uno and tried some different pins, modified the ino code for the ts_calibration under the Adafruit RA8875 library that I added to Arduino and it worked!

Here are the RA8875 pins and the MKR1000 pins that need to be used for the calibration.

RA8875/ MKR1000

VIN/ PIN 14 = +5

GND/ PIN 11 = GND

SCK/ PIN 09 = SCK

MISO/ PIN 10 = MISO

MOSI/ PIN 08 = MOSI

CS/ PIN 06 = Defined as CS in code

RST/ PIN 02 = Defined as RST

INT/ PIN 03 = Defined as INT

 

I modified the code to look like these pins:

 

#include <SPI.h>

#include "Adafruit_GFX.h"

#include "Adafruit_RA8875.h"

 

 

#define RA8875_INT     3

#define RA8875_CS      6

#define RA8875_RESET   2

 

and finally, I changed the code to reflect the 800x400 rather than the 480x272 display:

 

void setup()

{

  Serial.begin(9600);

  Serial.println("Hello, RA8875!");

 

 

  /* Initialise the display using 'RA8875_480x272' or 'RA8875_800x480' */

    if (!tft.begin(RA8875_800x480))

  {

    Serial.println("RA8875 not found ... check your wires!");

    while (1);

  }

image

  • Sign in to reply

Top Comments

  • roborob1266
    roborob1266 over 7 years ago in reply to genebren +2
    Thank you Gene! The hardship was well worth it since it is working now! Never give up, never surrender!
  • Andrew J
    Andrew J over 5 years ago in reply to roborob1266 +2
    I'm not taking account, per-se, of touch down, move release. When I ask for status (line 05), the response will be -1 if no touch detected, or another value that equates to TOUCH_PRESSED, TOUCH_MOVED,…
  • genebren
    genebren over 7 years ago +1
    Nice update on your design challenge project. Good work on getting everything connected and running. That was some first class detective work there. Gene
Parents
  • genebren
    genebren over 7 years ago

    Nice update on your design challenge project.  Good work on getting everything connected and running.  That was some first class detective work there.

    Gene

    • Cancel
    • Vote Up +1 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • roborob1266
    roborob1266 over 5 years ago in reply to genebren

    Hi Gene, Are you familiar with Arduino code? I am having an issue with this project (I picked it back up again using an Arduino Mega 2560 connected to an RA8875 (with 5 inch touch screen) and also the VS1053 audio player with SD slot).

    When I touch the screen, the VS1053 plays the audio file twice as if I pressed it twice.

    I think the touch screen connected to the RA8875 is registering when I press the screen and also when I let my finger up.

    I don't know how to stop that from happening. From what I am reading on the web, I think it could be a possible debounce issue but I am not sure nor am I familiar enough with Arduino code.

    I checked many places on the web to see how I can get this to work but I do not understand software debounce in regards to my specific code.

    Any assistance is appreciated. 

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • Andrew J
    Andrew J over 5 years ago in reply to roborob1266

    Hi Rob,

     

    does it have a library you use to detect touches, positions etc?  I have a similar situation with a different touch screen.  The library I use (Picaso processor) will event a touchdown and a touch up.  So you could, for example, change a graphic on touch down and action the command on touch up: in my code on touchdown I register what was pressed, and on touch up I check it’s the same widget before executing the action.  That way, if someone presses down on a widget, slides their finger off it and then releases, I can tell and not action the command (in other words, the user can ‘abort’ their action.) 

     

    What I found is that it could register multiple touches at the touch point because of the speed of execution of code.  So, as an example, when I pressed the ‘cancel’ button to close a dialog, the code would close that dialog but my finger was still touching the screen (because nano-second execution speed) and it would then event a touch on the widget that was on the screen at that point.  Hope that makes sense....

     

    Anyway, it wasn’t debouncing as such - like a mechanical button - but just you can’t physically move fast enough.  I put a very small delay in to ignore touches once one was detected - I’m not in front of the code, but I played around with the timing to get it right and 500mS worked ok believe it or not.  Also, as I noted above, I wrote the code to only action on the touch up (release) that way multiple touch down events on a widget wouldn’t cause anything to happen.  If you find that it is registered multiple touch up events on the same widget you could put a check in for that.

     

    It won’t be the same library of course, but I’ll try and post the code I use here later.  It may give you some ideas.

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • Andrew J
    Andrew J over 5 years ago in reply to Andrew J

    Here's some code I use.  This function, handleTouches(), is called from within loop() but it could be called from wherever needed.  Above, I said I put a delay in - and I did at one point - but I was able to take it out because that actually wasn't the problem I was experiencing (I remember now.)  Because it is called from loop() it may be called hundreds if not thousands of times a second, so the TOUCH events may be checked multiple times but it doesn't matter because I only process on TOUCH RELEASE.

     

    void handleTouches() {
      uint8_t status;
      int8_t imagePressed;
    
      status = Display.touch_Get(TOUCH_STATUS); // get touchscreen status
    
      if(status == TOUCH_PRESSED) {
        imagePressed = Display.img_Touched(hndl, -1);
        if (imagePressed != -1) {
          lastImagePressed = imagePressed;
        }
      }
    
      if(status == TOUCH_RELEASED) {
        imagePressed = Display.img_Touched(hndl, -1);
        if (imagePressed == lastImagePressed) {
          lastImagePressed = 255;
          switch(imagePressed) {
            case POWERBUTTON:
              handlePowerButton();
              break;
            case PREFSBUTTON:
              handlePrefsButton();
              break;
            case DEFAULTSBUTTON:
              handleDefaultsButton();
              break;
            case CANCELBUTTON:
              handleCancelButton();
              break;
    ….[other case checks]
            default:
              break;
          }
        }
      }
    }

     

    This is based on using a library created for the Picaso graphics processor.  I'd have to assume you have access to a similar library although it's likely to work differently.  The principles for processing should be similar though.

     

    Line 05: here, I get hold of the touch status, which can be -1 (no touch) or TOUCH_PRESSED, TOUCH_RELEASED, TOUCH_MOVED.  These are pretty self-explanatory; touch_moved is a detection of touch_pressed and a move of the pointer without an intervening touch_released event.  I'm not interested in this event so I don't process it.

     

    Line 07: if TOUCH_PRESSED status was indicated, then I can ask for which image (widget - button, string, image etc) was touched and remember it.  Note that a touch could be detected not on a widget.  If your library only returns a position (X,Y coordinates) you would need to calculate what was being touched - the library I use does that for me.

     

    Line 14: If TOUCH_RELEASED status was indicated, then I check that the touch occurred on the same widget and only process it if that was the case.  In other words, the user has to touch down and release on the same widget (see the check on line 16.)  You can see this in most UIs: press and release must occur on the same widget and if you change your mind, you can drag off before releasing.  Keyboards, at least physical ones, work differently in that the button registers on touch down rather than touch release. 

     

    ImagePressed is just a 0 (zero) to N index of widgets on the screen which is why I can process them through a Switch construct. 

     

    If I had to summarise:

    • Only process on a TOUCH PRESS or a TOUCH RELEASE.
    • If the library only reports a co-ordinate, you will need a routine to convert that co-ordinate to a widget.  The widget will cover an area so you would be looking at detecting the co-ordinate in an X,X1, Y,Y1 range.  Looking at the touch calibration example for this driver in Adafruit's GitHub, it looks like it is co-ordinate based.
    • When you detect a TOUCH PRESS, save the 'widget' pressed and ignore any more TOUCH PRESS events until you get a TOUCH RELEASE.
    • Ensure that the TOUCH RELEASE occurs on the same widget as the TOUCH PRESS you registered.
    • If the library doesn't flag anything except a touch point, your approach would be to do something like:
      • Detect a touch point
      • Save initial coordinates and convert to 'screen widget touched'
      • while (touch detected), save last coordinates and convert to screen widget touched // this loops until no touch detected
      • Does initial screen widget touched == last screen widget touched?  If yes, process the touch, otherwise, the touch point was moved so do nothing. [REMEMBER: that the widget covers an area so it isn't a SPECIFIC point you want to compare but a determined widget] 

    Hope this gives you some pointers.

    • Cancel
    • Vote Up +1 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • roborob1266
    roborob1266 over 5 years ago in reply to Andrew J

    Hi Andrew,

    The RA8875 library does have a program that detects touches as a calibration test. Here it is:

     

    #include <SPI.h>

    #include "Adafruit_GFX.h"

    #include "Adafruit_RA8875.h"

     

     

    #define RA8875_INT     3

    #define RA8875_CS      10

    #define RA8875_RESET   9

     

     

    Adafruit_RA8875 tft = Adafruit_RA8875(RA8875_CS, RA8875_RESET);

    tsPoint_t       _tsLCDPoints[3];

    tsPoint_t       _tsTSPoints[3];

    tsMatrix_t      _tsMatrix;

     

     

    /**************************************************************************/

    /*!

        @brief Calculates the difference between the touch screen and the

               actual screen co-ordinates, taking into account misalignment

               and any physical offset of the touch screen.

     

     

        @note  This is based on the public domain touch screen calibration code

               written by Carlos E. Vidales (copyright (c) 2001).

     

     

               For more information, see the following app notes:

     

     

               - AN2173 - Touch Screen Control and Calibration

                 Svyatoslav Paliy, Cypress Microsystems

               - Calibration in touch-screen systems

                 Wendy Fang and Tony Chang,

                 Analog Applications Journal, 3Q 2007 (Texas Instruments)

    */

    /**************************************************************************/

    int setCalibrationMatrix( tsPoint_t * displayPtr, tsPoint_t * screenPtr, tsMatrix_t * matrixPtr)

    {

      int  retValue = 0;

     

      matrixPtr->Divider = ((screenPtr[0].x - screenPtr[2].x) * (screenPtr[1].y - screenPtr[2].y)) -

                           ((screenPtr[1].x - screenPtr[2].x) * (screenPtr[0].y - screenPtr[2].y)) ;

     

      if( matrixPtr->Divider == 0 )

      {

        retValue = -1 ;

      }

      else

      {

        matrixPtr->An = ((displayPtr[0].x - displayPtr[2].x) * (screenPtr[1].y - screenPtr[2].y)) -

                        ((displayPtr[1].x - displayPtr[2].x) * (screenPtr[0].y - screenPtr[2].y)) ;

     

        matrixPtr->Bn = ((screenPtr[0].x - screenPtr[2].x) * (displayPtr[1].x - displayPtr[2].x)) -

                        ((displayPtr[0].x - displayPtr[2].x) * (screenPtr[1].x - screenPtr[2].x)) ;

     

        matrixPtr->Cn = (screenPtr[2].x * displayPtr[1].x - screenPtr[1].x * displayPtr[2].x) * screenPtr[0].y +

                        (screenPtr[0].x * displayPtr[2].x - screenPtr[2].x * displayPtr[0].x) * screenPtr[1].y +

                        (screenPtr[1].x * displayPtr[0].x - screenPtr[0].x * displayPtr[1].x) * screenPtr[2].y ;

     

        matrixPtr->Dn = ((displayPtr[0].y - displayPtr[2].y) * (screenPtr[1].y - screenPtr[2].y)) -

                        ((displayPtr[1].y - displayPtr[2].y) * (screenPtr[0].y - screenPtr[2].y)) ;

     

        matrixPtr->En = ((screenPtr[0].x - screenPtr[2].x) * (displayPtr[1].y - displayPtr[2].y)) -

                        ((displayPtr[0].y - displayPtr[2].y) * (screenPtr[1].x - screenPtr[2].x)) ;

     

        matrixPtr->Fn = (screenPtr[2].x * displayPtr[1].y - screenPtr[1].x * displayPtr[2].y) * screenPtr[0].y +

                        (screenPtr[0].x * displayPtr[2].y - screenPtr[2].x * displayPtr[0].y) * screenPtr[1].y +

                        (screenPtr[1].x * displayPtr[0].y - screenPtr[0].x * displayPtr[1].y) * screenPtr[2].y ;

     

     

        // Persist data to EEPROM

        // eepromWriteS32(CFG_EEPROM_TOUCHSCREEN_CAL_AN, matrixPtr->An);

        // eepromWriteS32(CFG_EEPROM_TOUCHSCREEN_CAL_BN, matrixPtr->Bn);

        // eepromWriteS32(CFG_EEPROM_TOUCHSCREEN_CAL_CN, matrixPtr->Cn);

        // eepromWriteS32(CFG_EEPROM_TOUCHSCREEN_CAL_DN, matrixPtr->Dn);

        // eepromWriteS32(CFG_EEPROM_TOUCHSCREEN_CAL_EN, matrixPtr->En);

        // eepromWriteS32(CFG_EEPROM_TOUCHSCREEN_CAL_FN, matrixPtr->Fn);

        // eepromWriteS32(CFG_EEPROM_TOUCHSCREEN_CAL_DIVIDER, matrixPtr->Divider);

        // eepromWriteU8(CFG_EEPROM_TOUCHSCREEN_CALIBRATED, 1);

      }

     

     

      return( retValue ) ;

    }

     

     

    /**************************************************************************/

    /*!

        @brief  Converts raw touch screen locations (screenPtr) into actual

                pixel locations on the display (displayPtr) using the

                supplied matrix.

              

        @param[out] displayPtr  Pointer to the tsPoint_t object that will hold

                                the compensated pixel location on the display

        @param[in]  screenPtr   Pointer to the tsPoint_t object that contains the

                                raw touch screen co-ordinates (before the

                                calibration calculations are made)

        @param[in]  matrixPtr   Pointer to the calibration matrix coefficients

                                used during the calibration process (calculated

                                via the tsCalibrate() helper function)

     

     

        @note  This is based on the public domain touch screen calibration code

               written by Carlos E. Vidales (copyright (c) 2001).

    */

    /**************************************************************************/

    int calibrateTSPoint( tsPoint_t * displayPtr, tsPoint_t * screenPtr, tsMatrix_t * matrixPtr )

    {

      int  retValue = 0 ;

     

      if( matrixPtr->Divider != 0 )

      {

        displayPtr->x = ( (matrixPtr->An * screenPtr->x) +

                          (matrixPtr->Bn * screenPtr->y) +

                           matrixPtr->Cn

                        ) / matrixPtr->Divider ;

     

     

        displayPtr->y = ( (matrixPtr->Dn * screenPtr->x) +

                          (matrixPtr->En * screenPtr->y) +

                           matrixPtr->Fn

                        ) / matrixPtr->Divider ;

      }

      else

      {

        return -1;

      }

     

     

      return( retValue );

    }

     

     

    /**************************************************************************/

    /*!

        @brief  Waits for a touch event

    */

    /**************************************************************************/

    void waitForTouchEvent(tsPoint_t * point)

    {

      /* Clear the touch data object and placeholder variables */

      memset(point, 0, sizeof(tsPoint_t));

     

      /* Clear any previous interrupts to avoid false buffered reads */

      uint16_t x, y;

      tft.touchRead(&x, &y);

      delay(1);

     

     

      /* Wait around for a new touch event (INT pin goes low) */

      while (digitalRead(RA8875_INT))

      {

      }

     

      /* Make sure this is really a touch event */

      if (tft.touched())

      {

        tft.touchRead(&x, &y);

        point->x = x;

        point->y = y;

        Serial.print("Touch: ");

        Serial.print(point->x); Serial.print(", "); Serial.println(point->y);

      }

      else

      {

        point->x = 0;

        point->y = 0;

      }

    }

     

     

    /**************************************************************************/

    /*!

        @brief  Renders the calibration screen with an appropriately

                placed test point and waits for a touch event

    */

    /**************************************************************************/

    tsPoint_t renderCalibrationScreen(uint16_t x, uint16_t y, uint16_t radius)

    {

      tft.fillScreen(RA8875_WHITE);

      tft.drawCircle(x, y, radius, RA8875_RED);

      tft.drawCircle(x, y, radius + 2, 0x8410);  /* 50% Gray */

     

     

      // Wait for a valid touch events

      tsPoint_t point = { 0, 0 };

     

      /* Keep polling until the TS event flag is valid */

      bool valid = false;

      while (!valid)

      {

        waitForTouchEvent(&point);

        if (point.x || point.y)

        {

          valid = true;

        }

      }

     

      return point;

    }

     

     

    /**************************************************************************/

    /*!

        @brief  Starts the screen calibration process.  Each corner will be

                tested, meaning that each boundary (top, left, right and

                bottom) will be tested twice and the readings averaged.

    */

    /**************************************************************************/

    void tsCalibrate(void)

    {

      tsPoint_t data;

     

     

      /* --------------- Welcome Screen --------------- */

      Serial.println("Starting the calibration process");

      data = renderCalibrationScreen(tft.width() / 2, tft.height() / 2, 5);

      delay(250);

     

     

      /* ----------------- First Dot ------------------ */

      // 10% over and 10% down

      data = renderCalibrationScreen(tft.width() / 10, tft.height() / 10, 5);

      _tsLCDPoints[0].x = tft.width() / 10;

      _tsLCDPoints[0].y = tft.height() / 10;

      _tsTSPoints[0].x = data.x;

      _tsTSPoints[0].y = data.y;

      Serial.print("Point 1 - LCD");

      Serial.print(" X: ");

      Serial.print(_tsLCDPoints[0].x);

      Serial.print(" Y: ");

      Serial.print(_tsLCDPoints[0].y);

      Serial.print(" TS X: ");

      Serial.print(_tsTSPoints[0].x);

      Serial.print(" Y: ");

      Serial.println(_tsTSPoints[0].y);

      delay(250);

     

     

      /* ---------------- Second Dot ------------------ */

      // 50% over and 90% down

      data = renderCalibrationScreen(tft.width() / 2, tft.height() - tft.height() / 10, 5);

      _tsLCDPoints[1].x = tft.width() / 2;

      _tsLCDPoints[1].y = tft.height() - tft.height() / 10;

      _tsTSPoints[1].x = data.x;

      _tsTSPoints[1].y = data.y;

      Serial.print("Point 2 - LCD");

      Serial.print(" X: ");

      Serial.print(_tsLCDPoints[1].x);

      Serial.print(" Y: ");

      Serial.print(_tsLCDPoints[1].y);

      Serial.print(" TS X: ");

      Serial.print(_tsTSPoints[1].x);

      Serial.print(" Y: ");

      Serial.println(_tsTSPoints[1].y);

      delay(250);

     

     

      /* ---------------- Third Dot ------------------- */

      // 90% over and 50% down

      data = renderCalibrationScreen(tft.width() - tft.width() / 10, tft.height() / 2, 5);

      _tsLCDPoints[2].x = tft.width() - tft.width() / 10;

      _tsLCDPoints[2].y = tft.height() / 2;

      _tsTSPoints[2].x = data.x;

      _tsTSPoints[2].y = data.y;

      Serial.print("Point 3 - LCD");

      Serial.print(" X: ");

      Serial.print(_tsLCDPoints[2].x);

      Serial.print(" Y: ");

      Serial.print(_tsLCDPoints[2].y);

      Serial.print(" TS X: ");

      Serial.print(_tsTSPoints[2].x);

      Serial.print(" Y: ");

      Serial.println(_tsTSPoints[2].y);

      delay(250);

     

      /* Clear the screen */

      tft.fillScreen(RA8875_WHITE);

     

     

      // Do matrix calculations for calibration and store to EEPROM

      setCalibrationMatrix(&_tsLCDPoints[0], &_tsTSPoints[0], &_tsMatrix);

    }

     

     

    /**************************************************************************/

    /*!

     

     

    */

    /**************************************************************************/

    void setup()

    {

      Serial.begin(9600);

      Serial.println("Hello, RA8875!");

     

     

      /* Initialise the display using 'RA8875_480x272' or 'RA8875_800x480' */

        if (!tft.begin(RA8875_480x272))

      {

        Serial.println("RA8875 not found ... check your wires!");

        while (1);

      }

     

     

      /* Enables the display and sets up the backlight */

      Serial.println("Found RA8875");

      tft.displayOn(true);

      tft.GPIOX(true); // Enable TFT - display enable tied to GPIOX

      tft.PWM1config(true, RA8875_PWM_CLK_DIV1024); // PWM output for backlight

      tft.PWM1out(255);

     

     

      /* Enable the touch screen */

      Serial.println("Enabled the touch screen");

      pinMode(RA8875_INT, INPUT);

      digitalWrite(RA8875_INT, HIGH);

      tft.touchEnable(true);

     

     

      // Try some GFX acceleration!

      //tft.drawCircle(100, 100, 50, RA8875_BLACK);

      //tft.fillCircle(100, 100, 49, RA8875_GREEN);

      //tft.drawPixel(10,10,RA8875_BLACK);

      //tft.drawPixel(11,11,RA8875_BLACK);

      //tft.drawRect(10, 10, 400, 200, RA8875_GREEN);

      //tft.fillRect(11, 11, 398, 198, RA8875_BLUE);

      //tft.drawLine(10, 10, 200, 100, RA8875_RED);

     

      tft.fillScreen(RA8875_WHITE);

      delay(100);

      

      /* Start the calibration process */

      tsCalibrate();

     

      /* _tsMatrix should now be populated with the correct coefficients! */

      Serial.println("Waiting for touch events ...");

    }

     

     

    /**************************************************************************/

    /*!

     

     

    */

    /**************************************************************************/

    void loop()

    {

      tsPoint_t raw;

      tsPoint_t calibrated;

     

     

      /* Wait around for a touch event */

      waitForTouchEvent(&raw);

     

      /* Calcuate the real X/Y position based on the calibration matrix */

      calibrateTSPoint(&calibrated, &raw, &_tsMatrix );

     

      /* Draw a single pixel at the calibrated point */

      tft.fillCircle(calibrated.x, calibrated.y, 3, RA8875_BLACK);

    }

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • roborob1266
    roborob1266 over 5 years ago in reply to Andrew J

    Hi Andrew

    Not sure if the code i placed above shows what you are looking for. I agree with you that it has to be on a release but what if someone presses one touch screen button then slides their finger to another image and let go there?

    how is that accounted for with your code?

     

    Regards

    Rob

    • Cancel
    • Vote Up +1 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • Andrew J
    Andrew J over 5 years ago in reply to roborob1266

    I'm not taking account, per-se, of touch down, move release.  When I ask for status (line 05), the response will be -1 if no touch detected, or another value that equates to TOUCH_PRESSED, TOUCH_MOVED, TOUCH_RELEASED.  Whilst I don't directly action on the TOUCH_MOVE status, when I get the TOUCH_PRESSED I capture the widget index that was touched (line 08).  When the status is TOUCH_RELEASED, I compare the widget index that was reported at that point with the one at the time of touch and if they are the same then I know that the person touched down and released on the same widget (line 16.)

     

    I looked at the code before to determine that it works on a touch point (co-ordinate) rather than reporting 'what' was touched.  So you will need to do this comparison yourself.  Relevant code appear to be:

     

    void waitForTouchEvent(tsPoint_t * point) {
      /* Clear the touch data object and placeholder variables */
      memset(point, 0, sizeof(tsPoint_t));
    
      /* Clear any previous interrupts to avoid false buffered reads */
      uint16_t x, y;
      tft.touchRead(&x, &y);
      delay(1);
    
    
      /* Wait around for a new touch event (INT pin goes low) */
      while (digitalRead(RA8875_INT)) {
      }
    
      /* Make sure this is really a touch event */
      if (tft.touched()) {
        tft.touchRead(&x, &y);
        point->x = x;
        point->y = y;
        Serial.print("Touch: ");
        Serial.print(point->x); Serial.print(", "); Serial.println(point->y);
      }  else {
        point->x = 0;
        point->y = 0;
      }
    }

     

    Line 12 is waiting for a touch and looping until it detects one - digitalRead(RA8875_INT) becomes 0.  This sets an interrupt flag on the controller. 

     

    Line 16 then tests to see if the screen was touched (returns true if the interrupt flag is set) and if it was, gets the co-ordinates into variables X and Y ( line 17) - reading the co-ordinates clears the flag.  So these three bits of code give you the code for detecting a touch and where.  I suspect you may be right with this controller: the code may run fast enough that it detects a touch, reports it and reads it, before the finger is removed and then it reports a touch again.  To debounce it you will want to 'wait' to process a touch for a small amount of time.

     

    Using the above as an example - you should be able to adjust for your own use:

     

    unsigned long lastTouchTime = millis();
    
    void waitForTouchEvent(tsPoint_t * point) {
      /* Clear the touch data object and placeholder variables */
      memset(point, 0, sizeof(tsPoint_t));
    
      /* Clear any previous interrupts to avoid false buffered reads */
      uint16_t x, y;
      tft.touchRead(&x, &y);
      delay(1);
    
    
      /* Wait around for a new touch event (INT pin goes low) */
      while (digitalRead(RA8875_INT)) {
      }
    
      /* Make sure this is really a touch event */
      if (tft.touched()) {
        tft.touchRead(&x, &y);
        if(millis() - lastTouchTime > 500) {     // if 500mS have passed since last processing a touch then process it.
             point->x = x;
             point->y = y;
             Serial.print("Touch: ");
             Serial.print(point->x); Serial.print(", "); Serial.println(point->y);
        } else {
              // ignore the press as it happened too quickly
              // This else clause is only needed if you need to do something when ignoring the press.
        }
        lastTouchTime = millis();
      } else {
        point->x = 0;
        point->y = 0;
      }
    }

     

    I added line 01 to declare a global variable to keep track of the time the screen was touched.  I added line 20 and 25-28 to wrap around the code to process the touch and if less than 500mS has passed, it ignores it. Line 29 then sets the time it was last touched. You can play around with this value and make it as small as possible - for example, I used a value of 150mS to debounce a mechanical rotary encoder pushswitch. 

     

    You must still execute the tft.touchRead(&x, &y) (line 19) because it is responsible for clearing the flag.

     

    So, this should work by:

    1. waiting for a touch event (line 14)
    2. detect if it was a real touch (is the touch flag set?) - line 18
    3. read the co-ordinates and reset the flag - line 19
    4. check that at least 500mS has passed since last processing a touch - line 20
    5. capture the time of the last press - line 29

    I can't test this of course but it looks ok.  Line 14 you will need to work out for your own application: in the code above it loops forever waiting for a touch - if this isn't something you want, then you'll need to adjust.  The three bits of code I pointed out are the ones you need to work with.

    • Cancel
    • Vote Up +2 Vote Down
    • Sign in to reply
    • More
    • Cancel
Comment
  • Andrew J
    Andrew J over 5 years ago in reply to roborob1266

    I'm not taking account, per-se, of touch down, move release.  When I ask for status (line 05), the response will be -1 if no touch detected, or another value that equates to TOUCH_PRESSED, TOUCH_MOVED, TOUCH_RELEASED.  Whilst I don't directly action on the TOUCH_MOVE status, when I get the TOUCH_PRESSED I capture the widget index that was touched (line 08).  When the status is TOUCH_RELEASED, I compare the widget index that was reported at that point with the one at the time of touch and if they are the same then I know that the person touched down and released on the same widget (line 16.)

     

    I looked at the code before to determine that it works on a touch point (co-ordinate) rather than reporting 'what' was touched.  So you will need to do this comparison yourself.  Relevant code appear to be:

     

    void waitForTouchEvent(tsPoint_t * point) {
      /* Clear the touch data object and placeholder variables */
      memset(point, 0, sizeof(tsPoint_t));
    
      /* Clear any previous interrupts to avoid false buffered reads */
      uint16_t x, y;
      tft.touchRead(&x, &y);
      delay(1);
    
    
      /* Wait around for a new touch event (INT pin goes low) */
      while (digitalRead(RA8875_INT)) {
      }
    
      /* Make sure this is really a touch event */
      if (tft.touched()) {
        tft.touchRead(&x, &y);
        point->x = x;
        point->y = y;
        Serial.print("Touch: ");
        Serial.print(point->x); Serial.print(", "); Serial.println(point->y);
      }  else {
        point->x = 0;
        point->y = 0;
      }
    }

     

    Line 12 is waiting for a touch and looping until it detects one - digitalRead(RA8875_INT) becomes 0.  This sets an interrupt flag on the controller. 

     

    Line 16 then tests to see if the screen was touched (returns true if the interrupt flag is set) and if it was, gets the co-ordinates into variables X and Y ( line 17) - reading the co-ordinates clears the flag.  So these three bits of code give you the code for detecting a touch and where.  I suspect you may be right with this controller: the code may run fast enough that it detects a touch, reports it and reads it, before the finger is removed and then it reports a touch again.  To debounce it you will want to 'wait' to process a touch for a small amount of time.

     

    Using the above as an example - you should be able to adjust for your own use:

     

    unsigned long lastTouchTime = millis();
    
    void waitForTouchEvent(tsPoint_t * point) {
      /* Clear the touch data object and placeholder variables */
      memset(point, 0, sizeof(tsPoint_t));
    
      /* Clear any previous interrupts to avoid false buffered reads */
      uint16_t x, y;
      tft.touchRead(&x, &y);
      delay(1);
    
    
      /* Wait around for a new touch event (INT pin goes low) */
      while (digitalRead(RA8875_INT)) {
      }
    
      /* Make sure this is really a touch event */
      if (tft.touched()) {
        tft.touchRead(&x, &y);
        if(millis() - lastTouchTime > 500) {     // if 500mS have passed since last processing a touch then process it.
             point->x = x;
             point->y = y;
             Serial.print("Touch: ");
             Serial.print(point->x); Serial.print(", "); Serial.println(point->y);
        } else {
              // ignore the press as it happened too quickly
              // This else clause is only needed if you need to do something when ignoring the press.
        }
        lastTouchTime = millis();
      } else {
        point->x = 0;
        point->y = 0;
      }
    }

     

    I added line 01 to declare a global variable to keep track of the time the screen was touched.  I added line 20 and 25-28 to wrap around the code to process the touch and if less than 500mS has passed, it ignores it. Line 29 then sets the time it was last touched. You can play around with this value and make it as small as possible - for example, I used a value of 150mS to debounce a mechanical rotary encoder pushswitch. 

     

    You must still execute the tft.touchRead(&x, &y) (line 19) because it is responsible for clearing the flag.

     

    So, this should work by:

    1. waiting for a touch event (line 14)
    2. detect if it was a real touch (is the touch flag set?) - line 18
    3. read the co-ordinates and reset the flag - line 19
    4. check that at least 500mS has passed since last processing a touch - line 20
    5. capture the time of the last press - line 29

    I can't test this of course but it looks ok.  Line 14 you will need to work out for your own application: in the code above it loops forever waiting for a touch - if this isn't something you want, then you'll need to adjust.  The three bits of code I pointed out are the ones you need to work with.

    • Cancel
    • Vote Up +2 Vote Down
    • Sign in to reply
    • More
    • Cancel
Children
  • roborob1266
    roborob1266 over 5 years ago in reply to Andrew J

    Thank you Andrew, I will try this code when i get off of work.

    I was thinking that the Interrupt pin (18) was the key and i was even going try the hardware way of putting a capacitor in line if i couldn't figure out the code.

     

    Thank you again for letting me try this code and I will let you know the outcome!

    Regards,

    • Cancel
    • Vote Up +1 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • roborob1266
    roborob1266 over 5 years ago in reply to roborob1266

    Hello Andrew,

    i just tried the code (just got some time to try it) and it did not work.

    I noticed that if i hold my finger on the screen, it continue to speak to me saying the same thing as if i keep pressing it.

    very interesting dilemma.

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • Andrew J
    Andrew J over 5 years ago in reply to roborob1266

    I don't have one of these to test unfortunately.  A bit of googling indicates that the interrupt pin goes HIGH when the panel is being touched, so the while() loop on line 14 isn't quite right I don't think.  Can you cut your code down to the absolute simplest version you can, just to get a grip on the touch handling - in fact, start a new sketch that just does screen touch detect, outputting the X,Y co-ordinates to the Serial monitor every time it detects a touch.  What we should be aiming for, in pseudocode, is something like:

     

    loop()

         clear touch data and reset read interrupts

         while(not touched)  <-- interrupt pin is LOW

              do nothing

         while(touched) <-- interrupt pin is HIGH

              save X,Y coordinates

         if touched and time since last touch > 500mS

              print X,Y coordinates

              save last touch time

         end if

    end loop

     

    What this should do is wait until it detects a touch, then stores the X,Y coordinates until it no longer detects a touch, then prints out the co-ordinates if enough time has passed.

     

    For the moment, forget playing your audio file. startup() should do the minimum it needs to initialise the serial monitor and the display, and loop() should do the above code.  See what happens: are you getting multiple output to the Serial monitor every time you press?  You could try it without the time elapsed element first if you want - it may be clever enough to already detect 'bounce', or indeed not bounce at all.  If we can get this working, then you can expand on it incrementally to detect movement whilst touching (X,Y changes as it detects touches) and so on.

     

    Can I ask - how much coding experience do you have? 

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
element14 Community

element14 is the first online community specifically for engineers. Connect with your peers and get expert answers to your questions.

  • Members
  • Learn
  • Technologies
  • Challenges & Projects
  • Products
  • Store
  • About Us
  • Feedback & Support
  • FAQs
  • Terms of Use
  • Privacy Policy
  • Legal and Copyright Notices
  • Sitemap
  • Cookies

An Avnet Company © 2025 Premier Farnell Limited. All Rights Reserved.

Premier Farnell Ltd, registered in England and Wales (no 00876412), registered office: Farnell House, Forge Lane, Leeds LS12 2NE.

ICP 备案号 10220084.

Follow element14

  • X
  • Facebook
  • linkedin
  • YouTube