Mapping touch coordinate to a button

I’m displaying several buttons on a 3.5” screen. Each button is a class object with all text, size, color, position and button-press action info.

When the screen is touched, the coordinates are captured and those need to be mapped to the specific button so the appropriate action can be taken.

An array could be loaded with just the coordinates, Button size, and Action. Then just search it to find if those coordinates are within a specific button’s footprint. If found, execute that button's action.

Example: Button HourPlus("Hour+", X, Y, W, H, IncHour);

With this example you would need to store (X, Y, W, H, IncHour) in the array.

Is there a better way to go about mapping touch location to a button?

You describe the ordinary GUI mapping function :slight_smile:

As a minor improvement the windows on screen (buttons...) are organized as a tree and sorted by top-left X,Y coordinates. For small displays with only about 2 buttons such an organization only means useless overhead. For a GUI design tool the tree organization with nested sub-trees is a must-have.

What display?
What Arduino controller?

If your screen is using an Arduino Library then there should be examples of using it touch system.

Thanks.. Tom.. :slight_smile:

I obviously didn't make this post clear enough. This is not a problem specific to any Arduino or display, it is the same logical problem with any touchscreen display and any Arduino board. Just for reference, this is an Arduino UNO and the 3.5" display is this one:

The arduino library example does show how to use the touch screen, but they do not show how to map the coordinates to a specific button that was drawn by the user.

I can read the touch coordinates just fine. I can draw a button on the screen just fine. The logical problem I am trying to figure out is how best to map a touch coordinate to a specific button that was previously drawn.

I compute the squared distance (d2) from the button center to the current touch coordinates.

d2 = (bx - tx)*(bx - tx) + (by - ty)*(by - ty);

If d2 is less than the button radius squared, then that button was selected. It is not the most efficient approach, but it works 100% of the time.

You will find this function, which does not do any multiplies, in the Adafruit graphics library:

boolean Adafruit_GFX_Button::contains(int16_t x, int16_t y) {
  return ((x >= _x1) && (x < (_x1 + _w)) &&
          (y >= _y1) && (y < (_y1 + _h)));

That is what I needed. Thanks!

I have a screen drawing library I use to do the touchscreen thing. Well, all screens, touch or otherwise actually.

Not yet very well documented. But, its found here : LC_GUIbase

Example project using it : Home made smart-phone

It has two basic classes that its built on.

A displayObj class that gives a uniform interface to what ever display hardware I've ported to it.


A drawObj class that is the base object of everything that can be drawn and/or touched on the screen.

If the display has no touch interface, no problem everything still works and draws great. Just nothing receives touch events.

If it does have some sort of touch functionality, like a capacitive touch screen, then touch events are passed down the drawObject list to see if any of them would like to handle it. (IE do something)

If you are thinking about doing more interface code, you may want to consider a path like this. Yes, it takes a LOT of effort to write and get working. But, if you do it right, its extremely handy to be able to add a touchscreen to your project without worrying about coding it.

Hope this helps.

-jim lee


For some time I have wanted to generalize a UI for touch displays but I don't really have the experience to do that very well. What you have been helping me with of late is my first attempts to do that with drawing "buttons" and activating actions when they are touched.

What you are offering here sounds like a big step in that direction. I will look into it.

You don't happen to have an example with UNO, LEONARDO, TEENSY 4.0 or 4.1, or MKR Zero, all of which I currently have?

I typically run everything on Teensy3.2s. From what I read, that's pretty much like their 4.x version that you have. So, that should not be a problem.

The bigger issue is what display are you using? I've ported this to three(?) Adafruit displays. The only one of those that has touch is their UNO shield, #1947 with the capacitive touch.

What displays do you have available?

If we can match up a display, I can write you an example program for your Teensy to play with.

-jim lee


That is a very generous offer. Thank you.

This this the display:

Here is the setup being used::

#include "Adafruit_HX8357.h"
#include <Adafruit_GFX.h>    // Core graphics library
#include "TouchScreen.h"

// These are the four touchscreen analog pins
#define YP A2  // must be an analog pin, use "An" notation!
#define XM A3  // must be an analog pin, use "An" notation!
#define YM 7   // can be a digital pin
#define XP 8   // can be a digital pin
TouchScreen tscr = TouchScreen(XP, YP, XM, YM, 500);

#define MINPRESSURE 300
#define MAXPRESSURE 1000

// The display uses hardware SPI, plus #9 & #10
#define TFT_RST -1  // dont use a reset pin, tie to arduino RST if you like
#define TFT_DC 9
#define TFT_CS 10

// This is calibration data for the raw touch data to the screen coordinates
#define TS_MINX 110
#define TS_MINY 80
#define TS_MAXX 900
#define TS_MAXY 940

All I would really need is a small example demonstrating the major functions.
BTW: I have a Teensy 3.2 as well. Let me know if you need any other information.

Ops display.

Tom.. :slight_smile:


Thanks Tom!

Ok, this display should be pretty close to what I've been using.(Just bigger and resistive touch) I ordered one for myself and it'll be a couple days to get here. But I can make up a test program for mine now, let you play with it, and then port the bit for yours once my display arrives.

-jim lee

I will be out of pocket for a few days with friends visiting tomorrow until Saturday.