esphome-docs/components/touchscreen/index.rst

305 lines
11 KiB
ReStructuredText

Touchscreen Components
======================
.. seo::
:description: Instruction for using touchscreen components.
:image: folder-open.svg
The ``touchscreen`` component contains the base code for most touchscreen driver components
available in ESPHome and is responsible for passing the touch events to
``binary_sensors`` with the ``touchscreen`` platform. It is also used by the LVGL component.
.. _config-touchscreen:
Base Touchscreen Configuration
------------------------------
.. code-block:: yaml
# Example touchscreen
touchscreen:
- platform: ...
display: display1
transform:
mirror_x: false
mirror_y: false
swap_xy: false
on_touch:
then:
...
on_update:
then:
...
on_release:
then:
...
Configuration variables:
************************
- **display** (*Required*, :ref:`config-id`): The display to use this touchscreen with.
- **transform** (*Optional*): Transform the reported position to match the display.
- **swap_xy** (*Optional*, boolean): If true, exchange the x and y axes.
- **mirror_x** (*Optional*, boolean): If true, mirror the x axis.
- **mirror_y** (*Optional*, boolean): If true, mirror the y axis.
- **update_interval** (*Optional*, :ref:`config-time`): The touchscreen polling interval - used only if an interrupt pin is not in use. Defaults to ``50ms``.
- **touch_timeout** (*Optional*, :ref:`config-time`): A timeout for touchscreens that do not report the end of touch. The default varies depending on the touchscreen.
- **calibration** (*Optional*): Some touchscreens require calibration on a per-device basis.
- **x_min** (**Required**, int): The raw value corresponding to the left
(or top if ``swap_xy`` is specified) edge of the touchscreen. See :ref:`touchscreen-calibration`
for the process to calibrate the touchscreen.
- **x_max** (**Required**, int): The raw value corresponding to the right
(or bottom if ``swap_xy`` is specified) edge of the touchscreen.
- **y_min** (**Required**, int): The raw value corresponding to the top
(or left if ``swap_xy`` is specified) edge of the touchscreen.
- **y_max** (**Required**, int): The raw value corresponding to the bottom
(or right if ``swap_xy`` is specified) edge of the touchscreen.
- **on_touch** (*Optional*, :ref:`Automation <automation>`): An automation to perform
when the touchscreen is touched. See :ref:`touchscreen-on_touch`.
- **on_update** (*Optional*, :ref:`Automation <automation>`): An automation to perform
when the touchscreen is touched. See :ref:`touchscreen-on_update`.
- **on_release** (*Optional*, :ref:`Automation <automation>`): An automation to perform
when the touchscreen is no longer touched. See :ref:`touchscreen-on_release`.
.. _touchscreen-touchpoint:
``TouchPoint`` Argument Type
----------------------------
Both the :ref:`touchscreen-on_touch` and :ref:`touchscreen-on_update` have an argument of the type :apistruct:`touchscreen::TouchPoint` in a
list (``on_update``) or as an ``optional`` (``on_touch``).
The integer members for the touch positions below are in relation to the display width and height:
- ``id`` is a number provided by the touchscreen to uniquely identify the touch on a multi-touch screen.
- ``state`` indicates the state of the touch. This can be **1**, indicating it is an initial touch, or **2** indicating the touch position has changed/moved.
- ``x`` and ``y`` are the current position.
- ``x_last`` and ``y_last`` are the previous position.
- ``x_first`` and ``y_first`` are the position of the touch when it was first detected.
- ``x_raw`` and ``y_raw`` are for calibrating the touchscreen in relation of the display. This replaces the properties with the same name in the touchscreen classes.
.. _touchscreen-calibration:
Calibration
-----------
For most touchscreen drivers the dimensions of the touchscreen are automatically set from the display driver to match the screen size.
In some cases such as the :ref:`XPT2046 <xpt2046-component>` (a resistive touch screen) the reported values bear no relation to the actual screen size.
The ``calibration`` configuration can be used to manually calibrate the touchscreen.
To match the point of the touch to the display coordinates the touch screen has to be calibrated.
The touchscreen component returns raw values in the calibration range. Those raw values are available
as the ``x_raw`` and ``y_raw`` member variables. The goal of the calibration is to identify the raw values corresponding
to the edges of the screen.
The calibration assumes a display oriented in a way that you will be using it, i.e. your
:ref:`display-engine` component has to have the [0,0] logical coordinate at the top left.
.. code-block:: yaml
# Touchscreen
touchscreen:
platform: xpt2046
id: my_touchscreen
cs_pin: GPIOXX
on_touch:
- lambda: |-
ESP_LOGI("cal", "x=%d, y=%d, x_raw=%d, y_raw=%0d",
touch.x,
touch.y,
touch.x_raw,
touch.y_raw
);
Get a stylus or a similar object, run the project and touch the corners of the screen at
the edge pixels. Repeat several times and note minimum and maximum x and y raw values.
.. code-block:: none
... top left ...
[21:07:48][I][cal:071]: x=217, y=34, x_raw=3718, y_raw=445
[21:07:49][I][cal:071]: x=222, y=32, x_raw=3804, y_raw=419
... top right ...
[21:07:52][I][cal:071]: x=19, y=36, x_raw=334, y_raw=370
[21:07:52][I][cal:071]: x=22, y=35, x_raw=386, y_raw=347
... bottom left ...
[21:08:00][I][cal:071]: x=224, y=299, x_raw=3836, y_raw=3835
[21:08:00][I][cal:071]: x=225, y=303, x_raw=3848, y_raw=3878
[21:08:01][I][cal:071]: x=223, y=299, x_raw=3807, y_raw=3829
... bottom right ...
[21:08:11][I][cal:071]: x=16, y=299, x_raw=281, y_raw=3839
[21:08:12][I][cal:071]: x=19, y=302, x_raw=328, y_raw=3866
[21:08:13][I][cal:071]: x=20, y=296, x_raw=358, y_raw=3799
That means that the minimum raw x is 281, maximum 3848, minimum y 347 and maximum 3878.
Identify which raw value is the display's x direction and what the y one. In our case
moving right decreases the x raw value and going down increases the y one so the axes
match and we *don't* need to use ``swap_xy``. If the raw x is the display's y,
use ``swap_xy = true``.
If one of the coordinates goes in the "wrong" direction it needs to be inverted.
The inversion is performed by setting the ``mirror_x`` and/or ``mirror_y`` to true.
.. code-block:: yaml
touchscreen:
platform: xpt2046
calibration:
x_min: 281
x_max: 3848
y_min: 347
y_max: 3878
transform:
mirror_x: false
mirror_y: false
swap_xy: false
Compile, run and click on the edges again. The x and y should now match the coordinates
of the display.
.. code-block:: none
[21:32:34][I][cal:071]: x=7, y=6, x_raw=3755, y_raw=407
[21:32:37][I][cal:071]: x=237, y=4, x_raw=313, y_raw=385
[21:32:43][I][cal:071]: x=239, y=318, x_raw=284, y_raw=3845
[21:33:05][I][cal:071]: x=2, y=313, x_raw=3821, y_raw=3793
Note that the touch screen is not extremely precise and there might be nonlinearities
or similar errors so don't expect a pixel-perfect precision. You can verify the touchpoint
using a display lambda similar to the following.
.. code-block:: yaml
display:
- platform: ili9341
lambda: |-
auto touch = id(my_touchscreen)->get_touch();
if (touch) // or touch.has_value()
it.filled_circle(touch.value().x, touch.value().y, 10, RED);
To be exact, the component does the following
- reads the raw x and y and normalizes it using (non-inverted) min and max values
- swaps x and y if needed
- inverts if needed
- scales to the display dimensions
.. _touchscreen-on_touch:
``on_touch`` Trigger
--------------------
This automation will be triggered when the touchscreen initially detects a touch on the touchscreen; it will not be fired again until
all touches (for multi-touch supported drivers) are released.
NOTE: This has changed (from ESPHome 2023.11.6.) To receive continuous updates from touch drags, use :ref:`touchscreen-on_update`.
This trigger provides two arguments named ``touch`` of type *touchpoint* and ``touches`` with a list of all touches.
.. _touchscreen-on_update:
``on_update`` Trigger
---------------------
This new automation will be triggered when the touchscreen detects an extra touch or that a touch has moved around on the screen.
This trigger provides one argument named ``touches`` of type :apiref:`touchscreen::TouchPoints_t` which has a list of
:ref:`touchscreen-touchpoint`.
This trigger may be useful to detect gestures such as swiping across the display.
For example you could do:
.. code-block:: yaml
on_update:
- lambda: |-
for (auto touch: touches) {
if (touch.state <= 2) {
ESP_LOGI("Touch points:", "id=%d x=%d, y=%d", touch.id, touch.x, touch.y);
}
}
Be aware that you need to check the state flag every time to see if the touch is still valid.
- state value 0. means the touch is invalid as the touch is no longer detected.
- state value 1 means is being the first time detected.
- state value 2 means the touch is still being detected but is moved on the screen.
- state value 4 and higher means a touch release is detected.
.. _touchscreen-on_release:
``on_release`` Trigger
----------------------
This automation will be triggered when all touches are released from the touchscreen.
At this point of time it has no extra arguments.
Binary Sensor
-------------
The ``touchscreen`` binary sensor allows you to setup areas on the touch screen as virtual
buttons.
.. code-block:: yaml
binary_sensor:
- platform: touchscreen
name: Top Left Touch Button
x_min: 0
x_max: 100
y_min: 0
y_max: 100
page_id: home_page_id
Configuration variables:
************************
- **touchscreen_id** (*Optional*, :ref:`config-id`): Manually specify the ID of the touchscreen.
- **x_min** (**Required**, int): Left coordinate of the screen area to be detected as the virtual button.
- **x_max** (**Required**, int): Right coordinate of the screen area to be detected as the virtual button.
- **y_min** (**Required**, int): Top coordinate of the screen area to be detected as the virtual button.
- **y_max** (**Required**, int): Bottom coordinate of the screen area to be detected as the virtual button.
- **page_id** (*Optional*, :ref:`config-id`): Only trigger this binary sensor if the display is showing this page.
Cannot be used with ``pages``.
- **pages** (*Optional*, list of :ref:`config-id`): Only trigger this binary sensor if the display is showing one of these pages.
Cannot be used with ``page_id``.
- All other options from :ref:`Binary Sensor <config-binary_sensor>`.
See Also
--------
- :ref:`Binary Sensor Filters <binary_sensor-filters>`
- :doc:`Inkplate 6 Plus </components/display/inkplate6>`
- :doc:`EKTF2232 </components/touchscreen/ektf2232>`
- :doc:`XPT2046 </components/touchscreen/xpt2046>`
- :doc:`TT21100 </components/touchscreen/tt21100>`
- :doc:`GT911 </components/touchscreen/gt911>`
- :apiref:`touchscreen/touchscreen.h`
- :apiref:`touchscreen/binary_sensor/touchscreen_binary_sensor.h`
- :ghedit:`Edit`
.. toctree::
:maxdepth: 1
:glob:
*