ESPHome  2024.4.0
touchscreen.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include "esphome/core/defines.h"
5 
7 #include "esphome/core/hal.h"
8 
9 #include <vector>
10 #include <map>
11 
12 namespace esphome {
13 namespace touchscreen {
14 
15 static const uint8_t STATE_RELEASED = 0x00;
16 static const uint8_t STATE_PRESSED = 0x01;
17 static const uint8_t STATE_UPDATED = 0x02;
18 static const uint8_t STATE_RELEASING = 0x04;
19 static const uint8_t STATE_CALIBRATE = 0x07;
20 
21 struct TouchPoint {
22  uint8_t id;
23  int16_t x_raw{0}, y_raw{0}, z_raw{0};
24  uint16_t x_prev{0}, y_prev{0};
25  uint16_t x_org{0}, y_org{0};
26  uint16_t x{0}, y{0};
27  int8_t state{0};
28 };
29 
30 using TouchPoints_t = std::vector<TouchPoint>;
31 
33  volatile bool touched{true};
34  bool init{false};
35  static void gpio_intr(TouchscreenInterrupt *store);
36 };
37 
39  public:
40  virtual void touch(TouchPoint tp) {}
41  virtual void update(const TouchPoints_t &tpoints) {}
42  virtual void release() {}
43 };
44 
45 class Touchscreen : public PollingComponent {
46  public:
47  void set_display(display::Display *display) { this->display_ = display; }
48  display::Display *get_display() const { return this->display_; }
49 
50  void set_touch_timeout(uint16_t val) { this->touch_timeout_ = val; }
51  void set_mirror_x(bool invert_x) { this->invert_x_ = invert_x; }
52  void set_mirror_y(bool invert_y) { this->invert_y_ = invert_y; }
53  void set_swap_xy(bool swap) { this->swap_x_y_ = swap; }
54 
55  void set_calibration(int16_t x_min, int16_t x_max, int16_t y_min, int16_t y_max) {
56  this->x_raw_min_ = std::min(x_min, x_max);
57  this->x_raw_max_ = std::max(x_min, x_max);
58  this->y_raw_min_ = std::min(y_min, y_max);
59  this->y_raw_max_ = std::max(y_min, y_max);
60  if (x_min > x_max)
61  this->invert_x_ = true;
62  if (y_min > y_max)
63  this->invert_y_ = true;
64  }
65 
67  Trigger<const TouchPoints_t &> *get_update_trigger() { return &this->update_trigger_; }
68  Trigger<> *get_release_trigger() { return &this->release_trigger_; }
69 
70  void register_listener(TouchListener *listener) { this->touch_listeners_.push_back(listener); }
71 
72  optional<TouchPoint> get_touch() { return this->touches_.begin()->second; }
73 
75  TouchPoints_t touches;
76  for (auto i : this->touches_) {
77  touches.push_back(i.second);
78  }
79  return touches;
80  }
81 
82  void update() override;
83  void loop() override;
84  void call_setup() override;
85 
86  protected:
88 
89  void attach_interrupt_(InternalGPIOPin *irq_pin, esphome::gpio::InterruptType type);
90 
91  void add_raw_touch_position_(uint8_t id, int16_t x_raw, int16_t y_raw, int16_t z_raw = 0);
92 
93  virtual void update_touches() = 0;
94 
95  void send_touches_();
96 
97  int16_t normalize_(int16_t val, int16_t min_val, int16_t max_val, bool inverted = false);
98 
99  display::Display *display_{nullptr};
100 
101  int16_t x_raw_min_{0}, x_raw_max_{0}, y_raw_min_{0}, y_raw_max_{0};
102  int16_t display_width_{0}, display_height_{0};
103 
104  uint16_t touch_timeout_{0};
105  bool invert_x_{false}, invert_y_{false}, swap_x_y_{false};
106 
110  std::vector<TouchListener *> touch_listeners_;
111 
112  std::map<uint8_t, TouchPoint> touches_;
114 
115  bool first_touch_{true};
116  bool need_update_{false};
117  bool is_touched_{false};
118  bool was_touched_{false};
119  bool skip_update_{false};
120 };
121 
122 } // namespace touchscreen
123 } // namespace esphome
display::Display * get_display() const
Definition: touchscreen.h:48
void loop()
void set_calibration(int16_t x_min, int16_t x_max, int16_t y_min, int16_t y_max)
Definition: touchscreen.h:55
std::vector< TouchPoint > TouchPoints_t
Definition: touchscreen.h:30
Trigger< TouchPoint, const TouchPoints_t & > touch_trigger_
Definition: touchscreen.h:107
Trigger< const TouchPoints_t & > * get_update_trigger()
Definition: touchscreen.h:67
Trigger< const TouchPoints_t & > update_trigger_
Definition: touchscreen.h:108
mopeka_std_values val[4]
This class simplifies creating components that periodically check a state.
Definition: component.h:283
std::map< uint8_t, TouchPoint > touches_
Definition: touchscreen.h:112
void set_touch_timeout(uint16_t val)
Definition: touchscreen.h:50
optional< TouchPoint > get_touch()
Definition: touchscreen.h:72
virtual void update(const TouchPoints_t &tpoints)
Definition: touchscreen.h:41
uint8_t type
std::vector< TouchListener * > touch_listeners_
Definition: touchscreen.h:110
TouchscreenInterrupt store_
Definition: touchscreen.h:113
void swap(optional< T > &x, optional< T > &y)
Definition: optional.h:210
InterruptType
Definition: gpio.h:40
virtual void touch(TouchPoint tp)
Definition: touchscreen.h:40
void set_mirror_y(bool invert_y)
Definition: touchscreen.h:52
void set_mirror_x(bool invert_x)
Definition: touchscreen.h:51
This is a workaround until we can figure out a way to get the tflite-micro idf component code availab...
Definition: a01nyub.cpp:7
void init()
Definition: core.cpp:80
void register_listener(TouchListener *listener)
Definition: touchscreen.h:70
Trigger< TouchPoint, const TouchPoints_t & > * get_touch_trigger()
Definition: touchscreen.h:66
void set_display(display::Display *display)
Definition: touchscreen.h:47