It means GPIO14 and GPIO27
On schematic it is called T_IRQ and T_CS to tell it apart from Display CS on GPIO5
Just found out, that my display was missing touch. I received the wrong version. No it works like a charm.
I had the same thing here with a touch display for the Raspberry. But there was not “touch”. Either its hard to differentiate for the shop to. Or it is a trick.
hello,
nice work, can you share the esphome code please?
Thanks
Would you mind sharing your complete code? I do also have a 2.8 inch screen and I am just wondering how this works in the “display” section of esphome since on the homepage there is only considered the 2.4 inch screen.
Hey guys, new to the forums and HA. I have been trying to figure out how to use this touch controller with different display pages. The ‘touchscreen’ component has the option for page_id but this component does not, AFAIK. I’m hoping it does and I’m just not doing it right.
So far I have the 3 day weather across the lower portion of the screen and 8 buttons for controlling various functions in my room (lights and TV’s) in a grid at the top. I added different icons for displaying the state of the devices (on/off only). Then the date and time at the bottom.
What I’m trying to now do is add another page with different info and buttons. I figured out how to do it on the display but I cannot get the touch areas to change with the new display page.
color:
- id: red
red: 100%
green: 0%
blue: 0%
- id: my_red
red: 100%
green: 3%
blue: 5%
- id: blue
red: 0%
green: 0%
blue: 100%
- id: green
red: 0%
green: 100%
blue: 0%
- id: yellow
red: 100%
green: 100%
blue: 0%
- id: white
red: 100%
green: 100%
blue: 100%
- id: black
red: 0%
green: 0%
blue: 0%
- id: orange
red: 100%
green: 73%
blue: 0%
- id: purple
green: 0%
red: 80%
blue: 100%
- id: grey
red: 66%
green: 66%
blue: 66%
- id: dkgreen
red: 0%
green: 66%
blue: 0%
- id: redorange
red: 90%
green: 35%
blue: 0%
- id: yellowgreen
red: 52%
green: 99%
blue: 0%
- id: pink
red: 100%
green: 0%
blue: 66%
spi:
clk_pin: GPIO14
mosi_pin: GPIO13
miso_pin: GPIO27
font:
- file: "dosis.ttf"
id: font_e
size: 16
- file: "dosis.ttf"
id: font_s
size: 14
- file: "dosis.ttf"
id: font_b
size: 20
- file: "raleway.ttf"
id: font_c
size: 30
- file: "dosis.ttf"
id: font_d
size: 22
- file: 'mdi.ttf'
id: font_icons
size: 44
glyphs:
- "\U000F0590" # cloudy
- "\U000F0595" # partlycloudy
- "\U000F0591" # fog
- "\U000F0592" # hail
- "\U000F067E" # lightning-rainy
- "\U000F0596" # pouring
- "\U000F0597" # rainy
- "\U000F0F36" # snowy
- "\U000F067F" # snowy-rainy
- "\U000F0599" # sunny
- "\U000F0F33" # light-rain
- "\U000F0F34" # flurries
- "\U000F0598" # light-snow
- "\U000F0F35" # freezing-drizzle
- "\U000F0502" # television off
- "\U000F0594" # star night
- "\U000F1A4C" # night light
- "\U000F1051" # led strip on
- "\U000F18DD" # multiple ceiling lights filled
- "\U000F0335" # light bulb filled
- "\U000F0336" # light bulb outline
- "\U000F12CF" # multiple lights off
- "\U000F18DE" # multiple ceiling lights outline
- "\U000F1253" # multiple bulbs filled
- "\U000F1254" # multiple bulbs outline
- "\U000F1A4B" # led strip off
- "\U000F0503" # television on
- "\U000F0395" # dasboard
sensor:
- platform: homeassistant
id: temphigh
entity_id: sensor.temphigh
internal: True
- platform: homeassistant
id: templow
entity_id: sensor.templow
internal: True
- platform: homeassistant
id: precipprob
entity_id: sensor.precipprob
- platform: homeassistant
id: temphigh1
entity_id: sensor.temphigh1
internal: True
- platform: homeassistant
id: templow1
entity_id: sensor.templow1
internal: True
- platform: homeassistant
id: precipprob1
entity_id: sensor.precipprob1
- platform: homeassistant
id: temphigh2
entity_id: sensor.temphigh2
internal: True
- platform: homeassistant
id: templow2
entity_id: sensor.templow2
internal: True
- platform: homeassistant
id: precipprob2
entity_id: sensor.precipprob2
text_sensor:
- platform: homeassistant
id: bradtv_on
entity_id: binary_sensor.controllerv2_bradtv_on
internal: True
- platform: homeassistant
id: benchdisp_on
entity_id: binary_sensor.controllerv2_benchdisp_on
internal: True
- platform: homeassistant
id: bb1_on
entity_id: binary_sensor.controllerv2_bb1_on
internal: True
- platform: homeassistant
id: uv_on
entity_id: binary_sensor.controllerv2_uv_on
internal: True
- platform: homeassistant
id: bluemood_on
entity_id: binary_sensor.controllerv2_bluemood_on
internal: True
- platform: homeassistant
id: ceiling_on
entity_id: binary_sensor.controllerv2_ceiling_on
internal: True
- platform: homeassistant
id: conditions
entity_id: sensor.conditions
internal: True
- platform: homeassistant
id: conditions1
entity_id: sensor.conditions1
internal: True
- platform: homeassistant
id: conditions2
entity_id: sensor.conditions2
internal: True
xpt2046:
id: touchscreen
cs_pin: GPIO16
irq_pin: GPIO21
update_interval: 50ms
report_interval: 1s
threshold: 400
dimension_x: 240
dimension_y: 320
calibration_x_min: 3890
calibration_x_max: 131
calibration_y_min: 310
calibration_y_max: 3897
output:
- platform: ledc
pin: GPIO22
id: gpio_22_backlight_pwm
light:
- platform: monochromatic
output: gpio_22_backlight_pwm
name: "ILI9341 Display Backlight"
id: back_light
restore_mode: ALWAYS_ON
binary_sensor:
# template sensors
- platform: template
id: keyclick_key0
name: "Brad's TV Click"
- platform: template
id: keyhold_key0
name: "Brad's TV Hold"
- platform: template
id: keyclick_key1
name: "Bench Display Click"
- platform: template
id: keyhold_key1
name: "Bench Display Hold"
- platform: template
id: keyclick_key2
name: "Bed Light Click"
- platform: template
id: keyhold_key2
name: "Bed Light Hold"
- platform: template
id: keyclick_key3
name: "Night Mode Click"
- platform: template
id: keyhold_key3
name: "Night Mode Hold"
- platform: template
id: keyclick_key4
name: "UV Click"
- platform: template
id: keyhold_key4
name: "UV Hold"
- platform: template
id: keyclick_key5
name: "Mood Click"
- platform: template
id: keyhold_key5
name: "Mood Hold"
- platform: template
id: keyclick_key6
name: "Ceiling Lights Click"
- platform: template
id: keyhold_key6
name: "Ceiling Lights Hold"
- platform: template
id: keyclick_key7
name: "Dashboard Click"
- platform: template
id: keyhold_key7
name: "Dashboard Hold"
# key0 definition and tests
- platform: xpt2046
xpt2046_id: touchscreen
id: touch_key0
name: "Brad's TV"
device_class: ''
x_min: 0
x_max: 60
y_min: 0
y_max: 60
internal: True
on_click:
- min_length: 5ms
max_length: 500ms
then:
lambda: |-
id(keyclick_key0).publish_state(true);
delay(500);
id(keyclick_key0).publish_state(false);
- min_length: 1000ms
max_length: 10000ms
then:
lambda: |-
id(keyhold_key0).publish_state(true);
delay(500);
id(keyhold_key0).publish_state(false);
# key1 def and test
- platform: xpt2046
xpt2046_id: touchscreen
id: touch_key1
name: "Bench Display"
device_class: ''
x_min: 60
x_max: 120
y_min: 0
y_max: 60
internal: True
on_click:
- min_length: 5ms
max_length: 500ms
then:
lambda: |-
id(keyclick_key1).publish_state(true);
delay(500);
id(keyclick_key1).publish_state(false);
- min_length: 1000ms
max_length: 10000ms
then:
lambda: |-
id(keyhold_key1).publish_state(true);
delay(500);
id(keyhold_key1).publish_state(false);
# Key2 def and test
- platform: xpt2046
xpt2046_id: touchscreen
id: touch_key2
name: "Bed Light"
device_class: ''
x_min: 120
x_max: 180
y_min: 0
y_max: 60
internal: True
on_click:
- min_length: 5ms
max_length: 500ms
then:
lambda: |-
id(keyclick_key2).publish_state(true);
delay(500);
id(keyclick_key2).publish_state(false);
- min_length: 1000ms
max_length: 10000ms
then:
lambda: |-
id(keyhold_key2).publish_state(true);
delay(500);
id(keyhold_key2).publish_state(false);
# key3 def and tests
- platform: xpt2046
xpt2046_id: touchscreen
id: touch_key3
name: "Night Dimming Timer"
device_class: ''
x_min: 180
x_max: 240
y_min: 0
y_max: 60
internal: True
on_click:
- min_length: 5ms
max_length: 500ms
then:
lambda: |-
id(keyclick_key3).publish_state(true);
delay(500);
id(keyclick_key3).publish_state(false);
- min_length: 1000ms
max_length: 10000ms
then:
lambda: |-
id(keyhold_key3).publish_state(true);
delay(500);
id(keyhold_key3).publish_state(false);
# key4 def and tests
- platform: xpt2046
xpt2046_id: touchscreen
id: touch_key4
name: "UV Light"
device_class: ''
x_min: 0
x_max: 60
y_min: 60
y_max: 120
internal: True
on_click:
- min_length: 5ms
max_length: 500ms
then:
lambda: |-
id(keyclick_key4).publish_state(true);
delay(500);
id(keyclick_key4).publish_state(false);
- min_length: 1000ms
max_length: 10000ms
then:
lambda: |-
id(keyhold_key4).publish_state(true);
delay(500);
id(keyhold_key4).publish_state(false);
# key5 def and tests
- platform: xpt2046
xpt2046_id: touchscreen
id: touch_key5
name: "Blue Mood"
device_class: ''
x_min: 60
x_max: 120
y_min: 60
y_max: 120
internal: True
on_click:
- min_length: 5ms
max_length: 500ms
then:
lambda: |-
id(keyclick_key5).publish_state(true);
delay(500);
id(keyclick_key5).publish_state(false);
- min_length: 1000ms
max_length: 10000ms
then:
lambda: |-
id(keyhold_key5).publish_state(true);
delay(500);
id(keyhold_key5).publish_state(false);
# key6 def and tests
- platform: xpt2046
xpt2046_id: touchscreen
id: touch_key6
name: "Ceiling Lights"
device_class: ''
x_min: 120
x_max: 180
y_min: 60
y_max: 120
internal: True
on_click:
- min_length: 5ms
max_length: 500ms
then:
lambda: |-
id(keyclick_key6).publish_state(true);
delay(500);
id(keyclick_key6).publish_state(false);
- min_length: 1000ms
max_length: 10000ms
then:
lambda: |-
id(keyhold_key6).publish_state(true);
delay(500);
id(keyhold_key6).publish_state(false);
# key7 def and tests
- platform: xpt2046
xpt2046_id: touchscreen
id: touch_key7
name: "All Off"
device_class: ''
x_min: 180
x_max: 240
y_min: 60
y_max: 120
internal: True
on_click:
- min_length: 5ms
max_length: 500ms
then:
lambda: |-
id(keyclick_key7).publish_state(true);
delay(500);
id(keyclick_key7).publish_state(false);
- min_length: 1000ms
max_length: 10000ms
then:
lambda: |-
id(keyhold_key7).publish_state(true);
delay(500);
id(keyhold_key7).publish_state(false);
display:
- platform: ili9341
model: TFT 2.4
cs_pin: GPIO26
dc_pin: GPIO19
led_pin: GPIO22
reset_pin: GPIO25
rotation: 180°
pages:
- id: home_page
lambda: |-
#define xcond 40 // X POS for Day 0 (center)
#define xcond1 120 // X POS for Day 1 (center)
#define xcond2 200 // X POS for Day 2 (center)
#define ycond 142 // Y POS line 1 (center)
#define ycondb 183 // Y POS line 2 (center)
#define ycondc 225 // Y POS line 3 (center)
#define ycondd 277 // Y POS line 4 (center)
#define yconde 252 // Y POS line 3.5 (center)
//color defs
auto black = Color(0, 0, 0);
auto yellow = Color(255, 255, 0);
auto red = Color(255, 0, 0);
auto green = Color(0, 255, 0);
auto blue = Color(0, 0, 255);
auto white = Color(255, 255, 255);
auto orange = Color(255, 170, 0);
auto purple = Color(200, 0, 255);
auto grey = Color(153, 153, 153);
auto ltgblue = Color(93, 241, 238);
auto dkyellow = Color(90, 90, 0);
auto ltblue = Color(134, 164, 218);
auto ltpink = Color(150, 79, 159);
auto dkgreen = Color(0, 175, 0);
auto pink = Color(255, 0, 163);
it.fill(Color::BLACK); // clr screen to black
// draw background
// it.filled_rectangle(0, 0, 240, 120, ltgblue); // top behind buttons (has issue with borders combining)
it.filled_rectangle(0, 294, 240, 26, dkyellow); // bottom behind date
it.filled_rectangle(0, 121, 240, 172, ltblue);
// it.filled_rectangle(160, 121, 80, 172, ltblue);
it.filled_rectangle(80, 121, 80, 172, ltpink);
// drawing of buttons
it.rectangle(0, 0, 59, 59, red);
it.rectangle(60, 0, 59, 59, red);
it.rectangle(120, 0, 59, 59, red);
it.rectangle(180, 0, 59, 59, red);
it.rectangle(0, 60, 59, 59, red);
it.rectangle(60, 60, 59, 59, red);
it.rectangle(120, 60, 59, 59, red);
it.rectangle(180, 60, 59, 59, red);
it.line(1, 59, 238, 59, orange);
it.line(59, 1, 59, 118, orange);
it.line(119, 1, 119, 118, orange);
it.line(179, 1, 179, 118, orange);
it.line(1, 119, 238, 119, orange);
it.line(238, 1, 238, 119, orange);
// drawing of button touches and icons (on or off)
if (id(touch_key0).state) {
it.filled_rectangle(1, 1, 57, 57, orange);
} else {
it.filled_rectangle(1, 1, 57, 57, black);
}
if (id(bradtv_on).state == "on") {
it.printf(30, 30, id(font_icons), id(green), TextAlign::CENTER, "\U000F0503");
} else {
it.printf(30, 30, id(font_icons), id(green), TextAlign::CENTER, "\U000F0502");
}
if (id(touch_key1).state) {
it.filled_rectangle(61, 1, 57, 57, orange);
} else {
it.filled_rectangle(61, 1, 57, 57, black);
}
if (id(benchdisp_on).state == "on") {
it.printf(90, 30, id(font_icons), id(yellow), TextAlign::CENTER, "\U000F0503");
} else {
it.printf(90, 30, id(font_icons), id(yellow), TextAlign::CENTER, "\U000F0502");
}
if (id(touch_key2).state) {
it.filled_rectangle(121, 1, 57, 57, orange);
} else {
it.filled_rectangle(121, 1, 57, 57, black);
}
if (id(bb1_on).state == "on") {
it.printf(150, 30, id(font_icons), id(white), TextAlign::CENTER, "\U000F0335");
} else {
it.printf(150, 30, id(font_icons), id(white), TextAlign::CENTER, "\U000F0336");
}
if (id(touch_key3).state) {
it.filled_rectangle(181, 1, 57, 57, orange);
} else {
it.filled_rectangle(181, 1, 57, 57, black);
it.printf(210, 30, id(font_icons), id(grey), TextAlign::CENTER, "\U000F0594");
}
if (id(touch_key4).state) {
it.filled_rectangle(1, 61, 57, 57, orange);
} else {
it.filled_rectangle(1, 61, 57, 57, black);
}
if (id(uv_on).state == "on") {
it.printf(30, 90, id(font_icons), id(blue), TextAlign::CENTER, "\U000F1051");}
else {
it.printf(30, 90, id(font_icons), id(blue), TextAlign::CENTER, "\U000F1A4B");
}
if (id(touch_key5).state) {
it.filled_rectangle(61, 61, 57, 57, orange);
} else {
it.filled_rectangle(61, 61, 57, 57, black);
}
if (id(bluemood_on).state == "on") {
it.printf(90, 90, id(font_icons), id(blue), TextAlign::CENTER, "\U000F1253");
} else {
it.printf(90, 90, id(font_icons), id(blue), TextAlign::CENTER, "\U000F1254");
}
if (id(touch_key6).state) {
it.filled_rectangle(121, 61, 57, 57, orange);
} else { it.filled_rectangle(121, 61, 57, 57, black);
}
if (id(ceiling_on).state == "on") {
it.printf(150, 90, id(font_icons), id(white), TextAlign::CENTER, "\U000F18DD");
} else {
it.printf(150, 90, id(font_icons), id(white), TextAlign::CENTER, "\U000F18DE");
}
if (id(touch_key7).state) {
it.filled_rectangle(181, 61, 57, 57, orange);
} else {
it.filled_rectangle(181, 61, 57, 57, black);
it.printf(210, 90, id(font_icons), id(pink), TextAlign::CENTER, "\U000F0395");
}
// place temperature on screen
// if (id(outdoor_temp).has_state()) {
// it.printf(4, 64, id(font_b), id(purple), TextAlign::TOP_LEFT, "%.1f°", id(outdoor_temp).state);}
// it.print(4, 94, id(font_s), id(blue), TextAlign::TOP_LEFT, "Outdoor Temperature");
// draw conditions icon at day0
if (id(conditions).state == "rainy") {
it.printf(xcond, ycondc, id(font_icons), id(grey), TextAlign::CENTER, "\U000F0597");}
if (id(conditions).state == "heavy rain") {
it.printf(xcond, ycondc, id(font_icons), id(grey), TextAlign::CENTER, "\U000F0596");}
if (id(conditions).state == "light rain") {
it.printf(xcond, ycondc, id(font_icons), id(grey), TextAlign::CENTER, "\U000F0F33");}
if (id(conditions).state == "drizzle") {
it.printf(xcond, ycondc, id(font_icons), id(grey), TextAlign::CENTER, "\U000F0F33");}
if (id(conditions).state == "thunderstorm") {
it.printf(xcond, ycondc, id(font_icons), id(grey), TextAlign::CENTER, "\U000F067E");}
if (id(conditions).state == "lightning") {
it.printf(xcond, ycondc, id(font_icons), id(grey), TextAlign::CENTER, "\U000F067E");}
if (id(conditions).state == "clear") {
it.printf(xcond, ycondc, id(font_icons), id(yellow), TextAlign::CENTER, "\U000F0599");}
if (id(conditions).state == "mostly clear") {
it.printf(xcond, ycondc, id(font_icons), id(yellow), TextAlign::CENTER, "\U000F0599");}
if (id(conditions).state == "partly cloudy") {
it.printf(xcond, ycondc, id(font_icons), id(grey), TextAlign::CENTER, "\U000F0595");}
if (id(conditions).state == "mostly cloudy") {
it.printf(xcond, ycondc, id(font_icons), id(grey), TextAlign::CENTER, "\U000F0595");}
if (id(conditions).state == "cloudy") {
it.printf(xcond, ycondc, id(font_icons), id(grey), TextAlign::CENTER, "\U000F0590");}
if (id(conditions).state == "light fog") {
it.printf(xcond, ycondc, id(font_icons), id(grey), TextAlign::CENTER, "\U000F0591");}
if (id(conditions).state == "fog") {
it.printf(xcond, ycondc, id(font_icons), id(grey), TextAlign::CENTER, "\U000F0591");}
if (id(conditions).state == "flurries") {
it.printf(xcond, ycondc, id(font_icons), id(blue), TextAlign::CENTER, "\U000F0F34");}
if (id(conditions).state == "light snow") {
it.printf(xcond, ycondc, id(font_icons), id(blue), TextAlign::CENTER, "\U000F0598");}
if (id(conditions).state == "snow") {
it.printf(xcond, ycondc, id(font_icons), id(blue), TextAlign::CENTER, "\U000F0F36");}
if (id(conditions).state == "heavy snow") {
it.printf(xcond, ycondc, id(font_icons), id(blue), TextAlign::CENTER, "\U000F0F36");}
if (id(conditions).state == "freezing drizzle") {
it.printf(xcond, ycondc, id(font_icons), id(blue), TextAlign::CENTER, "\U000F0F35");}
if (id(conditions).state == "light freezing drizzle") {
it.printf(xcond, ycond, id(font_icons), id(blue), TextAlign::CENTER, "\U000F0F35");}
if (id(conditions).state == "freezing rain") {
it.printf(xcond, ycondc, id(font_icons), id(blue), TextAlign::CENTER, "\U000F067F");}
if (id(conditions).state == "heavy freezing rain") {
it.printf(xcond, ycondc, id(font_icons), id(blue), TextAlign::CENTER, "\U000F067F");}
if (id(conditions).state == "ice pellets") {
it.printf(xcond, ycondc, id(font_icons), id(blue), TextAlign::CENTER, "\U000F0592");}
if (id(conditions).state == "light ice pellets") {
it.printf(xcond, ycondc, id(font_icons), id(blue), TextAlign::CENTER, "\U000F0592");}
if (id(conditions).state == "heavy ice pellets") {
it.printf(xcond, ycondc, id(font_icons), id(blue), TextAlign::CENTER, "\U000F0592");}
if (id(conditions).state == "pouring") {
it.printf(xcond, ycondc, id(font_icons), id(grey), TextAlign::CENTER, "\U000F0596");}
if (id(conditions).state == "sunny") {
it.printf(xcond, ycondc, id(font_icons), id(yellow), TextAlign::CENTER, "\U000F0599");}
// draw conditions icon at day1
if (id(conditions1).state == "rainy") {
it.printf(xcond1, ycondc, id(font_icons), id(grey), TextAlign::CENTER, "\U000F0597");}
if (id(conditions1).state == "heavy rain") {
it.printf(xcond1, ycondc, id(font_icons), id(grey), TextAlign::CENTER, "\U000F0596");}
if (id(conditions1).state == "light rain") {
it.printf(xcond1, ycondc, id(font_icons), id(grey), TextAlign::CENTER, "\U000F0F33");}
if (id(conditions1).state == "drizzle") {
it.printf(xcond1, ycondc, id(font_icons), id(grey), TextAlign::CENTER, "\U000F0F33");}
if (id(conditions1).state == "thunderstorm") {
it.printf(xcond1, ycondc, id(font_icons), id(grey), TextAlign::CENTER, "\U000F067E");}
if (id(conditions1).state == "clear") {
it.printf(xcond1, ycondc, id(font_icons), id(yellow), TextAlign::CENTER, "\U000F0599");}
if (id(conditions1).state == "lightning") {
it.printf(xcond1, ycondc, id(font_icons), id(grey), TextAlign::CENTER, "\U000F067E");}
if (id(conditions1).state == "mostly clear") {
it.printf(xcond1, ycondc, id(font_icons), id(yellow), TextAlign::CENTER, "\U000F0599");}
if (id(conditions1).state == "partly cloudy") {
it.printf(xcond1, ycondc, id(font_icons), id(grey), TextAlign::CENTER, "\U000F0595");}
if (id(conditions1).state == "mostly cloudy") {
it.printf(xcond1, ycondc, id(font_icons), id(grey), TextAlign::CENTER, "\U000F0595");}
if (id(conditions1).state == "cloudy") {
it.printf(xcond1, ycondc, id(font_icons), id(grey), TextAlign::CENTER, "\U000F0590");}
if (id(conditions1).state == "light fog") {
it.printf(xcond1, ycondc, id(font_icons), id(grey), TextAlign::CENTER, "\U000F0591");}
if (id(conditions1).state == "fog") {
it.printf(xcond1, ycondc, id(font_icons), id(grey), TextAlign::CENTER, "\U000F0591");}
if (id(conditions1).state == "flurries") {
it.printf(xcond1, ycondc, id(font_icons), id(blue), TextAlign::CENTER, "\U000F0F34");}
if (id(conditions1).state == "light snow") {
it.printf(xcond1, ycondc, id(font_icons), id(blue), TextAlign::CENTER, "\U000F0598");}
if (id(conditions1).state == "snow") {
it.printf(xcond1, ycondc, id(font_icons), id(blue), TextAlign::CENTER, "\U000F0F36");}
if (id(conditions1).state == "heavy snow") {
it.printf(xcond1, ycondc, id(font_icons), id(blue), TextAlign::CENTER, "\U000F0F36");}
if (id(conditions1).state == "freezing drizzle") {
it.printf(xcond1, ycondc, id(font_icons), id(blue), TextAlign::CENTER, "\U000F0F35");}
if (id(conditions1).state == "light freezing drizzle") {
it.printf(xcond1, ycond, id(font_icons), id(blue), TextAlign::CENTER, "\U000F0F35");}
if (id(conditions1).state == "freezing rain") {
it.printf(xcond1, ycondc, id(font_icons), id(blue), TextAlign::CENTER, "\U000F067F");}
if (id(conditions1).state == "heavy freezing rain") {
it.printf(xcond1, ycondc, id(font_icons), id(blue), TextAlign::CENTER, "\U000F067F");}
if (id(conditions1).state == "ice pellets") {
it.printf(xcond1, ycondc, id(font_icons), id(blue), TextAlign::CENTER, "\U000F0592");}
if (id(conditions1).state == "light ice pellets") {
it.printf(xcond1, ycondc, id(font_icons), id(blue), TextAlign::CENTER, "\U000F0592");}
if (id(conditions1).state == "heavy ice pellets") {
it.printf(xcond1, ycondc, id(font_icons), id(blue), TextAlign::CENTER, "\U000F0592");}
if (id(conditions1).state == "pouring") {
it.printf(xcond1, ycondc, id(font_icons), id(grey), TextAlign::CENTER, "\U000F0596");}
if (id(conditions1).state == "sunny") {
it.printf(xcond1, ycondc, id(font_icons), id(yellow), TextAlign::CENTER, "\U000F0599");}
// draw conditions icon at day2
if (id(conditions2).state == "rainy") {
it.printf(xcond2, ycondc, id(font_icons), id(grey), TextAlign::CENTER, "\U000F0597");}
if (id(conditions2).state == "heavy rain") {
it.printf(xcond2, ycondc, id(font_icons), id(grey), TextAlign::CENTER, "\U000F0596");}
if (id(conditions2).state == "light rain") {
it.printf(xcond2, ycondc, id(font_icons), id(grey), TextAlign::CENTER, "\U000F0F33");}
if (id(conditions2).state == "drizzle") {
it.printf(xcond2, ycondc, id(font_icons), id(grey), TextAlign::CENTER, "\U000F0F33");}
if (id(conditions2).state == "thunderstorm") {
it.printf(xcond2, ycondc, id(font_icons), id(grey), TextAlign::CENTER, "\U000F067E");}
if (id(conditions2).state == "clear") {
it.printf(xcond2, ycondc, id(font_icons), id(yellow), TextAlign::CENTER, "\U000F0599");}
if (id(conditions2).state == "mostly clear") {
it.printf(xcond2, ycondc, id(font_icons), id(yellow), TextAlign::CENTER, "\U000F0599");}
if (id(conditions2).state == "partly cloudy") {
it.printf(xcond2, ycondc, id(font_icons), id(grey), TextAlign::CENTER, "\U000F0595");}
if (id(conditions2).state == "mostly cloudy") {
it.printf(xcond2, ycondc, id(font_icons), id(grey), TextAlign::CENTER, "\U000F0595");}
if (id(conditions2).state == "lightning") {
it.printf(xcond2, ycondc, id(font_icons), id(grey), TextAlign::CENTER, "\U000F067E");}
if (id(conditions2).state == "cloudy") {
it.printf(xcond2, ycondc, id(font_icons), id(grey), TextAlign::CENTER, "\U000F0590");}
if (id(conditions2).state == "light fog") {
it.printf(xcond2, ycondc, id(font_icons), id(grey), TextAlign::CENTER, "\U000F0591");}
if (id(conditions2).state == "fog") {
it.printf(xcond2, ycondc, id(font_icons), id(grey), TextAlign::CENTER, "\U000F0591");}
if (id(conditions2).state == "flurries") {
it.printf(xcond2, ycondc, id(font_icons), id(blue), TextAlign::CENTER, "\U000F0F34");}
if (id(conditions2).state == "light snow") {
it.printf(xcond2, ycondc, id(font_icons), id(blue), TextAlign::CENTER, "\U000F0598");}
if (id(conditions2).state == "snow") {
it.printf(xcond2, ycondc, id(font_icons), id(blue), TextAlign::CENTER, "\U000F0F36");}
if (id(conditions2).state == "heavy snow") {
it.printf(xcond2, ycondc, id(font_icons), id(blue), TextAlign::CENTER, "\U000F0F36");}
if (id(conditions2).state == "freezing drizzle") {
it.printf(xcond2, ycondc, id(font_icons), id(blue), TextAlign::CENTER, "\U000F0F35");}
if (id(conditions2).state == "light freezing drizzle") {
it.printf(xcond2, ycond, id(font_icons), id(blue), TextAlign::CENTER, "\U000F0F35");}
if (id(conditions2).state == "freezing rain") {
it.printf(xcond2, ycondc, id(font_icons), id(blue), TextAlign::CENTER, "\U000F067F");}
if (id(conditions2).state == "heavy freezing rain") {
it.printf(xcond2, ycondc, id(font_icons), id(blue), TextAlign::CENTER, "\U000F067F");}
if (id(conditions2).state == "ice pellets") {
it.printf(xcond2, ycondc, id(font_icons), id(blue), TextAlign::CENTER, "\U000F0592");}
if (id(conditions2).state == "light ice pellets") {
it.printf(xcond2, ycondc, id(font_icons), id(blue), TextAlign::CENTER, "\U000F0592");}
if (id(conditions2).state == "heavy ice pellets") {
it.printf(xcond2, ycondc, id(font_icons), id(blue), TextAlign::CENTER, "\U000F0592");}
if (id(conditions2).state == "pouring") {
it.printf(xcond2, ycondc, id(font_icons), id(grey), TextAlign::CENTER, "\U000F0596");}
if (id(conditions2).state == "sunny") {
it.printf(xcond2, ycondc, id(font_icons), id(yellow), TextAlign::CENTER, "\U000F0599");}
// print 'precip' above the forcasted precip number
it.print(xcond, yconde, id(font_e), id(yellowgreen), TextAlign::CENTER, "Precip");
it.print(xcond1, yconde, id(font_e), id(yellowgreen), TextAlign::CENTER, "Precip");
it.print(xcond2, yconde, id(font_e), id(yellowgreen), TextAlign::CENTER, "Precip");
// print forcast, high, low and precip day0
it.printf(xcond, ycond, id(font_c), id(my_red), TextAlign::CENTER, "%.0f°", id(temphigh).state);
it.printf(xcond, ycondb, id(font_c), id(blue), TextAlign::CENTER, "%.0f°", id(templow).state);
it.printf(xcond, ycondd, id(font_c), id(yellowgreen), TextAlign::CENTER, "%.2f\"", id(precipprob).state);
// print forcast, high, low and precip day1
it.printf(xcond1, ycond, id(font_c), id(my_red), TextAlign::CENTER, "%.0f°", id(temphigh1).state);
it.printf(xcond1, ycondb, id(font_c), id(blue), TextAlign::CENTER, "%.0f°", id(templow1).state);
it.printf(xcond1, ycondd, id(font_c), id(yellowgreen), TextAlign::CENTER, "%.2f\"", id(precipprob1).state);
// print forcast, high, low and precip day2
it.printf(xcond2, ycond, id(font_c), id(my_red), TextAlign::CENTER, "%.0f°", id(temphigh2).state);
it.printf(xcond2, ycondb, id(font_c), id(blue), TextAlign::CENTER, "%.0f°", id(templow2).state);
it.printf(xcond2, ycondd, id(font_c), id(yellowgreen), TextAlign::CENTER, "%.2f\"", id(precipprob2).state);
// Date
it.strftime(120, 315, id(font_d), id(redorange), TextAlign::BASELINE_CENTER, "%c", id(ntp).now());
It wouldn’t let me add the image to previous post. Apparently my S22Ultra doesn’t have enough memory … … …
Hi Brad,
this is the display part of a yaml:
display:
- platform: ili9341
model: TFT 2.4
id: touch_display
cs_pin: GPIO5
dc_pin: GPIO4
#led_pin:
# number: 15
# inverted: true
reset_pin: GPIO22
pages:
- id: page1
lambda: |-
it.print( 0, 80, id(font4), id(my_blue), TextAlign::TOP_LEFT, "\U000F095F");
if (id(extended_color_light_3).state) {
it.image( 80, 80, id(steckdose_on));
} else {
it.image( 80, 80, id(steckdose));
}
// 3 x 4 grid
it.line( 80, 0, 80, 319);
it.line(160, 0, 160, 319);
it.line( 0, 80, 239, 80);
it.line( 0, 160, 239, 160);
it.line( 0, 240, 239, 240);
- id: page2
lambda: |-
// 3 x 4 grid
// it.line( 80, 0, 80, 319);
// it.line(160, 0, 160, 319);
// it.line( 0, 80, 239, 80);
it.line( 0, 160, 239, 160);
it.printf(120, 240, id(font2), TextAlign::BASELINE_CENTER, "%s", id(my_text).state.c_str());
// it.line( 0, 240, 239, 240);
// it.print(10, 0, id(font1), id(my_red), TextAlign::TOP_LEFT, "Hello World!");
// it.print(10, 80, id(font2), id(my_blue), TextAlign::TOP_LEFT, "Hello World!");
// it.print(10, 160, id(font3), id(my_yellow), TextAlign::TOP_LEFT, "Hello World!");
Then touch actions:
binary_sensor:
// here al light_3 is toggled
- platform: xpt2046
xpt2046_id: touchscreen
id: touch_key4
x_min: 80
x_max: 159
y_min: 80
y_max: 159
on_state:
if:
condition:
binary_sensor.is_on: touch_key4
then:
- homeassistant.service:
service: light.toggle
data:
entity_id: light.extended_color_light_3
// here the pages are turned, touch_key11 ist is the last square of 12
// the screen is divided in to 3 x 4 squares
- platform: xpt2046
xpt2046_id: touchscreen
id: touch_key11
x_min: 160
x_max: 239
y_min: 240
y_max: 319
on_state:
if:
condition:
binary_sensor.is_on: touch_key11
then:
- display.page.show_next: touch_display
But in this case the touch action is always triggered. No matter, what page is on.
To do it right, i have to ask before, which page is displayed? An then trigger the right action according the actual page.
Ich sende später ein Beispiel.
hi i can’t figure out how to connect the TFT and the esp32. Can someone help me?
to AZ-Delivery ESP32 DEV KitC V2.
How many wire i would connect?
Hi Giuian, it is difficult to help. I could not find detailled datasheet for this display. It is designed for arduino. Maybe the arduino programm exsample helps you out. You can compare the names of pins and translate it to the esp. The ardunio programm should run also on your esp.
I got only different touch displays.
Sorry,
Christian
Thanks Christian
i have the same screen and there is not mutch information about it. i will buy a other one.
Resurrecting my AZ-Touch project, but I cannot find any code examples for the initial config of the 2.8 screen? See below for the 2.4 screen as provided by Christian…
display:
- platform: ili9341
model: TFT 2.4
id: touch_display
cs_pin: GPIO5
dc_pin: GPIO4
#led_pin:
# number: 15
# inverted: true
reset_pin: GPIO22
pages:
- id: page1
lambda: |-
it.print( 0, 80, id(font4), id(my_blue), TextAlign::TOP_LEFT, "\U000F095F");
if (id(extended_color_light_3).state) {
it.image( 80, 80, id(steckdose_on));
} else {
it.image( 80, 80, id(steckdose));
}
// 3 x 4 grid
it.line( 80, 0, 80, 319);
it.line(160, 0, 160, 319);
it.line( 0, 80, 239, 80);
it.line( 0, 160, 239, 160);
it.line( 0, 240, 239, 240);
- id: page2
lambda: |-
// 3 x 4 grid
// it.line( 80, 0, 80, 319);
// it.line(160, 0, 160, 319);
// it.line( 0, 80, 239, 80);
it.line( 0, 160, 239, 160);
it.printf(120, 240, id(font2), TextAlign::BASELINE_CENTER, "%s", id(my_text).state.c_str());
// it.line( 0, 240, 239, 240);
// it.print(10, 0, id(font1), id(my_red), TextAlign::TOP_LEFT, "Hello World!");
// it.print(10, 80, id(font2), id(my_blue), TextAlign::TOP_LEFT, "Hello World!");
// it.print(10, 160, id(font3), id(my_yellow), TextAlign::TOP_LEFT, "Hello World!");
Would very much appreciate any code examples similar to above that relate to setting up the AZ-Touch 2.8 screen.
I also got one with 2.8". I will check this.
Hello Gregonic, you can use the model tft 2.4 as well. They both have resolution of 320 x 240. On the 2.8" display it looks the same, only little bit bigger.
display:
- platform: ili9xxx
model: TFT 2.4
id: touch_display
cs_pin: GPIO5
dc_pin: GPIO4
#led_pin:
# number: 15
# inverted: true
reset_pin: GPIO22
GPIOs are for AZ-Touchmod ok.
Put this in your yaml. Otherwise the log gets spammed.
# Enable logging
logger:
level: DEBUG
logs:
component: ERROR
To explore your touch-coordinates use this:
touchscreen:
platform: xpt2046
id: my_touchscreen
cs_pin: 14
interrupt_pin: 27
update_interval: 50ms
report_interval: 1s
threshold: 400
swap_x_y: false
on_touch:
- lambda: |-
ESP_LOGI("cal", "x=%d, y=%d, x_raw=%d, y_raw=%0d",
id(my_touchscreen).x,
id(my_touchscreen).y,
id(my_touchscreen).x_raw,
id(my_touchscreen).y_raw
);
Touch with the pencil all over the place an watch the log at the same time.
The touch-areas i have defined like this:
binary_sensor:
- platform: touchscreen
id: touch_key0
x_min: 0
x_max: 79
y_min: 0
y_max: 79
on_press:
- logger.log: "Key0 was touched"
- platform: touchscreen
id: touch_key1
x_min: 80
x_max: 159
y_min: 0
y_max: 79
on_state:
- lambda: 'ESP_LOGI("main", "key1: %s", (x ? "touch" : "release"));'
Or like this to turn pages:
- platform: touchscreen
id: touch_key11
x_min: 160
x_max: 239
y_min: 240
y_max: 319
on_state:
if:
condition:
binary_sensor.is_on: touch_key11
then:
- display.page.show_next: touch_display
In that case you must test, which page is displayed, to select the right reaction for that touch area action!
I have added a remote reciver and a DHT-Sensor.
Hi Christian, thank you. I’ve started implementing the setup. Here’s my code…
esphome:
name: esp6-touch
friendly_name: esp6-touch
esp32:
board: nodemcu-32s
framework:
type: arduino
# Enable logging
logger:
level: DEBUG
logs:
component: ERROR
# Enable Home Assistant API
api:
encryption:
key: "<REDACTED>="
# component buzzer
rtttl:
output: rtttl_out
on_finished_playback:
- logger.log: 'Song ended!'
ota:
password: "<REDACTED>"
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
# Enable fallback hotspot (captive portal) in case wifi connection fails
ap:
ssid: "Esp6-Touch"
password: "<REDACTED"
captive_portal:
# Setup the screen
spi:
clk_pin: GPIO18
mosi_pin: GPIO23
miso_pin: GPIO19
output:
# buzzer
- platform: ledc
pin: GPIO21
id: rtttl_out
# backlight
- platform: ledc
pin: GPIO15
id: gpio_15_backlight_pwm
inverted: true
sensor:
- platform: dht
pin: GPIO25
temperature:
name: "Touch Temperature"
humidity:
name: "Touch Humidity"
update_interval: 60s
display:
- platform: ili9xxx
model: TFT 2.4
id: touch_display
cs_pin: GPIO5
dc_pin: GPIO4
#led_pin:
# number: 15
# inverted: true
reset_pin: GPIO22
lambda: |-
it.image(0, 0, id(bg_image));
image:
- file: "images/background.jpeg"
id: bg_image
# resize: 200x200
type: RGB24
touchscreen:
platform: xpt2046
id: my_touchscreen
cs_pin: GPIO14
interrupt_pin: GPIO27
update_interval: 50ms
report_interval: 1s
threshold: 400
swap_x_y: false
on_touch:
- lambda: |-
ESP_LOGI("cal", "x=%d, y=%d, x_raw=%d, y_raw=%0d",
id(my_touchscreen).x,
id(my_touchscreen).y,
id(my_touchscreen).x_raw,
id(my_touchscreen).y_raw
);
The setup I would like is to have an image displaying until someone touches the screen. After the screen is touched I want to present a menu of options.
Unfortunately the code above presents the picture like below… I’ve tried a few things but no success?
Thank you for a great write up!
I am running a 2.8 screen with lots of real estate and would like to have different touch actions on different pages. If my German doesn’t fool me, you wrote that you would get examples later.
Would it be possible to give an example on how you determine on which page the touch action is executed?
Many thanks!
Alles gute
Rob
Hi Rob! It’s true. I remeber
If you want different actions depending on which page is displayed.
You first have to test which page is on the display. And then take the correct action.
As described here.
In my example:
display:
- platform: ili9xxx
model: TFT 2.4
id: touch_display
cs_pin: GPIO5
dc_pin: GPIO4
reset_pin: GPIO22
Define pages:
pages:
- id: page1
lambda: |-
it.print( 0, 80, id(font4), id(my_blue), TextAlign::TOP_LEFT, "\U000F095F");
if (id(extended_color_light_3).state) {
it.image( 80, 80, id(steckdose_on));
} else {
it.image( 80, 80, id(steckdose));
}
- id: page2
lambda: |-
it.printf( 120, 100, id(font2), TextAlign::BASELINE_CENTER, "%s", id(my_text).state.c_str());
it.line( 0, 160, 239, 160);
it.printf( 120, 200, id(font2), TextAlign::BASELINE_CENTER, "%s", id(media_artist).state.c_str());
it.printf( 120, 240, id(font1), TextAlign::BASELINE_CENTER, "%s", id(media_title).state.c_str());
Define touchscreen:
touchscreen:
platform: xpt2046
id: my_touchscreen
cs_pin: 14
interrupt_pin: 27
update_interval: 50ms
threshold: 400
calibration_x_min: 3860
calibration_x_max: 280
calibration_y_min: 340
calibration_y_max: 3860
Define touch areas and actions.
Here touch area 5 on my 3 x 4 grid in portrait alignment.
binary_sensor:
- platform: touchscreen
id: touch_key5
x_min: 160
x_max: 239
y_min: 80
y_max: 159
on_state:
if:
condition:
binary_sensor.is_on: touch_key5
then:
- if:
condition:
display.is_displaying_page:
id: touch_display
page_id: page2
then:
- homeassistant.service:
service: input_select.select_next
data:
entity_id: input_select.scenes_bedroom
… is only executet, if page2 is displayed.
I hope, it helpes!