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());