It looks interesting, and I’m sure will have a purpose (the RFID feature is very interesting), but for my use cases not really. It is roughly double the price, is over 3cm thick vs 1cm - so may require cutting a hole into the wall otherwise it will stick out quite a bit, plus the orange colour would not be looked at kindly by my wife!
Excellent! With that I now have a working touch screen. As you noted, it doesn’t support everything, but the basics are definitely working. The following code shows the ability to swipe between screens, as well as detect a single touch - so this could now be used as the basis for, for example, swiping between screens and toggling on/off different lights etc. It also detects swipe up/down (so that could be used to dim/brighten lights or change a thermostat) as well as a long touch - I haven’t added examples for those in the code, but it’s just a case of adding those terms in.
update actually, I will update the code below if there are any major changes I think might be of use. If you want access some sample image files, I have uploaded them here. Be aware that you are probably much better off searching one of the many image libraries out there for the images you actually want, and then use something like gimp to modify them so that they are the correct size for where you want to use them on the screen.
# V1.0 - 1/7/2024
# Compiled and tested on esphome 2024.6.4 and HA 2024.6.4
#
# There are a lot of comments in this code - some are to help guide when using
# Some code is commented out - those are works in progress and in general can be ignored
#
# PLEASE NOTE:
#
# Try this with any other versions and it might work, but otherwise "you are in a maze of twisty little passages, all alike" so good luck in your future endeavours.
# This is because an external component is still required to support the touch controller, and as that is not always updated when an
# update to esphome or home assistant is released, you may see errors when compiling. In short, if you see compilation errors, always
# check to see if you are running versions of esphome and home assistant that are the same as noted above. If you are running a newer
# version then check the community discussions for resolution
#
# To use, create a config in esphome with this code. Change or remove references to sensors as required to suit/match your environment.
# This code refers to external image files - feel free to remove and/or change. For legal reasons I cannot share these.
# Pay close attention to the "substitutions" section and update to suit you
# Then compile and save the file locally
# Then go to https://web.esphome.io/ and connect the device to the pc and prepare it for first use
# Then upload the saved binary to the device
# Once installed, you will be able to use OTA updates
# Notes - feel free to remove
# - it is a single core processor running at up to 160Mhz, 400KB SRAM, 348KB ROM, 4MB flash
# - display resolution is 240*240 IPS
# - battery connector is a JST 1.25 2P. Note that this is for a 3V lithium battery (3.3V would be fine. It does have
# over current protection but even so I would avoid 3.7V or greater just in case).
# - Can power direct through the jst with DC but you need to initially provide power via USB
# before it recognises that there is power coming in via the battery port
# - it has a tiny click button called "switch" - unclear how to use. Have seen some images that refer to it as on/off
# but it does not seem to do that. The circuit diags seem to imply it is IO8 which is used for the screen so maybe
# it could be used to toggle the screen on or off. It is deeply recessed and so tiny I doubt many people would use it anyhow.
# - it has two larger buttons for reset and boot
# - I/O interface connector is a SH 1.0 4P (GND, +3.3V, TX, RX) so UART - could for example use with
# DS18B20 temp sensor (to measure the room temp)
# URM07 distance sensor (to trigger the screen to wake up as someone approaches)
# other options may include the following, but be aware many require more than 3V to be reliable, so may require separate power
# SEN0395 or LD2410 mmWave for presense detection
# MH-Z19C to measure CO2
# SM300D2 to measure all sorts of things (CO2, formaldehyde, TVOC, laser PM2.5, PM10, temperature and humidity)
# - It has bluetooth, and can function as a ble tracker but memory and processor constraints means that it can
# have issues (eg random rebooting) doing that AND running the display at the same time
# - processor is weak and memory low, so do not expect it to be able to handle animation too well
# - specs say power consumption is 100mA - but varies depending on load and if display is active
# - screen is 240 pixels wide, so radius is 120 pixels, circumference 754 pixels
# a square would have sides 170 pixels to just fit - maybe 169 to be safe
# adjust images to suit. Keep in mind that images will eat away the limited memory on the device.
substitutions:
devicename: wallwatch07
friendname: WallWatch07
location: guest
# Change the timezone to suit your location, or even just remove it - it will likely be picked up automatically
timez: Australia/Melbourne
board: esp32-c3-devkitm-1
# Display state on initial start
# Note that the screensaver only starts after the first touch of the display
# Change to ALWAYS_OFF if want the screen to be off after booting, ALWAYS_ON if want it on at start eg for initial troubleshooting
screenstart: ALWAYS_OFF
# Timeout for the screen
screensaver: 10 min
#GPIO pins for the LCD screen
repin: GPIO1
dcpin: GPIO2
# Note - you may see an error on compilation "WARNING GPIO2 is a Strapping PIN and should be avoided" - ignore this as you have no choice
# This error message may be removed via the "ignore_strapping_warning" option for the screen driver
bkpin: GPIO3
clpin: GPIO6
mopin: GPIO7
cspin: GPIO10
# GPIO pins for the touch screen
sdapin: GPIO4
sclpin: GPIO5
intpin: GPIO8
esphome:
name: $devicename
friendly_name: $friendname
esp32:
board: $board
framework:
type: arduino
# Enable logging
# Change to avoid "Components should block for at most 20-30ms" warning messages in the log - an issue since 2023.7.0
# Not really a breaking change - it's an issue I suspect due to the device being slow and this error previously
# simply not being reported
logger:
level: DEBUG #makes uart stream available in esphome logstream
logs:
component: ERROR
#Turn off UART logging over RX/TX
baud_rate: 0
#uart:
# rx_pin: GPIO20
# tx_pin: GPIO21
# baud_rate: 9600
# id: uart_bus
# Enable Home Assistant API
api:
encryption:
key: !secret esphome_encryption_key
ota:
password: !secret ota_password
platform: esphome
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
# Enable fallback hotspot (captive portal) in case wifi connection fails
ap:
ssid: "$devicename Fallback Hotspot"
password: !secret fallback_password
captive_portal:
time:
- platform: homeassistant
# Feel free to remove the timezone reference - it will probably work it out automatically
timezone: "$timez"
id: esptime
# Amazingly, ble_tracker now seems to work
# Things to note if using it:
# 1. Make sure you use https://web.esphome.io/ to wipe the device first and then upload the new image
# Do not use OTA after enabling esp32_ble_tracker: as it needs to change the partition to support the code
# 2. Comment out "#eight_bit_color: false" in the display section. Drawback is screen redraw is slower and colours less vibrant.
# 3. Don't be surprised if the thing locks ups or reboots randomly - this is bleeding edge
# 4. Refer to https://esphome.io/components/binary_sensor/ble_presence.html for more info
#esp32_ble_tracker:
#binary_sensor:
# # Presence based on MAC address
# - platform: ble_presence
# mac_address: AC:37:43:77:5F:4C
# name: "ESP32 BLE Tracker Google Home Mini"
# min_rssi: -80dB
# # Presence based on BLE Service UUID
# - platform: ble_presence
# service_uuid: '11aa'
# name: "ESP32 BLE Tracker Test Service 16 bit"
# # Presence based on iBeacon UUID
# - platform: ble_presence
# ibeacon_uuid: '68586f1e-89c2-11eb-8dcd-0242ac130003'
# name: "ESP32 BLE Tracker Test Service iBeacon"
select:
- platform: template
name: Thermostat Mode
id: mode
options:
- "off"
- "cool"
- "heat"
initial_option: "off"
optimistic: true
# - select.next: mode
# set_action:
# - logger.log:
# format: "Chosen option: %s"
# args: ["x.c_str()"]
sensor:
- platform: uptime
name: "$devicename Uptime"
- platform: wifi_signal
name: "$devicename WiFi Signal"
update_interval: 60s
- platform: homeassistant
id: outdoor_temperature
entity_id: sensor.gw1000_v1_7_6_outdoor_temperature
- platform: homeassistant
id: max_temperature
entity_id: sensor.brighton_east_temp_max_0
- platform: homeassistant
id: min_temperature
entity_id: sensor.brighton_east_temp_min_1
- platform: homeassistant
id: thermostat_temperature
entity_id: climate.thermostat_sitting_2
attribute: temperature
- platform: homeassistant
id: room_temperature
entity_id: sensor.lumi_lumi_sens_temperature_2
- platform: template
name: $devicename free memory
lambda: return heap_caps_get_free_size(MALLOC_CAP_INTERNAL);
icon: "mdi:memory"
entity_category: diagnostic
state_class: measurement
unit_of_measurement: "b"
update_interval: 60s
external_components:
- source: github://GadgetFactory/[email protected]
# Still need this external driver to support the touch screen
# Supported added via https://github.com/esphome/esphome/pull/5941
# Currently testing
spi:
mosi_pin: $mopin
clk_pin: $clpin
# Don't use software - makes it crawl
# force_sw: True
#mosi = Master Out Slave In
#miso = Master In Slave Out or fermented bean paste. In this case, most likely the former rather than the latter. Doesn't matter as not used.
i2c:
sda: $sdapin
scl: $sclpin
#Following helped someone get rid of the "Components should block" error messages but didn't for me
#frequency: 400kHz
number:
# This is a binary off or on to toggle the virtual thermostat states between off or heat or cool
# Where 0 is off and 1 is heat and 2 is cool
# There is now a 'climate.toggle' option but for me I don't want to cycle through all the options
- platform: template
optimistic: true
name: "$devicename therm state"
id: thermostat_state
min_value: 0
max_value: 2
# on boot, use the value it had if possible
restore_value: True
# if can't restore the value, then make it 0 ie off
initial_value: 0
update_interval: 1s
step: 1
#Create a script to turn the screen off after a set period
script:
- id: screentime
mode: restart
then:
- light.turn_on: back_light
- delay: $screensaver
- light.turn_off: back_light
# - platform: CST816S_touchscreen
text_sensor:
# - platform: ble_scanner
# name: "BLE Devices Scanner"
- platform: homeassistant
id: light_state
entity_id: light.guest_lamp
- platform: CST816S_touchscreen
id: my_touch_screen
on_value:
then:
- script.execute: screentime # See script to set timeout delay
- if:
condition:
text_sensor.state:
id: my_touch_screen
state: 'SWIPE RIGHT'
then:
- display.page.show_next: watchface
- component.update: watchface
- logger.log: "Swiped right, go to next page"
- if:
condition:
text_sensor.state:
id: my_touch_screen
state: 'SWIPE LEFT'
then:
- display.page.show_previous: watchface
- delay: 0.5s
- component.update: watchface
- logger.log: "Swiped left, go back a page"
- if:
condition:
and:
- text_sensor.state:
id: my_touch_screen
state: 'LONG PRESS'
- display.is_displaying_page: page1
then:
- logger.log: "Long press on page1"
# - select.next: mode
# - homeassistant.service:
# service: climate.set_hvac_mode
# data:
# hvac_mode: "off"
# target:
# entity_id:
# - climate.thermostat_sitting_2
# Note that this is changing a sensor value in HA, and and automation is then acting on that to then change the
# thermostat state eg from cooling to off
- number.decrement: thermostat_state
- delay: 0.5s
- component.update: watchface
- if:
condition:
and:
- text_sensor.state:
id: my_touch_screen
state: 'SWIPE UP'
- display.is_displaying_page: page1
then:
- logger.log: "Swiped up on page1"
#Note that this is the reverse of what you might expect
# This is directly reducing the thermostat set temperature in HA by one degree
- homeassistant.service:
service: climate.set_temperature
data_template:
entity_id: climate.thermostat_sitting_2
temperature: '{{(state_attr(''climate.thermostat_sitting_2'' , ''temperature'')|round(0)) - 1 }}'
- component.update: watchface
- if:
condition:
and:
- text_sensor.state:
id: my_touch_screen
state: 'SWIPE DOWN'
- display.is_displaying_page: page1
then:
- logger.log: "Swiped down on page1"
#Note that this is the reverse of what you might expect
# This is directly increasing the thermostat set temperature in HA by one degree
- homeassistant.service:
service: climate.set_temperature
data_template:
entity_id: climate.thermostat_sitting_2
temperature: '{{(state_attr(''climate.thermostat_sitting_2'' , ''temperature'')|round(0)) + 1 }}'
- component.update: watchface
- if:
condition:
and:
- text_sensor.state:
id: my_touch_screen
state: 'LONG PRESS'
- display.is_displaying_page: page2
then:
- logger.log: "Long press on page2"
- display.page.show: page1
- component.update: watchface
- if:
condition:
and:
- text_sensor.state:
id: my_touch_screen
state: 'LONG PRESS'
- display.is_displaying_page: page3
then:
- logger.log: "Long press on page3"
- display.page.show: page1
- component.update: watchface
- if:
condition:
and:
- text_sensor.state:
id: my_touch_screen
state: 'SINGLE CLICK'
then:
- logger.log: "Single click to toggle backlight"
- light.toggle: back_light
- if:
condition:
and:
- text_sensor.state:
id: my_touch_screen
state: 'LONG PRESS'
- display.is_displaying_page: page4
then:
- logger.log: "Long press on page4 - toggle light"
# Option to toggle a light - note need to go to settings/devices/esphome click on configure for the device and allow the device to make HA calls
- homeassistant.service:
service: light.toggle
data:
entity_id: light.guest_lamp
# refresh the screen
- component.update: watchface
- if:
condition:
and:
- text_sensor.state:
id: my_touch_screen
state: 'LONG PRESS'
- display.is_displaying_page: page5
then:
- logger.log: "Long press on page5"
- display.page.show: page1
- component.update: watchface
# States currently detected
# 'SWIPE UP' - note that this appears to be reversed
# 'SWIPE DOWN - note that this appears to be reversed
# 'SWIPE LEFT'
# 'SWIPE RIGHT'
# 'LONG PRESS'
# 'SINGLE CLICK' - note that this can be temperamental. It works most of the time, but as the device is capacitive
# it is looking for voltage changes and might miss a quick tap. The longer actions like swiping are more reliable.
# For that reason, I'm just using the single tap to toggle the screen on or off. I'd note that this is also device
# dependent ie the sensitivity seems to vary between devices so you may have better luck.
# Need to turn on backlight as by default is not on
output:
- platform: ledc
pin: $bkpin
id: gpio_3_backlight_pwm
light:
- platform: monochromatic
output: gpio_3_backlight_pwm
name: "Display Backlight"
id: back_light
restore_mode: $screenstart
font:
- file: "gfonts://Roboto"
id: font_12
size: 12
- file: "gfonts://Roboto"
id: font_16
size: 16
- file: "gfonts://Roboto"
id: font_24
size: 24
- file: "gfonts://Roboto"
id: font_32
size: 32
- file: "gfonts://Roboto"
id: font_64
size: 64
color:
- id: my_red
hex: FF0000
- id: my_green
hex: 008000
- id: my_blue
hex: 0000FF
- id: my_yellow
hex: FFFF00
# Some pretty images - not critical
# I have a collection of images I have either created or modified from various sources using gimp
# As I do not have the rights to all the images I can't provide them here
# Again assumes you have them in config\icons or config\images
# Do not use large or complex images as the poor processor will struggle
# Ideally use images that are the right size and do not need resizing - to save memory and improve screen refresh speed
animation:
# This is a gif file that has two 8*8 pixel, 72dpi images of the sun so it looks like it glows as it alternates between them
# I used the resize option to make it the size I wanted
# Long term I plan to make different icons and change them based on the actual weather
# I may or may not use animations - the effect is very subtle and likely not worth the effort
- file: "icons/2051v2.gif"
id: clear_day
resize: 40x40
type: RGB565 #default is binary ie greyscale
# This is an 80*116 pixel, 144 pixel/inch image of a light bulb in the off position
- file: "images/lightoff.png"
id: light_off
type: BINARY
# This is an 80*116 pixel, 144 pixel/inch image of a glowing light bulb
- file: "images/lighton.png"
id: light_on
type: RGB565
# This is an 28*40 pixel, 72 pixel/inch image of a green arrow pointing down
- file: "images/greenarrow.png"
id: greenarrow
type: RGB565
# This is an 28*40 pixel, 72 pixel/inch image of a red arrow pointing up
- file: "images/redarrow.png"
id: redarrow
type: RGB565
- file: "images/wifi-qr.png"
id: qrcode
type: BINARY
# This is a QR code with your guest or home wifi in it - can create using https://qifi.org/
# Ideally resize the resulting image to, say, 169 pixels by 169 pixels
# If you want to give someone access to your wifi, then if their device has a camera then they
# may be able to scan the qr code and automatically join
# As a side note, if you have a decent 3d printer you can also use https://printer.tools/qrcode2stl/
# to create a STL file that you can use to print a physical qr code - I reduce that by 40% then print it
# using white PLA and 0.1mm resolution, then colour the ridges in with a black permanent marker
display:
- platform: ili9xxx
model: GC9A01A
id: watchface
reset_pin: $repin
cs_pin: $cspin
dc_pin:
number: $dcpin
ignore_strapping_warning: true
# The above is to remove the strapping pin warning message
# The next are optional
# width: 240
# height: 240
# Disable this if using ble_tracker as the poor thing doesn't have enough memory
# Enable it if not using ble_tracker as you will find the screen looks and responds better
# Disable this if you are encountering random reboots or other issues
# eight_bit_color: false
# How often to refresh the display
update_interval: 1s
# Rotate the screen so usb socket is pointing down
# rotation: 90
# No longer needed as integrated ili9xxx driver rotates the screen by default
pages:
- id: page1
lambda: |-
it.image(100, 20, id(redarrow), COLOR_ON, COLOR_OFF);
it.printf(140, 30, id(font_12), id(my_red), "swipe");
it.image(100, 190, id(greenarrow), COLOR_ON, COLOR_OFF);
it.printf(140, 200, id(font_12), id(my_green), "swipe");
it.printf(120,120, id(font_64), TextAlign::CENTER, "%.1f°", id(thermostat_temperature).state);
it.printf(120, 170, id(font_24), id(my_blue), TextAlign::CENTER, "Now: %.1f°", id(room_temperature).state);
it.circle(120, 120, 119, id(my_red));
if (id(thermostat_state).state == 0)
it.printf(120,80, id(font_24), id(my_green), TextAlign::CENTER, "HVAC Off");
if (id(thermostat_state).state == 1)
it.printf(120,80, id(font_24), id(my_red), TextAlign::CENTER, "Heater On");
if (id(thermostat_state).state == 2)
it.printf(120,80, id(font_24), id(my_blue), TextAlign::CENTER, "AC On");
- id: page2
lambda: |-
id(clear_day).next_frame();
it.image(100, 30, id(clear_day), COLOR_ON, COLOR_OFF);
it.strftime(120,80, id(font_16), id(my_blue), TextAlign::CENTER, "%A %b %d", id(esptime).now());
it.strftime(120,120, id(font_32), TextAlign::CENTER, "%I:%M %p", id(esptime).now());
it.printf(120, 170, id(font_32), id(my_blue), TextAlign::CENTER, "Now: %.1f°", id(outdoor_temperature).state);
it.printf(120, 200, id(font_16), id(my_green), TextAlign::CENTER, "outside");
it.circle(120, 120, 119, id(my_yellow));
- id: page3
lambda: |-
id(clear_day).next_frame();
it.image(100, 30, id(clear_day), COLOR_ON, COLOR_OFF);
it.strftime(120,80, id(font_16), id(my_blue), TextAlign::CENTER, "%A %b %d", id(esptime).now());
it.printf(120,120, id(font_24), TextAlign::CENTER, "Today Min/Max:");
it.printf(120, 170, id(font_32), id(my_blue), TextAlign::CENTER, "%.1f/%.1f°", id(min_temperature).state,id(max_temperature).state);
it.printf(120, 200, id(font_16), id(my_green), TextAlign::CENTER, "weather");
it.circle(120, 120, 119, id(my_blue));
- id: page4
lambda: |-
if (id(light_state).state == "off")
it.image(85, 60, id(light_off), COLOR_ON, COLOR_OFF);
if (id(light_state).state == "on")
it.image(85, 60, id(light_on), COLOR_ON, COLOR_OFF);
it.printf(120, 200, id(font_16), id(my_blue), TextAlign::CENTER, "lamp");
it.circle(120, 120, 119, id(my_green));
- id: page5
lambda: |-
it.image(35, 35, id(qrcode));
it.printf(120, 220, id(font_16), id(my_green), TextAlign::CENTER, "guest wifi");
it.circle(120, 120, 119, id(my_blue));
- id: page6
lambda: |-
id(clear_day).next_frame();
it.printf(120,30, id(font_16), id(my_blue), TextAlign::CENTER, "help");
it.printf(120,60, id(font_16), TextAlign::CENTER, "Swipe up/down");
it.printf(120,80, id(font_16), TextAlign::CENTER, "to change temp");
it.printf(120,110, id(font_16), id(my_yellow), TextAlign::CENTER, "Long press on thermostat");
it.printf(120,130, id(font_16), id(my_yellow), TextAlign::CENTER, "to toggle off/cool/heat");
it.printf(120,160, id(font_16), TextAlign::CENTER, "Swipe L/R to change screens");
it.printf(120,190, id(font_16), id(my_yellow), TextAlign::CENTER, "Tap to turn screen");
it.printf(120,210, id(font_16), id(my_yellow), TextAlign::CENTER, "on/off");
it.circle(120, 120, 119, id(my_green));
…and finally for those still playing at home, here’s a working example on how to use the controller to swipe between screens showing different information, show a thermostat and adjust the temps using swipe up/down, and toggle a light on/off. Note that the controller can show sensor states from home assistant, but to get home assistant to act on changes to the controller you need to create an automation that performs an action based on changes to the sensors that the controller creates in HA. Can take a moment to get your head around it, but it makes sense once you’ve done it a few times. For example, in the code for the controller there is:
- platform: template
optimistic: true
name: "$devicename light state"
id: light_state
min_value: 0
max_value: 1
initial_value: 0
update_interval: 1s
step: 1
This creates a sensor in HA that is either “0” or “1”. Then you also have:
- if:
condition:
and:
- text_sensor.state:
id: my_touch_screen
state: 'SINGLE CLICK'
- display.is_displaying_page: page4
then:
- logger.log: "Single click on page4"
- number.increment: light_state
This toggles the sensor value between 1 or 0 whenever the screen is on page 4 and is tapped.
Then in HA you need to create an automation along the lines of:
alias: Wallwatch - light toggle
description: ""
trigger:
- platform: state
entity_id:
- number.wallwatch01_wallwatch01_light_state
condition: []
action:
- service: light.toggle
data: {}
target:
entity_id: light.hue_white_lamp_1_4
mode: single
So now whenever the controller screen is on page 4, if you tap the screen the entity sensor will change state and HA will detect that and the automation will toggle the light on or off. You could of course make this so it specifically turns on when the entity is “1” or off when the entity is “0” - I will probably do that in the future so I can have the light icon state on the controller match the physical light state. (On a side note, I am currently finding that the “SINGLE CLICK” is not always detected and/or it thinks it is a swipe so I’m using both single click as well as long press in my code to toggle the light.)
To do other things, such as control a thermostat, you basically need to follow the same basic steps - create a sensor that changes state depending on what you do on the controller, and create automations in HA that perform actions depending on what the sensor states are. There are I expect better ways of doing this, but it works for me.
Here is the example code in full:
# V0.3 - 10/10/2023
# Compiled and tested on esphome 2023.9.3
substitutions:
devicename: wallwatch01
friendname: WallWatch01
location: master
board: esp32-c3-devkitm-1
#GPIO pins for the LCD screen
repin: GPIO1
dcpin: GPIO2
bkpin: GPIO3
clpin: GPIO6
mopin: GPIO7
cspin: GPIO10
# GPIO pins for the touch screen
sdapin: GPIO4
sclpin: GPIO5
intpin: GPIO8
esphome:
name: $devicename
friendly_name: $friendname
esp32:
board: $board
framework:
type: arduino
# Enable logging
# Change to avoid "Components should block for at most 20-30ms" warning messages in the log - an issue since 2023.7.0
# Not really a breaking change - it's an issue I suspect due to the device being slow and this error previously
# simply not being reported
logger:
level: DEBUG
logs:
component: ERROR
# Enable Home Assistant API
api:
encryption:
key: !secret esphome_encryption_key
ota:
password: !secret ota_password
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
# Enable fallback hotspot (captive portal) in case wifi connection fails
ap:
ssid: "Wallwatch01 Fallback Hotspot"
password: !secret fallback_password
captive_portal:
time:
- platform: homeassistant
timezone: "Australia/Melbourne"
id: esptime
# Test - see if the thing picks up BLE info
#esp32_ble_tracker:
#nope - locks up
#SpokeTooSoon - actually does work, kinda. Slows down the startup significantly then claims to scan but nothing is found
#Either is not supported or antenna is really weak. Suspect both.
sensor:
- platform: uptime
name: "$devicename Uptime"
- platform: wifi_signal
name: "$devicename WiFi Signal"
update_interval: 60s
- platform: homeassistant
id: outdoor_temperature
entity_id: sensor.gw1000_v1_7_6_outdoor_temperature
- platform: homeassistant
id: max_temperature
entity_id: sensor.brighton_east_temp_max_0
- platform: homeassistant
id: min_temperature
entity_id: sensor.brighton_east_temp_min_1
# Add in the thermostat and temp sensor we want to see
- platform: homeassistant
id: thermostat_temperature
entity_id: climate.thermostat_master
attribute: temperature
- platform: homeassistant
id: room_temperature
entity_id: sensor.wall_control_06_wall06_temp
external_components:
- source: github://zagnuts/esphome-components
components: [ gc9a01 ]
refresh: 30min
- source: github://GadgetFactory/[email protected]
spi:
mosi_pin: $mopin
clk_pin: $clpin
# Don't use software - makes it crawl
# force_sw: True
#mosi = Master Out Slave In
#miso = Master In Slave Out or fermented bean paste. In this case, most likely the former rather than the latter. Doesn't matter as not used.
i2c:
sda: $sdapin
scl: $sclpin
#Following helped someone get rid of error messages but didn't for me
#frequency: 400kHz
number:
# Create some virtual sensors - use automations to perform actions based on the state of these
# This is to adjust the virtual thermostat
- platform: template
optimistic: true
name: "$devicename thermostat"
id: thermostat_adjust
min_value: 18
max_value: 35
initial_value: 20
update_interval: 1s
step: 1
# This is a binary off or on to toggle the virtual thermostat states between off or heat or cool
# Where 0 is off and 1 is heat and 2 is cool
- platform: template
optimistic: true
name: "$devicename therm state"
id: thermostat_state
min_value: 0
max_value: 2
initial_value: 0
update_interval: 1s
step: 1
# This is a binary off or on to toggle the light off or on
- platform: template
optimistic: true
name: "$devicename light state"
id: light_state
min_value: 0
max_value: 1
initial_value: 0
update_interval: 1s
step: 1
text_sensor:
- platform: CST816S_touchscreen
id: my_touch_screen
on_value:
then:
- if:
condition:
text_sensor.state:
id: my_touch_screen
state: 'SWIPE RIGHT'
then:
- display.page.show_next: watchface
- component.update: watchface
- logger.log: "Swiped right, go to next page"
- if:
condition:
text_sensor.state:
id: my_touch_screen
state: 'SWIPE LEFT'
then:
- display.page.show_previous: watchface
- component.update: watchface
- logger.log: "Swiped left, go back a page"
- if:
condition:
and:
- text_sensor.state:
id: my_touch_screen
state: 'SINGLE CLICK'
- display.is_displaying_page: page1
then:
- logger.log: "Clicked on page1"
- if:
condition:
and:
- text_sensor.state:
id: my_touch_screen
state: 'SINGLE CLICK'
- display.is_displaying_page: page2
then:
- logger.log: "Clicked on page2"
- if:
condition:
and:
- text_sensor.state:
id: my_touch_screen
state: 'SWIPE UP'
- display.is_displaying_page: page1
then:
- logger.log: "Swiped up on page1"
#Note that this is the reverse of what you might expect
- number.decrement: thermostat_adjust
- if:
condition:
and:
- text_sensor.state:
id: my_touch_screen
state: 'SWIPE DOWN'
- display.is_displaying_page: page1
then:
- logger.log: "Swiped down on page1"
#Note that this is the reverse of what you might expect
- number.increment: thermostat_adjust
- if:
condition:
and:
- text_sensor.state:
id: my_touch_screen
state: 'LONG PRESS'
- display.is_displaying_page: page4
then:
- logger.log: "Long press on page4"
- number.increment: light_state
# Have found that the 'single click' does not always register hence also using 'long press' to toggle light
- if:
condition:
and:
- text_sensor.state:
id: my_touch_screen
state: 'SINGLE CLICK'
- display.is_displaying_page: page4
then:
- logger.log: "Single click on page4"
- number.increment: light_state
# States currently detected
# 'SWIPE UP' - note that this appears to be reversed
# 'SWIPE DOWN' - note that this appears to be reversed
# 'SWIPE LEFT'
# 'SWIPE RIGHT'
# 'LONG PRESS'
# 'SINGLE CLICK'
# Need to turn on backlight as by default is not on
output:
- platform: ledc
pin: $bkpin
id: gpio_3_backlight_pwm
light:
- platform: monochromatic
output: gpio_3_backlight_pwm
name: "Display Backlight"
id: back_light
restore_mode: ALWAYS_ON
# The following assumes you have the named fonts in config\fonts
# If not, you can always download on the fly eg
# - file: "gfonts://Roboto"
# id: font_16
# size: 16
font:
- file: 'fonts/GoogleSans-Medium.ttf'
id: font_16
size: 16
- file: 'fonts/GoogleSans-Medium.ttf'
id: font_24
size: 24
- file: 'fonts/GoogleSans-Medium.ttf'
id: font_32
size: 32
color:
- id: my_red
red: 100%
green: 3%
blue: 5%
- id: my_green
red: 3%
green: 100%
blue: 5%
- id: my_blue
red: 3%
green: 5%
blue: 100%
# Some pretty images - not critical
# Again assumes you have them in config\icons
# Do not use large or complex images as the poor processor will struggle
animation:
- file: "icons/2051v2.gif"
id: clear_day
resize: 40x40
type: RGB565 #default is binary ie greyscale
- file: "images/light2.png"
id: light_bulb
# resize: 80x80
# type: RGB565
# Need the following image section currently with esphome since 2023.7.0
# Otherwise you will probably get 'id' is a required option for [0] errors when trying to compile
# I will note here a pet hate with breaking changes - I know that this is community developed code
# but still, it's a total pain when updating brings in weird issues like this and I continue to be in
# awe when the community discover work arounds that are so left field
image:
- file: "icons/2051v2.gif"
id: gifArt
display:
# - platform: ili9xxx
# model: gc9a01
# Above is for when or if this is merged into the ili9xxx platform
# Until then though, need to use an external component
- platform: gc9a01
id: watchface
reset_pin: $repin
cs_pin: $cspin
dc_pin: $dcpin
# Rotate the screen so usb socket is pointing down
rotation: 90
# Print the date on one line in blue
# Print the current time on the next line, but in a bigger font and in default white
# Print the outside temp on the next line but in green
# Surround the lot by a red circle with centre at 120, 120 and a radius of 115 because why not
# Procrastinating now on the touchscreen, so instead added a second page and cycling between two screens because again why not
pages:
- id: page1
lambda: |-
id(clear_day).next_frame();
it.image(100, 30, id(clear_day), COLOR_ON, COLOR_OFF);
it.printf(120,80, id(font_16), id(my_blue), TextAlign::CENTER, "Thermostat");
it.printf(120,120, id(font_24), TextAlign::CENTER, "Set Temp: %.1f°", id(thermostat_temperature).state);
it.printf(120, 170, id(font_32), id(my_green), TextAlign::CENTER, "Now: %.1f°", id(room_temperature).state);
it.circle(120, 120, 115, id(my_red));
- id: page2
lambda: |-
id(clear_day).next_frame();
it.image(100, 30, id(clear_day), COLOR_ON, COLOR_OFF);
it.strftime(120,80, id(font_16), id(my_blue), TextAlign::CENTER, "%A %b %d", id(esptime).now());
it.strftime(120,120, id(font_32), TextAlign::CENTER, "%I:%M %p", id(esptime).now());
it.printf(120, 170, id(font_32), id(my_green), TextAlign::CENTER, "Now: %.1f°", id(outdoor_temperature).state);
it.circle(120, 120, 115, id(my_red));
- id: page3
lambda: |-
id(clear_day).next_frame();
it.image(100, 30, id(clear_day), COLOR_ON, COLOR_OFF);
it.strftime(120,80, id(font_16), id(my_blue), TextAlign::CENTER, "%A %b %d", id(esptime).now());
it.printf(120,120, id(font_24), TextAlign::CENTER, "Today Min/Max:");
it.printf(120, 170, id(font_32), id(my_green), TextAlign::CENTER, "%.1f/%.1f°", id(min_temperature).state,id(max_temperature).state);
it.circle(120, 120, 115, id(my_blue));
- id: page4
lambda: |-
id(clear_day).next_frame();
it.image(80, 80, id(light_bulb), COLOR_ON, COLOR_OFF);
it.circle(120, 120, 115, id(my_blue));
Well done! Very cool.
I suggest posting this in the Cookbook section of the ESPhome website.
Hahaha, I just realized, I probably should have written in my post what the minimal touchscreen support could do instead of what was missing. I was a little tired and just trying to push the code out before calling it a day.
It should be fully working for all of the gestures which is probably the bulk of what most use cases will be.
Next up is working on the x,y coordinates and the ability to convert to polar coordinates.
My plan is to be able to put a color wheel on the screen so you can easily and intuitively select the color of your lights with it. I’ve designed a 3d printed enclosure that lets you put this over an existing light switch so you can prevent the power from being cut off from the smart bulbs while still allowing convenient control in the same location. It will be a smarter light switch.
I started out with a touchless light switch that uses a gesture sensor to turn the lights on and off or dim them with just the swipe of a hand. That is working pretty well and is pretty neat but I think this round display might be a nice upgrade. Here are some pictures of the progress so far:
Gesture sensor light switch
Round Touchscreen light switch (still lots to do still)
Still need to put in a battery holder and get the right connector to connect a battery to the round touchscreen.
The gesture sensor uses esp-now to enable very fast wakeup from deep sleep and turning the light on or off within 500mS. I’ll work on making that work with this round gesture sensor as time allows. So far the battery has lasted several months with no problem and I think I calculated it should last over a year.
I haven’t measured the current draw of this round touchscreen yet, but it should be able to work off battery for an acceptable amount of time. We can always put larger batteries in too.
I love it - my method is to put a yellow sticky note on the switches with “magic enabled” written on it. Works, but your solution is far more elegant.
Fully understand the whole pushing the thing out before calling it a day - I did the same thing when initially putting the original post together ie did a big burst of trying to nut out the screen and then when I finally got it to work I had to put it aside for a while. But huge thank you for getting the touch code working - I agree it does pretty much everything we need. It would be nice to have the ability to identify where on the screen it’s being touched, but it’s so damn small the only use case might be for dimming the lights , changing music volume, or temperature settings - but all of those can be done with swipes as well. Anyhoo, found a few more spare minutes and have added light on/off rather than toggle.
# V0.3 - 10/10/2023
# Compiled and tested on esphome 2023.9.3
substitutions:
devicename: wallwatch01
friendname: WallWatch01
location: master
board: esp32-c3-devkitm-1
#GPIO pins for the LCD screen
repin: GPIO1
dcpin: GPIO2
bkpin: GPIO3
clpin: GPIO6
mopin: GPIO7
cspin: GPIO10
# GPIO pins for the touch screen
sdapin: GPIO4
sclpin: GPIO5
intpin: GPIO8
esphome:
name: $devicename
friendly_name: $friendname
esp32:
board: $board
framework:
type: arduino
# Enable logging
# Change to avoid "Components should block for at most 20-30ms" warning messages in the log - an issue since 2023.7.0
# Not really a breaking change - it's an issue I suspect due to the device being slow and this error previously
# simply not being reported
logger:
level: DEBUG
logs:
component: ERROR
# Enable Home Assistant API
api:
encryption:
key: !secret esphome_encryption_key
ota:
password: !secret ota_password
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
# Enable fallback hotspot (captive portal) in case wifi connection fails
ap:
ssid: "Wallwatch01 Fallback Hotspot"
password: !secret fallback_password
captive_portal:
time:
- platform: homeassistant
timezone: "Australia/Melbourne"
id: esptime
# Test - see if the thing picks up BLE info
#esp32_ble_tracker:
#nope - locks up
#SpokeTooSoon - actually does work, kinda. Slows down the startup significantly then claims to scan but nothing is found
#Either is not supported or antenna is really weak. Suspect both.
sensor:
- platform: uptime
name: "$devicename Uptime"
- platform: wifi_signal
name: "$devicename WiFi Signal"
update_interval: 60s
- platform: homeassistant
id: outdoor_temperature
entity_id: sensor.gw1000_v1_7_6_outdoor_temperature
- platform: homeassistant
id: max_temperature
entity_id: sensor.brighton_east_temp_max_0
- platform: homeassistant
id: min_temperature
entity_id: sensor.brighton_east_temp_min_1
# Add in the thermostat and temp sensor we want to see
- platform: homeassistant
id: thermostat_temperature
entity_id: climate.thermostat_master
attribute: temperature
- platform: homeassistant
id: room_temperature
entity_id: sensor.wall_control_06_wall06_temp
external_components:
- source: github://zagnuts/esphome-components
components: [ gc9a01 ]
refresh: 30min
- source: github://GadgetFactory/[email protected]
spi:
mosi_pin: $mopin
clk_pin: $clpin
# Don't use software - makes it crawl
# force_sw: True
#mosi = Master Out Slave In
#miso = Master In Slave Out or fermented bean paste. In this case, most likely the former rather than the latter. Doesn't matter as not used.
i2c:
sda: $sdapin
scl: $sclpin
#Following helped someone get rid of error messages but didn't for me
#frequency: 400kHz
number:
# Create some virtual sensors - use automations to perform actions based on the state of these
# This is to adjust the virtual thermostat
- platform: template
optimistic: true
name: "$devicename thermostat"
id: thermostat_adjust
min_value: 18
max_value: 35
initial_value: 20
update_interval: 1s
step: 1
# This is a binary off or on to toggle the virtual thermostat states between off or heat or cool
# Where 0 is off and 1 is heat and 2 is cool
- platform: template
optimistic: true
name: "$devicename therm state"
id: thermostat_state
min_value: 0
max_value: 2
initial_value: 0
update_interval: 1s
step: 1
# This is a binary off or on to toggle the light off or on
- platform: template
optimistic: true
name: "$devicename light state"
id: light_state
min_value: 0
max_value: 1
initial_value: 0
update_interval: 1s
step: 1
text_sensor:
- platform: CST816S_touchscreen
id: my_touch_screen
on_value:
then:
- if:
condition:
text_sensor.state:
id: my_touch_screen
state: 'SWIPE RIGHT'
then:
- display.page.show_next: watchface
- component.update: watchface
- logger.log: "Swiped right, go to next page"
- if:
condition:
text_sensor.state:
id: my_touch_screen
state: 'SWIPE LEFT'
then:
- display.page.show_previous: watchface
- component.update: watchface
- logger.log: "Swiped left, go back a page"
- if:
condition:
and:
- text_sensor.state:
id: my_touch_screen
state: 'SINGLE CLICK'
- display.is_displaying_page: page1
then:
- logger.log: "Clicked on page1"
- if:
condition:
and:
- text_sensor.state:
id: my_touch_screen
state: 'SINGLE CLICK'
- display.is_displaying_page: page2
then:
- logger.log: "Clicked on page2"
- if:
condition:
and:
- text_sensor.state:
id: my_touch_screen
state: 'SWIPE UP'
- display.is_displaying_page: page1
then:
- logger.log: "Swiped up on page1"
#Note that this is the reverse of what you might expect
- number.decrement: thermostat_adjust
- if:
condition:
and:
- text_sensor.state:
id: my_touch_screen
state: 'SWIPE DOWN'
- display.is_displaying_page: page1
then:
- logger.log: "Swiped down on page1"
#Note that this is the reverse of what you might expect
- number.increment: thermostat_adjust
- if:
condition:
and:
- text_sensor.state:
id: my_touch_screen
state: 'SINGLE CLICK'
- display.is_displaying_page: page4
then:
- logger.log: "Single click on page4"
- number.increment: light_state
# refresh the screen
- component.update: watchface
# Have found that the 'single click' does not always register hence also using 'long press' to toggle light
- if:
condition:
and:
- text_sensor.state:
id: my_touch_screen
state: 'LONG PRESS'
- display.is_displaying_page: page4
then:
- logger.log: "Long press on page4"
- number.increment: light_state
# refresh the screen
- component.update: watchface
# States currently detected
# 'SWIPE UP' - note that this appears to be reversed
# 'SWIPE DOWN - note that this appears to be reversed
# 'SWIPE LEFT'
# 'SWIPE RIGHT'
# 'LONG PRESS'
# 'SINGLE CLICK'
# Need to turn on backlight as by default is not on
output:
- platform: ledc
pin: $bkpin
id: gpio_3_backlight_pwm
light:
- platform: monochromatic
output: gpio_3_backlight_pwm
name: "Display Backlight"
id: back_light
restore_mode: ALWAYS_ON
# The following assumes you have the named fonts in config\fonts
# If not, you can always download on the fly eg
# - file: "gfonts://Roboto"
# id: font_16
# size: 16
font:
- file: 'fonts/GoogleSans-Medium.ttf'
id: font_16
size: 16
- file: 'fonts/GoogleSans-Medium.ttf'
id: font_24
size: 24
- file: 'fonts/GoogleSans-Medium.ttf'
id: font_32
size: 32
color:
- id: my_red
red: 100%
green: 3%
blue: 5%
- id: my_green
red: 3%
green: 100%
blue: 5%
- id: my_blue
red: 3%
green: 5%
blue: 100%
# Some pretty images - not critical
# Again assumes you have them in config\icons
# Do not use large or complex images as the poor processor will struggle
animation:
- file: "icons/2051v2.gif"
id: clear_day
resize: 40x40
type: RGB565 #default is binary ie greyscale
- file: "images/lightoff.png"
id: light_off
- file: "images/lighton.png"
id: light_on
type: RGB565
# resize: 80x80
# type: RGB565
# Need the following image section currently with esphome since 2023.7.0
# Otherwise you will probably get 'id' is a required option for [0] errors when trying to compile
# I will note here a pet hate with breaking changes - I know that this is community developed code
# but still, it's a total pain when updating brings in weird issues like this and I continue to be in
# awe when the community discover work arounds that are so left field
image:
- file: "icons/2051v2.gif"
id: gifArt
display:
# - platform: ili9xxx
# model: gc9a01
# Above is for when or if this is merged into the ili9xxx platform
# Until then though, need to use an external component
- platform: gc9a01
id: watchface
reset_pin: $repin
cs_pin: $cspin
dc_pin: $dcpin
# Rotate the screen so usb socket is pointing down
rotation: 90
# Print the date on one line in blue
# Print the current time on the next line, but in a bigger font and in default white
# Print the outside temp on the next line but in green
# Surround the lot by a red circle with centre at 120, 120 and a radius of 115 because why not
# Procrastinating now on the touchscreen, so instead added a second page and cycling between two screens because again why not
pages:
- id: page1
lambda: |-
id(clear_day).next_frame();
it.image(100, 30, id(clear_day), COLOR_ON, COLOR_OFF);
it.printf(120,80, id(font_16), id(my_blue), TextAlign::CENTER, "Thermostat");
it.printf(120,120, id(font_24), TextAlign::CENTER, "Set Temp: %.1f°", id(thermostat_temperature).state);
it.printf(120, 170, id(font_32), id(my_green), TextAlign::CENTER, "Now: %.1f°", id(room_temperature).state);
it.circle(120, 120, 115, id(my_red));
- id: page2
lambda: |-
id(clear_day).next_frame();
it.image(100, 30, id(clear_day), COLOR_ON, COLOR_OFF);
it.strftime(120,80, id(font_16), id(my_blue), TextAlign::CENTER, "%A %b %d", id(esptime).now());
it.strftime(120,120, id(font_32), TextAlign::CENTER, "%I:%M %p", id(esptime).now());
it.printf(120, 170, id(font_32), id(my_green), TextAlign::CENTER, "Now: %.1f°", id(outdoor_temperature).state);
it.circle(120, 120, 115, id(my_red));
- id: page3
lambda: |-
id(clear_day).next_frame();
it.image(100, 30, id(clear_day), COLOR_ON, COLOR_OFF);
it.strftime(120,80, id(font_16), id(my_blue), TextAlign::CENTER, "%A %b %d", id(esptime).now());
it.printf(120,120, id(font_24), TextAlign::CENTER, "Today Min/Max:");
it.printf(120, 170, id(font_32), id(my_green), TextAlign::CENTER, "%.1f/%.1f°", id(min_temperature).state,id(max_temperature).state);
it.circle(120, 120, 115, id(my_blue));
- id: page4
lambda: |-
it.image(80, 80, id(light_off), COLOR_ON, COLOR_OFF);
if (id(light_state).state == 0)
it.image(80, 80, id(light_off), COLOR_ON, COLOR_OFF);
if (id(light_state).state == 1)
it.image(80, 80, id(light_on), COLOR_ON, COLOR_OFF);
it.circle(120, 120, 115, id(my_blue));
and two automations
alias: Wallwatch - light turn on
description: ""
trigger:
- platform: numeric_state
entity_id: number.wallwatch01_wallwatch01_light_state
above: 0
condition: []
action:
- service: light.turn_on
data: {}
target:
entity_id: light.hue_white_lamp_1_4
mode: single
and
alias: Wallwatch - light turn off
description: ""
trigger:
- platform: numeric_state
entity_id: number.wallwatch01_wallwatch01_light_state
below: 1
condition: []
action:
- service: light.turn_off
data: {}
target:
entity_id: light.hue_white_lamp_1_4
mode: single
…or could combine into one automation eg:
alias: Wallwatch - turn light on or off
description: ""
trigger:
- platform: state
entity_id:
- number.wallwatch01_wallwatch01_light_state
condition: []
action:
- if:
- condition: numeric_state
entity_id: number.wallwatch01_wallwatch01_light_state
above: 0
then:
- service: light.turn_on
data: {}
target:
entity_id: light.hue_white_lamp_1_4
else:
- service: light.turn_off
data: {}
target:
entity_id: light.hue_white_lamp_1_4
mode: single
The main use case I was thinking was to be able to quickly select a color from a color wheel. Oh, and I also want to drag up and down on the screen to dim or brighten lights.
That is what drew me to this round display in the first place, I thought it might look cool to put a color wheel like this on it:
Oooh… yes, true. I tend to have set modes for parties etc as it can be a bit problematic hunting around trying to get that shade of pink that’s just right, but that would definitely be nice to have.
Sorry, but I don’t have the rights to share those. I just found some images online and used gimp to shrink them to a size more suited to the screen. Frankly they are quick hacks done as a proof of concept. Now that the thing works, will probably look for some better images to use.
Tried installing the yaml file to device, says Device Disconnected. Even did a reset to device using Esptool. Also when I try to download the installation file from esphome get following error:
INFO ESPHome 2023.8.2
INFO Reading configuration /config/round-display.yaml...
WARNING GPIO2 is a Strapping PIN and should be avoided.
Attaching external pullup/down resistors to strapping pins can cause unexpected failures.
See https://esphome.io/guides/faq.html#why-am-i-getting-a-warning-about-strapping-pins
INFO Generating C++ source...
WARNING The image "/config/images/light2.png" you requested is very big. Please consider using the resize parameter.
INFO Compiling app...
Processing round-display (board: esp32-c3-devkitm-1; framework: arduino; platform: platformio/[email protected])
--------------------------------------------------------------------------------
HARDWARE: ESP32C3 160MHz, 320KB RAM, 4MB Flash
- toolchain-riscv32-esp @ 8.4.0+2021r2-patch5
Dependency Graph
|-- AsyncTCP-esphome @ 1.2.2
|-- WiFi @ 2.0.0
|-- FS @ 2.0.0
|-- Update @ 2.0.0
|-- ESPAsyncWebServer-esphome @ 2.1.0
|-- DNSServer @ 2.0.0
|-- ESPmDNS @ 2.0.0
|-- noise-c @ 0.1.4
|-- SPI @ 2.0.0
|-- Wire @ 2.0.0
|-- CST816S @ 1.1.1+sha.dd4f520
Compiling .pioenvs/round-display/src/esphome/components/CST816S_touchscreen/CST816S_touchscreen.cpp.o
sh: 1: riscv32-esp-elf-g++: not found
Compiling .pioenvs/round-display/src/esphome/components/animation/animation.cpp.o
sh: 1: riscv32-esp-elf-g++: not found
Compiling .pioenvs/round-display/src/esphome/components/api/api_connection.cpp.o
sh: 1: riscv32-esp-elf-g++: not found
*** [.pioenvs/round-display/src/esphome/components/CST816S_touchscreen/CST816S_touchscreen.cpp.o] Error 127
Compiling .pioenvs/round-display/src/esphome/components/api/api_frame_helper.cpp.o
*** [.pioenvs/round-display/src/esphome/components/animation/animation.cpp.o] Error 127
*** [.pioenvs/round-display/src/esphome/components/api/api_connection.cpp.o] Error 127
sh: 1: riscv32-esp-elf-g++: not found
*** [.pioenvs/round-display/src/esphome/components/api/api_frame_helper.cpp.o] Error 127
========================== [FAILED] Took 4.61 seconds ==========================
Here’s a short video of mine. Intend to use it as a media player controller.
It’s still work in progress, e.g. I need to fix a condition so that the screen does not “flicker” when I join a different speaker. But it’s quite nice and the image quality actually looks ok in real life - but does not translate very well to video.
Try using a different cable, and for the other, the error indicates the image file you are using is too big - that would cause the program to fail to load as the device does not have a lot of memory.
It suggests using the resize option, but personally I’d consider simply removing the images from the code to begin with or find some smaller images/use something like gimp to resize them to (say) 40*40 pixels.
Edit the code here:
animation:
# - file: "icons/2051v2.gif"
- file: "images/40x40.gif"
id: clear_day
resize: 40x40
type: RGB565 #default is binary ie greyscale
- file: "images/40x40.gif"
# - file: "images/lightoff.png"
id: light_off
- file: "images/40x40.gif"
# - file: "images/lighton.png"
id: light_on
type: RGB565
# resize: 80x80
# type: RGB565
# Need the following image section currently with esphome since 2023.7.0
# Otherwise you will probably get 'id' is a required option for [0] errors when trying to compile
# I will note here a pet hate with breaking changes - I know that this is community developed code
# but still, it's a total pain when updating brings in weird issues like this and I continue to be in
# awe when the community discover work arounds that are so left field
image:
# - file: "icons/2051v2.gif"
- file: "images/40x40.gif"
id: gifArt
…and use this file just to get going:
So I am on to the next stage - looking at wall mounting my test controller. It uses a standard JST 1.25mm 2 wire connector (a lot of batteries use these connectors), so fortunately I had one in my box of bits. As a bonus it also fits quite flush to the case, meaning that the controller should easily mount to the wall and I can run the power cable through a small hole. As always be cautious as to which wire is positive and which is negative. With my cable the black wire connected to the positive terminal, so the red to negative. In DC circuits it is usually the other way around but as in this case it is not always, so triple check before connecting power - if you accidentally reverse these you may hear a small pop and the magic smoke will be released.
…and also so I can work out how many of these I could potentially run off a single power supply, I tested the draw and mine seems to draw up to 0.1 of an amp (usually more around the 0.07 mark) and when the screen is powered off (I plan to use motion sensor to turn the screen on/off as required) it drops to around the 0.03 amp mark. Not too bad.
What size battery are you planning on using? We can calculate runtime once the battery capacity is known, but from what I remember, you will only get a week to a month run time out of a pretty large battery.
I’ve got the gesture sensor working down to 10uA or something really low by using deepsleep. The trick is to use a espnow gateway so it can respond quickly. Then it works for closer to a year depending on use.
I think this route is the way to go
https://es.aliexpress.com/item/32838390049.html?gatewayAdapt=glo2esp
(not this one in particular, picked up random one)
step down converter 220v (or 110v in USA, etc) to 5v and forget about batteries, small enough to fit in the light switch connections hole (I don’t know the term in english xD)
No batteries - I have the luxury of old cat5 cables running from the walls to a central location, so can use that to provide 5v from a power supply, so for me a single 2amp supply would easily support a dozen of these controllers without breaking a sweat even allowing for loss over distance (roughly 5% loss over 100 meters of FTP shielded cable) in particular assuming most of them would be off at any one point in time.
Definitely would work, but my concern would be the risk of fire from something like that being constantly powered in the wall behind the switch. Personally I’d either put the controller on a box that contains a battery and live with having to recharge it every now and then, or run a cable down/in the wall to a remote power pack.
No batteries - I have the luxury of old cat5 cables running from the walls to a central location
Oh! That is nice!