0
\$\begingroup\$

Just for fun and to learn, I'm writing code to drive a 800x480 TFT with resistive touch driven by an RA8875 and an ATmega328P and avr-libc.

It works fine so far but when reading touch events, I don't get touch points close to the edge of the screen; it seems like the coordinates are "scaled" down to an area of about (40, 60) and (760, 440):

touch point area

This is how the touch controller of the RA8875 is initialized:

// enable touch panel, wait 4096 clocks, system clock/8
regWrite(TPCR0, 0x80 | 0x30 | 0x03);
// enable debounce for touch interrupt
regWrite(TPCR1, 0x04);
// enable touch interrupt
regWrite(INTC1, 0x04);

The touch point is read like this:

void readTouch(Point *point) {
    uint8_t tpxh = regRead(TPXH);
    uint8_t tpyh = regRead(TPYH);
    uint8_t tpxyl = regRead(TPXYL);
    
    point->x = (tpxh << 2);
    point->x |= (tpxyl & 0x03);
    
    point->y = (tpyh << 2);
    point->y |= ((tpxyl & 0x0c) >> 2);
    
    // 10-bit ADC
    point->x = ((uint32_t)point->x * DISPLAY_WIDTH) >> 10;
    point->y = ((uint32_t)point->y * DISPLAY_HEIGHT) >> 10;
}

The point is used to draw a green circle with a radius of 10, then the touch interrupt is cleared.

Am I doing something wrong or is this common behaviour of such a touch panel and/or the RA8875 touch controller? Could this be improved by calibration, like "scaling up" the touch area to the display size?

\$\endgroup\$
5
  • \$\begingroup\$ What convinces you that the touch elements extend all the way to the edge of the screen? \$\endgroup\$
    – Andy aka
    Commented Jun 29 at 14:05
  • \$\begingroup\$ @Andyaka I am not convinced, it is just a (naive?) expectation. \$\endgroup\$ Commented Jun 29 at 19:46
  • 1
    \$\begingroup\$ I received a 1 day ban the other day for suggesting someone was naïve so, clearly I'm regarding your comment as potentially entrapment LOL. \$\endgroup\$
    – Andy aka
    Commented Jun 29 at 19:56
  • 1
    \$\begingroup\$ LOL you're safe to suggest I was naive, I can handle it. A 1 day ban for that..? \$\endgroup\$ Commented Jun 29 at 20:27
  • \$\begingroup\$ You can say that you are niave, telling someone else they are niave is not constructive and violates site rules \$\endgroup\$
    – Voltage Spike
    Commented Jul 1 at 14:36

1 Answer 1

3
\$\begingroup\$

Your touchscreen will return a raw ADC value that is proportional to where on the screen you touch. The full scale range of the ADC value does not necessarily however correspond to the full width/height of your screen.

In fact it will be less than the full width to allow for tolerances in the display, to make sure that you can always read a touch point from any part of the visible screen (it would be bad if it maxed out before the edge of the screen!).

This is precisely what touchscreen calibration is for. You need to work out the ADC values that correspond to at least two points in each direction (two height points, and two width points) to work out a simple scale factor. To also account for any rotation or skew, you need at least three to four points.

The process is generally done using four points, one in each corner of the display (your white dots). You ask the user to press on each of these dots and record the values. You now know the X and Y ADC values which correspond to each of those points, and can therefore map the ADC values correctly to every point in between.

There is an example on the Adafruit RA8875 GitHub repository here that shows the process of calibration.

\$\endgroup\$
1
  • \$\begingroup\$ Thanks for your clear answer. I had seen the example on calibration, it looked complicated and program space consuming and I thought it is rather for accuracy enthusiasts, but now it makes sense to me. \$\endgroup\$ Commented Jun 29 at 20:32

Not the answer you're looking for? Browse other questions tagged or ask your own question.