So I’ve documented my journey in being able to control the ducts of my home heating/cooling system using esphome, some relays, and e-ink displays here. It’s working well, but the wall control panels are time consuming to create and cost more than I’d like.
I’m now looking at creating a thermostat control that is small, inexpensive, and simple to setup. Although my use case as a room thermostat is fairly specific, I think that what I am trying to do is something that could easily be used for many other tasks around the house (such as light switches) so thought I’d document it here. To that end I have found these guys:
Found in Aliexpress under the title “ESP32 Arduino LVGL WIFI&Bluetooth Development Board 1.28” 240*240 IPS Smart Display Screen 1.28 inch IPS LCD TFT Module touch"
These fit my requirements almost exactly. They come with an ESP32 built in, can be purchased with a case (black or white), and don’t cost much (about AUD$25/USD$16 delivered). They have a USB-C socket to configure and provide power, but also have separate sockets for power or even external sensors. The screen may be just a little small (think of a medium size smart watch screen), but the screen is bright and crisp so I think it will do quite well.
I ordered one to experiment with, and this is what I’ve found so far.
The device is an ESP32-2424S012 (Single Core 32bit)
1.28-inch 240*240 IPS TFT screen with Capacitive touch
When it arrived, on plugging it in it already had the demo image installed - it allows you to swipe (left/right/up/down) between screens, tap on an area marked ‘home’ to go back to the home, on a screen with a (pretend) music player you can toggle pause/play as well as change volume with a slider around the edge.
Sweet. Looks good. Time to break it.
I installed esphome via webtools, which worked to a point - can reset and install code but fails when trying to configure WiFi as it does not appear to support Improv WiFi serial. Could install the code directly if plugged into my esphome server but I have migrated over to running everything in containers which makes that tricky. Dang. So the screen was dead. I then tried to reinstall the original demo code via Arduino IDE. Followed instructions but got errors - resolved most of them but still had a few left so eventually gave up as I don’t want to use Arduino IDE anyhow.
Went to https://web.esphome.io and uploaded the 1.28DEMO.bin file (from the support docs) - all good. Back to being able to pretend to play music. At least I knew I hadn’t borked the device.
So. I wiped the device again. I created a small esphome config on esphome, downloaded the file locally, then uploaded the bin file to the device. Success! Created some text sensors such as uptime and all fine. Nothing on the screen of course, but now I could test my code using esphome over wifi.
Checked demo code, then compared with the documentation, and verified what the GPIO pins etc were being used. I also confirmed from that, that the device is a GC9A01 with a CST816D touch screen.
I then found a discussion talking about support for the GC9A01, and I tried that code. It installed happily, but still no image on the screen itself. Need to put this to one side for a little while until I have some time to do a bit more debugging.
As an aside the device in theory supports bluetooth - I tried installing the BLE tracker and initially thought the device had locked up, but in reality it just took a lot longer to start up. I think that the unit is pretty low powered, and I also suspect that it’s either not supported or the antenna is not fantastic - so probably don’t assume you may be able to use these for presence detection.
I’ll upload my current code, with comments, and will update if/as I progress.
substitutions:
devicename: wallwatch01
friendname: WallWatch01
location: master
board: esp32-c3-devkitm-1
esphome:
name: $devicename
friendly_name: $friendname
esp32:
board: $board
framework:
type: arduino
# Enable logging
logger:
# Enable Home Assistant API
api:
encryption:
key: "thisisakey"
ota:
password: "thisisapassword"
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: "yetanotherpassword"
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
#SpokeToSoon - actually does work, kinda. Slows down the startup significantly then claims to scan but nothing is found
#Suspect that it is really weak
sensor:
- platform: uptime
name: "$devicename Uptime"
- platform: wifi_signal
name: "$devicename WiFi Signal"
update_interval: 60s
external_components:
# - source: github://pr#3625
# components: [ gc9a01 ]
- source: github://4cello/esphome@gc9a01
components: ["gc9a01"]
# Arduino code shows screen is a GC9A01 with CST816D touch screen
# Neither above work - screen blank
spi:
mosi_pin: GPIO7
clk_pin: GPIO6
# Arduino IDE Code says
# cfg.pin_sclk = 6
# cfg.pin_mosi = 7
# ESP32-2424S012-V1.0.PNG agrees
# ESP32-2424S012-V1.0.PNG (LCM diagram) agrees - SCL and SDA
font:
- file: 'fonts/GoogleSans-Medium.ttf'
id: font_16
size: 16
display:
# - platform: ili9xxx
# model: gc9a01
# Above is for when or if this is merged into the ili9xxx platform
- platform: gc9a01
id: watchface
# reset_pin: GPIO26 # code has this disabled - could be GPI08 or 9?
# ESP32-2424S012-V1.0.PNG (LCM diagram) shows REST goes to REST - most likely the physical reset buttton
# Which is connected to EN on the ESP32 - physical pin 8 - enable pin
# Note GPIO9 is a strapping pin, so not great to use
# ESP32-2424S012-V1.0.PNG says GPIO9 is boot. Might disable for now.
# reset_pin: GPIO9
cs_pin: GPIO10
# Arduino IDE Code says
# cfg.pin_cs = 10
# ESP32-2424S012-V1.0.PNG agrees
# ESP32-2424S012-V1.0.PNG (LCM diagram) agrees
dc_pin: GPIO2
# Arduino IDE Code says
# cfg.pin_dc = 2
# ESP32-2424S012-V1.0.PNG (ESP32 diagram) says this is SPIMISO
# ESP32-2424S012-V1.0.PNG (LCM diagram) shows D/C goes to SPIMISO which is GPI02
# Note GPIO2 is a strapping pin, so not great to use
rotation: 90
lambda: |-
it.strftime(120,80, id(font_16), TextAlign::CENTER, "%A %b %w", id(esptime).now());