Skip to content

Instantly share code, notes, and snippets.

@clydebarrow
Last active October 27, 2024 09:48
Show Gist options
  • Save clydebarrow/9d2cffd739cb844e9d6d5005fd29518d to your computer and use it in GitHub Desktop.
Save clydebarrow/9d2cffd739cb844e9d6d5005fd29518d to your computer and use it in GitHub Desktop.
LVGL watch face in ESPHome yaml
# Gitignore settings for ESPHome
# This is an example and may include too much for your use-case.
# You can modify this file to suit your needs.
/.esphome/
/secrets.yaml
/wifi.yaml
# Before asking any questions - read the docs!: https://deploy-preview-3510--esphome.netlify.app/components/lvgl.html
esphome:
name: t-embed
friendly_name: LVGL Test on T-Embed
platformio_options:
board_build.flash_mode: dio
esp32:
board: esp32-s3-devkitc-1
variant: esp32s3
framework:
type: esp-idf
logger:
level: DEBUG
hardware_uart: USB_SERIAL_JTAG
ota:
password: !secret ota_password
wifi: !include wifi.yaml
external_components:
- source: github://clydebarrow/esphome@lvgl
components: [ lvgl ]
power_supply:
- id: power_on
enable_on_boot: true
pin:
ignore_strapping_warning: true
number: GPIO46
spi:
clk_pin: GPIO12
mosi_pin: GPIO11
interface: hardware
output:
- platform: ledc
pin:
number: GPIO15
id: backlight_output
light:
- platform: monochromatic
output: backlight_output
name: LCD Backlight
id: led
restore_mode: ALWAYS_ON
default_transition_length: 0s
display:
- platform: ili9xxx
id: lcd_display
model: st7789v
dimensions:
height: 170
width: 320
offset_height: 35
offset_width: 0
transform:
swap_xy: true
mirror_x: false
mirror_y: true
data_rate: 80MHz
cs_pin: 10
dc_pin: GPIO13
reset_pin: GPIO9
update_interval: never
auto_clear_enabled: false
invert_colors: true
sensor:
- platform: rotary_encoder
name: "Rotary Encoder"
id: encoder
pin_a: 2
pin_b: 1
internal: true
binary_sensor:
- platform: gpio
id: pushbutton
name: Pushbutton
pin:
number: 0
inverted: true
ignore_strapping_warning: true
time:
- platform: sntp
id: time_comp
on_time_sync:
then:
- script.execute: time_update
script:
- id: time_update
then:
- lvgl.indicator.line.update:
id: minute_hand
value: !lambda |-
return id(time_comp).now().minute;
- lvgl.indicator.line.update:
id: hour_hand
value: !lambda |-
auto now = id(time_comp).now();
return std::fmod(now.hour, 12) * 60 + now.minute;
- lvgl.label.update:
id: date_label
text: !lambda |-
static const char * const mon_names[] = {"JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC"};
static char date_buf[8];
auto now = id(time_comp).now();
snprintf(date_buf, sizeof(date_buf), "%s %2d", mon_names[now.month-1], now.day_of_month);
return date_buf;
- lvgl.label.update:
id: day_label
text: !lambda |-
static const char * const day_names[] = {"SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT"};
return day_names[id(time_comp).now().day_of_week-1];
interval:
- interval: 1min
then:
- script.execute: time_update
lvgl:
log_level: INFO
rotary_encoders:
sensor: encoder
binary_sensor: pushbutton
group: general
color_depth: 16
bg_color: 0x0F0F0F
text_font: unscii_8
align: center
style_definitions:
- id: date_style
text_font: unscii_8
align: center
text_color: 0x000000
bg_opa: cover
radius: 4
pad_all: 2
widgets:
- obj: # Clock container
height: size_content
width: size_content
widgets:
- meter: # Gradient color arc
height: 160
width: 160
align: center
bg_color: 0
scales:
angle_range: 360
rotation: 255
range_from: 0
range_to: 12
ticks:
width: 35
count: 13
length: 8
indicators:
- ticks:
local: true
start_value: 0
end_value: 12
color_start: 0xFF0000
color_end: 0x0000FF
- meter:
height: 160
width: 160
align: center
bg_opa: TRANSP
text_color: 0xFFFFFF
scales:
- ticks:
width: 1
count: 61
length: 10
color: 0xFFFFFF
range_from: 0
range_to: 60
angle_range: 360
rotation: 270
indicators:
- line:
id: minute_hand
width: 3
color: 0xE0E0E0
r_mod: -1
-
angle_range: 330
rotation: 300
range_from: 1
range_to: 12
ticks:
width: 1
count: 12
length: 1
major:
stride: 1
width: 4
length: 8
color: 0xC0C0C0
label_gap: 6
- angle_range: 360
rotation: 270
range_from: 0
range_to: 720
indicators:
- line:
id: hour_hand
width: 4
color: 0xA0A0A0
r_mod: -20
- label:
styles: date_style
id: day_label
y: -20
- label:
id: date_label
styles: date_style
y: +20
@agillis
Copy link

