Touchscreen Components

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.

Warning

As of version 2023.12 the way how the touchscreen component has changed a bit. The following variables are now obsolite: * rotation is (temporary) removed in favor the new transform: * size_x_y is moved inside the transform: and renamed to size_xy * report_interval is removed in favor of using the update_interval The display id is only just to calculate the touch position reletive to the displays height and width

Base Touchscreen Configuration

# Example touchscreen
touchscreen:
  - platform: ...
    display: display1
    transform:
      mirror_x: false
      mirror_y: false
      swap_xy: false
    calibration:
      x_max: 240
      y_max: 320

    on_touch:
      then:
        ...
    on_update:
      then:
        ...
    on_release:
      then:
        ...

Configuration variables:

  • display (Required, ID): The display to use this touchscreen with.

  • transform (Optional): Transform the touchscreen presentation using hardware. All defaults are false.

    • 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, Time): The interval to check the touchscreen. Defaults to never. NOTE: You should set this to 50ms when you dont have set the interupt_pin.

  • calibration (Optional): When the touchscreen is not given the right configuration settings. You can set them here.

    • x_min (Optional, int): The raw value corresponding to the left (or top if swap_xy is specified) edge of the touchscreen. See Calibration for the process to calibrate the touchscreen. Defaults to 0.

    • x_max (Optional, int): The raw value corresponding to the right (or bottom if swap_xy is specified) edge of the touchscreen. Defaults to 0.

    • y_min (Optional, int): The raw value corresponding to the top (or left if swap_xy is specified) edge of the touchscreen. Defaults to 0.

    • y_max (Optional, int): The raw value corresponding to the bottom (or right if swap_xy is specified) edge of the touchscreen. Defaults to 0.

  • on_touch (Optional, Automation): An automation to perform when the touchscreen is touched. See on_touch Trigger.

  • on_update (Optional, Automation): An automation to perform when the touchscreen is touched. See on_update Trigger.

  • on_release (Optional, Automation): An automation to perform when the touchscreen is no longer touched. See on_release Trigger.

TouchPoint Argument Type

Both the on_touch Trigger and on_update Trigger have an argument of the type 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.

Calibration

For most of the touchscreen drivers the dimensions of the touchscreen are automatically set when the driver is setup. In some cases like for the XPT2046 this can be different per used display panel. Then you can set the values using the calibrate values.

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 0 to 4095 range. Those raw values are available as the x_raw and y_raw member variables and for example write them out as in the example on_touch Trigger. 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 Display Rendering Engine component has to have the [0,0] logical coordinate at the top left.

Note

Do not set any calibration values nor transform settings.

# Touchscreen
touchscreen:
  platform: xpt2046
  id: my_touchscreen
  cs_pin: 17
  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.

Warning

As long the calibrate settings are not correctly set, the x and y coordinates are not calculated.

... 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.

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.

[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.

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

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 on_update Trigger.

This trigger provides two arguments named touch of type touchpoint and touches with a list of all touches.

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 API Reference which has a list of

TouchPoint Argument Type.

This trigger may be useful to detect gestures such as swiping across the display.

For example you could do:

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.

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.

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:

  • name (Optional, string): The name for the binary sensor.

  • id (Optional, ID): Manually specify the ID used for code generation.

  • touchscreen_id (Optional, 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, ID): Only trigger this binary sensor if the display is showing this page.

  • All other options from Binary Sensor.

See Also