Installing ESPhome on GEEKMAGIC Smart Weather Clock (smalltv/pro)

Hello everyone.

Aliexpress currently offers a GEEKMAGIC Smart Weather Clock. From the photos of a review, it can be seen that ESPs are installed in it.

There are apparently two versions:
smalltv - ~15 EUR - with ESP-12F and without touch sensor on the top
smalltv pro - ~25 EUR - with ESP32-WROOM-32 and touch sensor on the top

As always, there are different vendors and prices, but the bottom line always seems to be these two devices.

There are various photos of the inside of the pro version in the reviews.

I ordered the non-pro version and have included a few photos here.

The pinout on the ESP board is as follows:

1 GND
2 TXD0
3 RXD0
4 3V3
5 GPIO0
6 RST

Edit: Onboard blue LED on GPIO2 (inverted)

I am still unsure about the display. It could be a variant of this display. The pinout of the display connector could match. At least GND and VCC are on the matching pins. I couldn’t trace the rest so far, because I can’t reach the small contacts on the display connector and on the ESP at the same time…

The display could be supported in ESPhome with the ST7789V component, although the memory on the ESP8266 will probably not be enough for that.

Edit: Firmware Repository (binary only, no sourcecode)

All in all, unfortunately, you can’t find any documentation for these two devices on the internet yet, at least I haven’t found anything so far despite a very intensive search. Has anyone here perhaps already dealt with it or even created a functional ESPhome configuration?

There is enough space in the housing to install e.g. a LD2410C…





2 Likes

I downloaded the pro firmware. Running it through strings is interesting, but hasn’t yet told me what the display chip is.

Lvgl libraries are used.

Spi seems to be used to connect the display.

2 Likes

Hi,

Was just trying to do some reverse engineering on this hwd with same intention to use it with ESPhome this week end…
For the display connection I came-up with the following pins connection:

|1| GND
|2| GP0 → D/C
|3| GND → CS ? tied to GND
|4| GP14 → SCK
|5| GP13 → MOSI
|6| GP2 - > reset ?
|7| VCC
|8| GND
|9| GP5 → Back-light Anode through P MOSFet
|10| GND → Back-light Cathode

I’ll have a try tomorrow in esphome with something like:

esphome:
  name: small-tv
  friendly_name: small-tv

esp8266:
  board: esp12e

.../...

font:
  - file: 'OpenSans-Regular.ttf'
    id: font1
    size: 20
color:
    - id: color_green
      red: 0%
      green: 100%
      blue: 0%
spi:
  clk_pin: GPIO14
  mosi_pin: GPIO13

display:
  - platform: st7789v
    model: "Adafruit Funhouse 240x240"
    dc_pin: GPIO0
    reset_pin: GPIO02
    lambda: |-
      it.printf(0, 0, id(font1), id(color_green),"Test");

Wow, thanks! That mostly matches the pinout description of the display mentioned above:

grafik

Have been trying multiples things recently but not able yet to display something on the LCD yet :frowning_face:

For the st7789V we’ll have to go for sure with the 'custom" model to be able to tune the pins selection properly something like

spi:
  clk_pin: GPIO14
  mosi_pin: GPIO13
  interface: hardware
  id: spihwd

display:
  - platform: st7789v
    model: "Custom"
    spi_id: spihwd
    height: 240
    width: 240
    offset_height: 0
    offset_width: 0

But I am now having some doubt in regards to the pin selection. So far this option is not working

    dc_pin: GPIO00
    reset_pin: GPIO02
    backlight_pin: GPIO05

I’ll keep trying…

The only working feauture is the backlight


output:
  - platform: esp8266_pwm
    pin: GPIO05
    frequency: 1000 Hz
    id: pwm_output

light:
  - platform: monochromatic
    output: pwm_output
    name: "Backlight"

Edit :
I am also starting to question if the model type st7789 could not be another one like ST7796 which would require another driver usage (the ILI9xxx TFT LCD Series from ESPHome)

In addition, unsure this is related to my specific unit but got some issues to install the ESPhome firmware in place of the native one using the on-board UART connector footprint.
My ESP8266 Tx0 pin that somehow behaving strangely (damaged ??) with limited high level clamped to 1.5V. I had to workaround this using some external logic.
Now ESPhome is installed I can OTA my device.

Yes, I also tried a few things last night, but without any results.

I had a few crash-related reboots, but no output on the display… However, flashing the chip worked without any problems.

I’ve tried a lot today, but still - nothing. The backlight turns on, but that’s it. :-/

I’ve verified the GPIO <=> Display connector pinout, it’s correct as mentioned above.

This is the code I’m testing with:

substitutions:
  devicename: az-smalltv
  friendly_devicename: "Az SmallTV"

esphome:
  name: ${devicename}
  friendly_name: "${friendly_devicename}"

esp8266:
  board: esp12e

# Enable logging
logger:

# Enable Home Assistant API
api:
  encryption:
    key: !secret api_enc_key 

ota:
  password: !secret api_ota_password

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "${friendly_devicename} AP"
    password: !secret ap_wifi_password

#web_server:
#  port: 80

captive_portal:

time:
  - platform: homeassistant
    id: homeassistant_time

# Button entities
button:

  # Restart button
  - platform: restart
    name: "Neustart"

  # Restart button (safe mode)  
  - platform: safe_mode
    name: "Neustart (abgesicherter Modus)"

# Sensors with general information
sensor:

  # Uptime sensor
  - platform: uptime
    name: "Uptime"

  # WiFi Signal sensor
  - platform: wifi_signal
    name: "WiFi Signalstärke"
    update_interval: 60s

spi:
  clk_pin: GPIO14
  mosi_pin: GPIO13

display:
  - platform: st7789v
    model: Custom
    height: 120 # 240
    width: 120 # 240
    offset_height: 0
    offset_width: 0
#    eightbitcolor: True
    dc_pin: GPIO0
    reset_pin: GPIO2
    backlight_pin: 
      number: GPIO5
      inverted: True
    lambda: |-
      auto red = Color(255, 0, 0);
      auto green = Color(0, 255, 0);
      auto blue = Color(0, 0, 255);
      auto white = Color(255, 255, 255);
      it.rectangle(20, 50, 30, 30, white);
      it.rectangle(25, 55, 30, 30, red);
      it.rectangle(30, 60, 30, 30, green);
      it.rectangle(35, 65, 30, 30, blue);

Tried platform ili9xxx with model ILI9341, ILI9342 as well. No success.

The other models of this platform require ESP32 to compile.

Thanks

Same on my side have been doing multiple attempts today with no progress…

Trying multiple models of the ILI9xxx as well… (though limited number of them are usable with ESP8266 …)

Today received a clone version of the GEEKMAGIC:

Pins assignment for the LCD are exactly the same (but firmware version and display design a bit different).

Probing some signals on this functional version:
SPi clock is ~ 20MHz
GP0 is driving D/C mode pin of the LCD and active while refreshing display
GP2 is confirmed being RST and active only during init

Interestingly, this clone has also CH340 on-board USB to UART easing the flashing process …

1 Like

The GEEKMAGIC Author confirmed our findings here.

Unfortunately, I do not know why it still does not work.

The pro version states it is 240x240, so not sure that 120x120 will work. I cannot see the resolution mentioned in the non pro advertising. I assume that the pro and non pro hardware use the same screen (noting meantime that assumption is the mother of screwups)

And then we come to this, from the esphome docs.

Note
Displays larger than the 135x240 pixel display on the TTGO T-Display shown require a significant amount of RAM to operate correctly. Some ESP devices, such as the ESP8266, do not have sufficient memory to support this display. If you attempt to use this component and experience repeated crashes, this is likely the cause of the issue.

I know the screen works with esp8266 in the author’s native c++ code, but maybe esphome is not memory efficient enough?

Has anyone got a pro to play with? (just ordered one, but ali being ali, it won’t be here for a while)

See this note in the ESPhome st7789v docs:

Note

On memory-constrained devices, it may be possible to use part of the display area by specifying a smaller height and/or width than that of the actual display.

missed that bit.

Without a device I can’t play, but keep trying :slight_smile:

Finally got some progress today.
Comparing the SPI waveforms between the functional native firmware versus the EspHome generated, figured out the SCL line idle state was different…
Somehow CPOL:1 and CPHA:1 on the functional firmware (suspecting it could be related to the none usage of the CS pin).

Implementing a custom SPI setting in a custom st7789v component got the display behaving properly but still facing display size limitation probably due to not enough RAM in the ESP8266 and its implementation in ESPHome

Using 120x120 display is fine, but when trying with higher resolutions device has some spurious reboot suspecting memory leak or watchdog reset due to too long time spent in display update.
Still need to wok on it…

sharing my esphome fork with fixed st7789 component (st7789v_noCS branch) in case someone would like to investigate this also…

external_components:
  - source:
      type: git
      url: https://github.com/rletendu/esphome.git
      ref: st7789v_noCS
    components: [st7789v]
1 Like

Wow, that’s great! :slight_smile: Did you try the eightbitcolor option?

Yes and unfortunately the eightbitcolor option does not help…

Googling about this specific ST7789 with no CS and ESPhome looks like this a known issue:

Somehow other members end up with same fix changing the SPI mode as I did., they came up with same screen size limitation.

So the “smalltv pro” with ESP32 is the better choice…

1 Like

Well clearly…

Esp32 can be used for other things like bluetooth proxy.

Yes the pro version and its ESP32 is easier and offers some extra features.
Though since I have a couple of those cheaper versions I am trying to get a software fix.

Definitely the ESPHome display component implementation is not suitable for ESP8266 with 240x240 screens since this display requires ~50kB of RAM usage for buffer that we cannot afford on this SOC.
So I have been starting to implement a version without frame buffer that makes the display refresh significantly slower but usable.

I am still working on it and I’ll share my branch later on, but I am now able to get the 240x240 display being functional with so far the limitation of getting the refresh rate being very slow (about 2.5s).
But I think that I can accommodate this for my usage and I am also expecting to improve this to be in the range of <1s.

3 Likes

For the ones still interested in using the st7789 with 240x240 display and ESPHome here’s my updated version that will make it compatible with :

  • Hardware not using CS pin (like the GEEKMAGIC Smart Weather Clock)
    – If no cs_pin is declared the drivers will switch SPI to mode 3

  • ESP8266 and screen larger than 120x120
    – The ESP8266 does not have enough RAM to implement frame buffer
    – The implementation detects automatically if buffer ca be allocate (max 80% of heap) and deals with direct screen memory access instead without frame buffer allocation.

This implementation obviously adds some latency and the screen refresh being visible but still usable for most of my usage of this little unexpensive gadget with ESP home…

You’ll have to declare this external component version from my github fork

external_components:
  - source:
      type: git
      url: https://github.com/rletendu/esphome.git
      ref: st7789_no_frame_buffer
    refresh: 0s
    components: [st7789v]

And use it for example

font:
  - file: 'OpenSans-Regular.ttf'
    id: font1
    size: 30

color:
    - id: color_green
      red: 0%
      green: 100%
      blue: 0%

spi:
  clk_pin: GPIO14
  mosi_pin: GPIO13
  interface: hardware
  id: spihwd


output:
  - platform: esp8266_pwm
    pin: GPIO05
    frequency: 1000 Hz
    id: pwm_output

light:
  - platform: monochromatic
    output: pwm_output
    name: "Backlight"

display:
  - platform: st7789v
    model: "Custom"
    spi_id: spihwd
    height: 240
    width: 240
    offset_height: 0
    offset_width: 0
    dc_pin: GPIO00
    reset_pin: GPIO02
    backlight_pin: GPIO05
    id: disp

        
    lambda: |-
      static int num_executions;
      it.rectangle(0,  0, it.get_width()-1, it.get_height()-1, id(color_green));
      it.printf(0, 0, id(font1), id(color_green),"Uptime %f",id(my_uptime).state);
      it.printf(0, 40, id(font1), id(color_green),"Refresh count %i",num_executions);
      num_executions++;

Just in case it could help some of you landing on this page…

[edit] : The commit with modifications : Comparing esphome:dev...rletendu:st7789_no_frame_buffer · esphome/esphome · GitHub

1 Like

Wow, that’s great! :slight_smile:

I tried this code and it works, but the display flickers every 5s. Is this because of the missing frame buffer?

# GEEKMAGIC SmallTV
# https://community.home-assistant.io/t/installing-esphome-on-geekmagic-smart-weather-clock-smalltv-pro/
# https://www.youtube.com/watch?v=CEeD7_jAdUc

substitutions:
  devicename: az-smalltv
  friendly_devicename: "Az SmallTV"

esphome:
  name: ${devicename}
  friendly_name: "${friendly_devicename}"

esp8266:
  board: esp12e

# https://community.home-assistant.io/t/installing-esphome-on-geekmagic-smart-weather-clock-smalltv-pro/618029/19
external_components:
  - source:
      type: git
      url: https://github.com/rletendu/esphome.git
      ref: st7789_no_frame_buffer
    refresh: 0s
    components: [st7789v]

# Enable logging
logger:

# Enable Home Assistant API
api:
  encryption:
    key: !secret api_enc_key 

ota:
  password: !secret api_ota_password

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "${friendly_devicename} AP"
    password: !secret ap_wifi_password

#web_server:
#  port: 80

captive_portal:

time:
  - platform: homeassistant
    id: homeassistant_time

# Button entities
button:

  # Restart button
  - platform: restart
    name: "Neustart"

  # Restart button (safe mode)  
  - platform: safe_mode
    name: "Neustart (abgesicherter Modus)"

# Sensors with general information
sensor:

  # Uptime sensor
  - platform: uptime
    name: "Uptime"

  # WiFi Signal sensor
  - platform: wifi_signal
    name: "WiFi Signalstärke"
    update_interval: 60s

spi:
  clk_pin: GPIO14
  mosi_pin: GPIO13

display:
  - platform: st7789v
    model: Custom
    height: 240
    width: 240
    offset_height: 0
    offset_width: 0
    dc_pin: GPIO0
    reset_pin: GPIO2
    backlight_pin: 
      number: GPIO5
      inverted: True
    lambda: |-
      auto red = Color(255, 0, 0);
      auto green = Color(0, 255, 0);
      auto blue = Color(0, 0, 255);
      auto white = Color(255, 255, 255);
      it.rectangle(20, 50, 30, 30, white);
      it.rectangle(25, 55, 30, 30, red);
      it.rectangle(30, 60, 30, 30, green);
      it.rectangle(35, 65, 30, 30, blue);
      it.rectangle(0,  0, it.get_width()-1, it.get_height()-1, green);