agillis commented Apr 15, 2024

@clydebarrow Thanks for all your work on LVGL in esphome. Its coming along really well. Can you add the value_ofs_x and value_ofs_y properties to a button? I really like have the text offset a bit. I gives more room on the buttons for badges and other information. I can put in a formal features request if you want but this would be a request to update a feature that is not even released yet :)

@clydebarrow
Copy link
Author

@clydebarrow Thanks for all your work on LVGL in esphome. Its coming along really well. Can you add the value_ofs_x and value_ofs_y properties to a button?

No, that's not present in LVGL 8.4. I'll move to V9 when it's sufficiently stable.

@skykingjwc
Copy link

skykingjwc commented Jul 6, 2024

I'm building with the dev container 2024.7.0-dev and I'm getting this when building.

[ticks] is an invalid option for [indicators]

@clydebarrow
Copy link
Author

@skykingjwc
Copy link

It's tick_styles now. See https://deploy-preview-3678--esphome.netlify.app/components/lvgl.html#meter

Thanks. Not sure how I missed that one. Do you happen to know if the ILI9341 or ILI9342 (aka Cheap Yellow Display) will work with ESPHome and LVGL?
So far the yaml builds, but I just get a static or black screen depending on the resolution I set, and in the log it says "Component lvgl is marked FAILED". I tried a few of the "hello world" examples but they don't seem to be working.

@clowrey
Copy link

clowrey commented Jul 7, 2024

Yes it will work with them, lots of examples in the Esphome Discord server under the Display > LVGL sub thread.

@clydebarrow
Copy link
Author

clydebarrow commented Jul 7, 2024

Without PSRAM you will need to set buffer_size to 25%

@qnlbnsl
Copy link

qnlbnsl commented Jul 9, 2024

@clydebarrow is there a way to get a circular button on there? I was trying a sample for this but i was unable to get the button be a circle.

        - btn:
            group: my_group
            align: Left_MID
            radius: 65535
            clip_corner: True
            id: btn_id_3
            width: 70
            height: 70
            checkable: true
            widgets:
              - label:
                  align: center
                  text: "Previous"
            on_value:
              then:
                - lvgl.page.previous:
                    animation: OUT_LEFT
                    time: 300ms  

@clydebarrow
Copy link
Author

Did you try radius: 50%?

@qnlbnsl
Copy link

qnlbnsl commented Jul 9, 2024

Did you try radius: 50%?

that worked! Thanks for the prompt reply!

One more thing and i can move this to a separate discussion thread if need be.

Do you have a on select sort of feature? So if one uses rotary encoder to move between buttons then using a on_select where it can trigger a label update. This way on smaller screens we can have smaller buttons with icons and a description area.

EDIT: Found it. The on_focus action on the widget

@skykingjwc
Copy link

Yes it will work with them, lots of examples in the Esphome Discord server under the Display > LVGL sub thread.

Got it to work. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment