New boards Wishlist
Support new device: Hosyond 4" ESP Screen
Per the response on the Home Assistant forum, here is the configuration for the Hosyond board. This is just for the 320x480 board, but it can easily be modified to support the other sized boards as well, assuming they share the same pin configuration.
Amazon listing for reference: https://www.amazon.com/Hosyond-320x480-ESP32-32E-Display-ST7796S/dp/B0FGJJ24S1
packages/boards/hosyond-esp32-4in.yaml | Click to expand
############################################################
# ESP Screens - Hosyond CYD board (ESP32-32E, "Cheap Yellow Display")
# Built-in ST7796 320x480 display and XPT2046 resistive touch.
#
# What is in here: the hardware (display, touch, backlight, LED), the sizes the
# shared tree takes from this board, the code the shared lambdas take from this
# board (hooks), and what only a CYD has: the calibration wizard for its
# resistive glass and a page swipe by LVGL's gesture. Everything else (the LVGL
# tree, the cards, the scripts, the entities) is packages/core.yaml, which every
# board shares; docs/PROFILES.md says how the files fit together.
#
# Entry file include this: packages/hosyond.yaml (the package a screen builds from over GitHub).
############################################################
# The cards of this board's grid: one per cell, from the file for 6 cells
# (tools/generate_cells.py writes them; docs/RESPONSIVE.md says why).
packages:
cells: !include ../cells/6.yaml
substitutions:
# A tap survives a finger that drifts up to this far (320 px over 58 mm: 1 cm); further is a swipe.
TOUCH_MOVE_LIMIT_PX: "56"
# Shortest contact that counts as a tap; a resistive panel bounces, a capacitive one does not.
TOUCH_MIN_PRESS_MS: "60"
# A slider let go this close to the left or right edge of the glass meant its end when that end lies in
# the band. The resistive panel reports a finger up to the bezel, so only the strip's last pixels and
# the margin beside them count (a capacitive Guition loses a fast finger 30-50 px before its edge).
SLIDER_EDGE_SNAP_PX: "20"
# The key of this board file; the firmware reports it so ESP Screens knows what board a screen is.
BOARD_ID: "cyd"
# This board's backlight takes levels (a PWM pin), so brightness is a percentage.
BACKLIGHT_DIMMABLE: "true"
# The screen can go dark: standby and night dim it, and Sleep and Wake exist.
CAN_STANDBY: "true"
DEVICE_NAME: "cyd-new"
DEVICE_FRIENDLY_NAME: "My CYD"
TOUCH_AFFINE_XX: "1.000000000"
TOUCH_AFFINE_XY: "0.000000000"
TOUCH_AFFINE_XC: "0.000000000"
TOUCH_AFFINE_YX: "0.000000000"
TOUCH_AFFINE_YY: "1.000000000"
TOUCH_AFFINE_YC: "0.000000000"
# ORIENTATION
# The panel's own pixels. The display block below always drives it at this size; LVGL turns the picture and
# the touch together, so nothing else on this board knows which way the glass hangs.
PANEL_W: "480"
PANEL_H: "320"
# The LVGL angle that lays this panel out lying down (320 x 480). Standing up is a quarter further.
ROTATION_LANDSCAPE: "90"
# Which way this screen hangs. ESP Screens writes it when the screen is built, the way it writes the language,
# and it is the only line that differs between a screen lying down and the same screen standing up.
LVGL_ROTATION: "${ROTATION_LANDSCAPE}"
TOUCH_SWAP_XY: "false"
# true on this board (resistive XPT2046) — was false on the 032c board
# (capacitive GT911). This is the original upstream value for this panel.
TOUCH_MIRROR_X: "false"
TOUCH_MIRROR_Y: "false"
TOUCH_CAL_X_MIN: "200"
TOUCH_CAL_X_MAX: "3900"
TOUCH_CAL_Y_MIN: "200"
TOUCH_CAL_Y_MAX: "3900"
# The tile grid: columns and rows of cells, the side margin and the gaps between cells. The shared tree places
# every cell from these (runtime_tiles::place_page), so a board with more room states more columns or rows.
GRID_COLS: "2"
GRID_ROWS: "3"
# The cells of a page when this screen stands up (firmware 0.2.92+).
# The 2.8-inch glass is 43 x 57 mm standing up: one column of four cards, each 39 x 10 mm.
GRID_COLS_PORTRAIT: "1"
GRID_ROWS_PORTRAIT: "4"
GRID_MARGIN: "9"
GRID_GAP_X: "8"
GRID_GAP_Y: "4"
DISPLAY_DPI: "143" # diagonal pixels / diagonal inches; the look's reference density on this board
LOOK: "compact"
SCROLL_Y: "40"
HEADER_Y: "14"
# Holding the top bar opens the settings page (0.2.44+). The whole strip counts on this board;
# a finger that travels further than the drift limit of a tap is swiping, not holding.
SETTINGS_HOLD_X: "0"
SETTINGS_HOLD_DRIFT_PX: "24"
ALERT_CARD_W: "292"
ALERT_CARD_H: "196"
ALERT_ICON_X: "18"
ALERT_ICON_Y: "16"
ALERT_TEXT_X: "62"
ALERT_TEXT_W: "212"
ALERT_TITLE_Y: "16"
ALERT_TITLE_H: "21" # one line of headline; a DOT label only ends in an ellipsis with a height
ALERT_SUBTITLE_Y: "44"
ALERT_SUBTITLE_H: "88"
ALERT_BUTTON_W: "100"
ALERT_BUTTON_H: "40"
ALERT_BUTTON_INSET: "14"
ALERT_TITLE_MAX: "48" # bytes; the label ends one line with an ellipsis
ALERT_BUTTON_MAX: "12" # bytes on the OK button
ALERT_SUBTITLE_MAX: "160" # bytes; wraps over the rows the card has
FONT_TIME_SIZE: "18" # the clock in the top bar
FONT_HEADLINE_SIZE: "18" # card titles
FONT_WATCH_VALUE_SIZE: "22"
FONT_CLOCK_DIGITS_SIZE: "24"
FONT_SETPOINT_SIZE: "40" # the climate card's setpoint
FONT_LABEL_SIZE: "11" # tile titles
FONT_SUBLABEL_SIZE: "11" # tile values and small text
FONT_SUBLABEL_BIG_SIZE: "14" # the top bar and settings rows
FONT_ICON_SIZE: "28" # tile icons
FONT_ICON_MINI_SIZE: "18" # the top bar and card keys
FONT_ICON_HOME_SIZE: "25" # the home key in the top bar
FONT_ICON_BIG_SIZE: "40" # full-page tiles
FONT_WATCH_ICON_SIZE: "12"
# Tiles and the top bar
TILE_RADIUS: "18" # corner of a tile
TILE_PAD: "8" # inside a tile
TILE_ICON_SIZE: "36" # the icon circle
HEADER_INSET: "11" # the room name and the clock from the glass edge
# The page bar under the tiles
PAGE_BAR_H: "36" # the page bar
PAGE_NUMBER_W: "104" # the dots in the middle
PAGE_CHEVRON_INSET: "14" # the chevrons from the outer edge
# Cards: the round keys and the brightness card
CARD_KEY_X: "10" # a card's round key from the side
CARD_KEY_Y: "8" # from the top
CARD_KEY_SIZE: "40" # its diameter
COLOR_TITLE_W: "210" # the colour card's title
COLOR_TITLE_Y: "21"
# The touch test page
TOUCH_TEST_PAGE_PAINT: "paint_calibration" # the page
TOUCH_TEST_TITLE: "calibration_title" # the words at the top
TOUCH_TEST_TITLE_FONT: "sublabel"
TOUCH_TEST_TITLE_Y: "65"
TOUCH_TEST_INSET: "10" # the corner crosses from the edge
TOUCH_TEST_SIZE: "20" # a cross
TOUCH_TEST_PAINT: "paint_calibration" # the crosses
# What the shared scripts do differently on this board
LVGL_DEFAULT_FONT: "sublabel_big" # LVGL's default font: every label names its own, so this only keeps Montserrat out of the build
LVGL_BUFFER_SIZE: "12%" # LVGL's draw buffer as a share of the screen
PAGE_DOTS_LARGE: "false" # bigger page dots
EFFECTS_ROW_FONT: "sublabel_big" # the effects page's rows
STANDBY_DIM_MS: "300" # how long the backlight takes to dim into standby (waking takes 300)
ALERT_FLASH_FADE_MS: "0" # an alert's flash: the fade of each step
ALERT_FLASH_DARK_MS: "120" # how long it stays dark
ALERT_FLASH_LIT_MS: "170" # how long it stays lit
# Code the shared lambdas of packages/core.yaml take from this board, at the place named ${...}: the
# exact lines the old profile had there. Empty when this board adds nothing at that place; every board
# must name every hook, or ESPHome stops at the undefined one.
# the first boot step: the touch guard, and what this board's panel needs
BOOT_TOUCH: |-
// Per-panel affine correction; shared defaults are neutral.
id(ts_touch).set_raw_correction(${TOUCH_AFFINE_XX}f, ${TOUCH_AFFINE_XY}f, ${TOUCH_AFFINE_XC}f, ${TOUCH_AFFINE_YX}f, ${TOUCH_AFFINE_YY}f, ${TOUCH_AFFINE_YC}f);
cyd::touch_guard.configure(${TOUCH_MOVE_LIMIT_PX}, ${TOUCH_MIN_PRESS_MS});
cyd::edge_snap_band = ${SLIDER_EDGE_SNAP_PX};
id(last_touch_ms) = millis();
id(last_use_ms) = millis();
id(display_dimmed) = false;
# right after runtime_tiles::enabled = true, before the settings load
BOOT_ENABLED_HOOK: ""
# the paint style only this board has (theme::paints)
BOARD_PAINT_FILL: "theme::fill(id(paint_calibration), Paint::calibration);"
# in runtime_tiles::dismiss, after the detail card closes
CLOSE_CARDS_HOOK: ""
# what LVGL's gesture over the tiles does on this board
BOOT_PAGE_GESTURE: |-
lv_obj_add_event_cb(id(home_page)->obj, [](lv_event_t *event) {
if(!runtime_tiles::enabled || !runtime_tiles::swipe_pages || id(display_dimmed) || id(calibration_active) ||
!id(active_entity).empty() || (runtime_tiles::detail_root && !lv_obj_has_flag(runtime_tiles::detail_root,LV_OBJ_FLAG_HIDDEN)))return;
auto *input=lv_indev_active();if(!input)return;
auto direction=lv_indev_get_gesture_dir(input);
if(direction!=LV_DIR_LEFT && direction!=LV_DIR_RIGHT && direction!=LV_DIR_TOP)return;
// A quick drag on a slider is that slider's, never a page swipe (firmware 0.2.68+).
if(runtime_tiles::captured_slider){ESP_LOGI("touch","page swipe ignored: a slider is being dragged");return;}
cyd::touch_guard.consume();
lv_indev_wait_release(input);
// Up is the way home (firmware 0.2.100+); this board has no edge band, so a flick anywhere over the tiles
// does it, as left and right do here.
if(direction==LV_DIR_TOP){
ESP_LOGI("touch","swipe up: back to page 1");
runtime_tiles::swipe_glow(runtime_tiles::Edge::bottom);
if(runtime_tiles::back_home)runtime_tiles::back_home();
return;
}
// The edge the page comes from lights up for a moment (firmware 0.2.100+): swiping left brings in the next
// page from the right.
runtime_tiles::swipe_glow(direction==LV_DIR_LEFT?runtime_tiles::Edge::right:runtime_tiles::Edge::left);
ESP_LOGI("touch","page swipe: page %d -> %d",id(tile_page),id(tile_page)+(direction==LV_DIR_LEFT?1:-1));
id(tile_page)+=direction==LV_DIR_LEFT?1:-1;
id(show_tile_page).execute();
}, LV_EVENT_GESTURE, nullptr);
# after the gesture: the camera images of a board that shows them
BOOT_CAMERA_HOOKS: ""
# after the cards' hooks, before the settings page's: the calibration wizard of a resistive panel, the fan and swing card of a big one
BOOT_CARDS_TAIL: |-
if (!runtime_tiles::enabled) return;
screen_calibration::apply = [](const screen_calibration::Calibration &cal) {
id(ts_touch).set_raw_correction(cal.c[0],cal.c[1],cal.c[2],cal.c[3],cal.c[4],cal.c[5]);
};
screen_calibration::isolation = [](bool active) { id(calibration_active) = active; };
screen_calibration::setup(id(home_page)->obj, id(sublabel)->get_lv_font(), id(headline)->get_lv_font(),
${TOUCH_CAL_X_MIN}, ${TOUCH_CAL_X_MAX}, ${TOUCH_CAL_Y_MIN}, ${TOUCH_CAL_Y_MAX});
// The wizard runs by itself the first time this panel starts; this is the way back to it (firmware 0.2.96+),
// the same one the Calibrate touch button in Home Assistant takes. Binding it is also what puts Calibrate
// touch on the settings page: a board that builds no wizard binds nothing and has no row, so the two can
// never disagree. The page closes first, as its own back arrow closes it: the wizard loads a screen of its
// own and leaves the home page behind it when it is done.
settings_screen::calibrate_touch = []() { settings_screen::close(); screen_calibration::begin(); };
# what else keeps the settings page closed (inline, in the condition)
MAY_OPEN_EXTRA: ""
# the log line of a boot onto the touch test page
TOUCH_TEST_READY_LOG: "USB calibration ready; no tile actions"
# one more line of the ui_state diagnostics
UI_STATE_HOOK: ""
# every 250 ms after runtime_tiles::tick()
TICK_HOOK: ""
# apply_screen_settings: how the backlight takes its level
APPLY_BACKLIGHT: "id(back_light).turn_on().set_transition_length(300).set_brightness(level / 100.0f).perform();"
# back_to_page_1_when_due: what else counts as away from page 1 (inline)
AWAY_EXTRA: ""
# alert_show: after the settings page closed, before the card is made
ALERT_SHOW_HOOK: ""
# ============================================================
# No need to edit below this line.
# ============================================================
esp32:
board: esp32dev
framework:
type: esp-idf
advanced:
# ESP-IDF's assert texts (file, line and condition of every check) stay out of the firmware (0.2.75+), 49 KB on
# the CYD: a failed assert still stops and restarts the screen, and its backtrace still points at the line.
# Every board sets it (tests/test_easy_package.py). ESP-IDF's error names stay: without them ESPHome's own
# error lines only say "UNKNOWN ERROR".
assertion_level: SILENT
# ESPHome recommends this itself in the boot log. Yields ~40KB extra IRAM
# and a smaller binary, and every KB counts on this board.
sram1_as_iram: true
# minimum_chip_revision deliberately left out: that was here for the
# 032c board (rev 3.1 confirmed), but this is a different physical board
# with an unknown chip revision. With an unjustifiably high minimum
# the firmware simply refuses to boot.
version: recommended
variant: esp32
# Two SPI buses used by the CYD:
# - lcd: built-in display
# - my_touchscreen: built-in touch controller
# Two SPI buses on the 2432S028: one for the display, a separate one for the
# resistive XPT2046 touch (no I2C on this board, unlike the 032c).
spi:
- id: lcd
clk_pin: GPIO14
mosi_pin: GPIO13
miso_pin: GPIO12
output:
- platform: ledc
pin: GPIO27 # Updated for Hosyond board. Was GPIO21
id: gpio_backlight_pwm
# ESPHome's ledc default is 1kHz. You don't see that while still (well
# above what the eye perceives as flicker), but moving the screen reveals
# motion blur turning the on/off pulses into streaks (the same effect as
# a PWM LED that "judders" when you move it). 20kHz sits well above the
# speed at which motion still makes that visible, and still leaves ample
# duty-cycle resolution left over for smooth dimming.
frequency: 20000Hz
- platform: ledc
id: output_red
pin: GPIO4
inverted: true
- platform: ledc
id: output_green
pin: GPIO16
inverted: true
- platform: ledc
id: output_blue
pin: GPIO17
inverted: true
light:
# The firmware owns the backlight: brightness, standby, night and alerts set it, and the minute tick
# restores it. Home Assistant uses the brightness numbers and the Wake and Sleep buttons (0.2.46+).
- platform: monochromatic
output: gpio_backlight_pwm
name: "Power Display Backlight"
id: back_light
internal: true
restore_mode: ALWAYS_ON
- platform: rgb
name: LED
red: output_red
id: led
green: output_green
blue: output_blue
restore_mode: ALWAYS_OFF
# Touchscreen configuration (XPT2046, resistive, via SPI)
# XPT2046 calibration is board-specific. Poll at 50Hz; LVGL rotates touch
# with the display. GPIO36 IRQ is deliberately unused (driver requests a
# pull-up that this input-only pin cannot provide).
touchscreen:
platform: xpt2046
id: ts_touch
spi_id: lcd
cs_pin: 33
# Polling avoids GPIO36 pull-up errors and noisy PENIRQ edges.
update_interval: 20ms
# Diagnosis caught a false corner contact at pressure 422. Deliberate
# contacts measured 936-2643; reject the low-pressure tail on release.
threshold: 800
calibration:
x_min: ${TOUCH_CAL_X_MIN}
x_max: ${TOUCH_CAL_X_MAX}
y_min: ${TOUCH_CAL_Y_MIN}
y_max: ${TOUCH_CAL_Y_MAX}
transform:
swap_xy: ${TOUCH_SWAP_XY}
mirror_x: ${TOUCH_MIRROR_X}
mirror_y: ${TOUCH_MIRROR_Y}
on_touch:
- lambda: |-
id(last_touch_ms) = millis();
id(last_use_ms) = millis();
id(touch_down) = true;
cyd::touch_guard.begin(millis(), touch.x, touch.y, touch.id);
// The point the screen itself works with, through ESPHome's own turn (the same call the tiles are hit
// with): the wizard fits against that, so it never has to work out what the turn does.
int screen_x = touch.x, screen_y = touch.y;
if (runtime_tiles::touch_input::to_screen) runtime_tiles::touch_input::to_screen(screen_x, screen_y);
screen_calibration::press(touch.id, screen_x, screen_y, id(ts_touch).filtered_raw_x(), id(ts_touch).filtered_raw_y());
ESP_LOGI("touch", "press native=%u,%u screen=%d,%d raw=%d,%d pressure=%d calibration=%d", touch.x, touch.y, screen_x, screen_y, id(ts_touch).filtered_raw_x(), id(ts_touch).filtered_raw_y(), touch.z_raw, id(calibration_active));
on_update:
- lambda: |-
id(last_touch_ms) = millis();
id(last_use_ms) = millis();
// Only the contact that started the touch counts; the guard ignores other ids.
for (const auto &point : touches) {
cyd::touch_guard.update(point.x, point.y, point.id);
// The wizard keeps both halves of a reading from the same instant (firmware 0.2.97+): where the screen
// puts this point, and what the panel is sending right now.
int screen_x = point.x, screen_y = point.y;
if (runtime_tiles::touch_input::to_screen) runtime_tiles::touch_input::to_screen(screen_x, screen_y);
screen_calibration::hold(point.id, screen_x, screen_y, id(ts_touch).filtered_raw_x(), id(ts_touch).filtered_raw_y());
}
on_release:
- lambda: |-
id(last_touch_ms) = millis();
id(last_use_ms) = millis();
id(touch_down) = false;
screen_calibration::release();
# Display configuration (ILI9341)
display:
- platform: mipi_spi
id: my_display
spi_id: lcd
model: ST7796
data_rate: 40MHz
cs_pin: GPIO15
dc_pin: GPIO2
invert_colors: false
update_interval: never
auto_clear_enabled: false
dimensions:
width: 320
height: 480
lvgl:
id: screen_lvgl
style_definitions:
# The calibration wizard's page and crosses (theme::paints fills it: BOARD_PAINT_FILL).
- id: paint_calibration
# Turning the screen as a Home Assistant choice (firmware 0.2.80+). This glass is not square, so it offers the half turn; a quarter turn would swap its width
# and height and change how many rows and columns fit. The shared tree applies the
# angle (packages/core.yaml); a list of options cannot come from a substitution, which is why every board carries this
# block and tools/check_packages.py keeps the three alike.
select:
- platform: template
id: setting_rotation
name: "Rotation"
icon: "mdi:screen-rotation"
entity_category: config
options: ["0°", "180°"]
update_interval: never
lambda: 'return std::to_string(settings_screen::rotation) + "°";'
set_action:
- lambda: |-
const std::string option(x.c_str(), x.size());
settings_screen::set("rotation", atoi(option.c_str()));
button:
- platform: template
name: "Calibrate touch"
internal: ${DASHBOARD_INBOX_INTERNAL}
entity_category: config
on_press:
- lambda: 'if (runtime_tiles::enabled) screen_calibration::begin();'
script:
# Render every overlay and both pages repeatedly without controlling devices.
- id: ui_self_test
mode: single
then:
- logger.log:
format: "UI_TEST START: page/overlay render stress, no HA actions"
level: INFO # the core logs from INFO; logger.log is DEBUG by default
- lambda: 'ESP_LOGI("ui_test", "Light sliders: %s", light_controls::self_test() ? "PASS" : "FAIL");'
- lambda: 'id(calibration_active) = false;'
- lvgl.page.show: home_page
- script.execute: wake_display
- repeat:
count: 10
then:
- lambda: |-
id(last_touch_ms) = millis();
id(last_use_ms) = millis();
static unsigned test_page=0;
id(tile_page) = runtime_tiles::enabled ? test_page++ % runtime_tiles::page_count() : 1;
- script.execute: show_tile_page
- delay: 300ms
- lambda: |-
lv_obj_update_layout(id(tile_scroll));
const int count = runtime_tiles::model.count;
// Wide cards take two slots, so visibility follows the runtime packing.
const bool paginated = runtime_tiles::enabled ? runtime_tiles::page_count() > 1 : count > 6;
// One card per cell of this board's grid: it is on screen when the page has a tile for its cell.
bool ok = true;
for (auto &w : runtime_tiles::widgets) {
bool visible = w.index < runtime_tiles::model.count;
ok = ok && w.tile && (lv_obj_has_flag(w.tile, LV_OBJ_FLAG_HIDDEN) != visible);
}
// The bar shows with more than one page, unless the Page buttons setting is off (firmware 0.2.69+).
const bool bar = paginated && (!runtime_tiles::enabled || settings_screen::page_buttons);
for (lv_obj_t* control : {id(page_prev), id(page_next), id(page_number)})
ok = ok && (lv_obj_has_flag(control, LV_OBJ_FLAG_HIDDEN) != bar);
lv_area_t nav, grid;
lv_obj_get_coords(id(page_next), &nav);
lv_obj_get_coords(id(tile_scroll), &grid);
ok = ok && (!bar || grid.y2 < nav.y1);
if(runtime_tiles::enabled)ok = runtime_tiles::check_tile_geometry() && ok;
ESP_LOGI("ui_test", "page_check=%s count=%d heap=%u frames=%u grid_bottom=%d nav_top=%d", ok ? "PASS" : "FAIL", count, (unsigned) esp_get_free_heap_size(), (unsigned) id(rendered_frames), (int) grid.y2, (int) nav.y1);
id(tile_page) = 0;
- script.execute: show_tile_page
- delay: 150ms
- lvgl.widget.show: color_detail_overlay
- delay: 150ms
- lvgl.widget.hide: color_detail_overlay
- lvgl.widget.show: alert_overlay
- delay: 150ms
- lvgl.widget.hide: alert_overlay
- lambda: 'if (!id(ui_refresh).is_running()) id(ui_refresh).execute();'
- logger.log:
format: "UI_TEST COMPLETE"
level: INFO
# The two scripts that drive the backlight as a light action; the Guition drives it through its set_backlight script.
- id: alert_dismiss
parameters:
reason: string
then:
- if:
condition:
lambda: 'return id(alert_active);'
then:
- lambda: |-
id(alert_active) = false;
id(last_touch_ms) = millis();
ESP_LOGI("alert", "dismissed: %s", reason.c_str());
- lvgl.widget.hide: alert_overlay
- script.stop: alert_timeout
- script.stop: alert_flash
- light.turn_on:
id: back_light
transition_length: 80ms
brightness: !lambda "return screen_settings::current.brightness / 100.0f;"
- script.execute:
id: alert_report
action: !lambda 'return reason;'
# Four backlight blinks when the alert arrives; the screen then stays on as usual.
- id: alert_flash
mode: restart
then:
- repeat:
count: 4
then:
- light.turn_off:
id: back_light
transition_length: 0s
- delay: 120ms
- light.turn_on:
id: back_light
transition_length: 0s
brightness: !lambda "return screen_settings::current.brightness / 100.0f;"
- delay: 170ms
- id: wake_display
mode: restart
then:
- lambda: |-
id(last_touch_ms) = millis();
id(display_dimmed) = false;
id(sleep_requested) = false;
- light.turn_on:
id: back_light
# Almost instant brightness-up. ESPHome's default is 1s, and that feels sluggish
# when you touch the screen and are waiting on light.
transition_length: 80ms
brightness: !lambda "return screen_settings::current.brightness / 100.0f;"
- lvgl.widget.hide: dim_wake_overlay
- script.execute: close_cards
packages/hosyond.yaml| Click to expand
# ESP Screens - the package a Hosyond CYD (ESP32-32E) builds from over GitHub. ESP Screen Manager writes every
# screen's own YAML with `packages: display: {url: <this repository>, files: [packages/cyd.yaml]}` and adds the
# name, the Wi-Fi reference and the unique keys (docs/EASY_SETUP.md); nothing of that lives here.
#
# The screen is two packages: core.yaml, which every board shares (the LVGL tree, the cards, the scripts, the
# entities), and boards/hosyond-esp32-4in.yaml with this board's hardware and sizes. docs/PROFILES.md says how the
# files fit together.
substitutions:
FONT_DIR: "https://raw.githubusercontent.com/MaxGramser/homeassistant_espscreen/main/fonts"
packages:
core: !include core.yaml
board: !include boards/hosyond-esp32-4in.yaml
external_components:
- source:
type: git
url: https://github.com/MaxGramser/homeassistant_espscreen.git
ref: main
path: components
refresh: 0s
components: [xpt2046, smart_display]
-Eric
Discussion 12
Add a commentCome posso utilizzare questi file? non riesco a capire dove inserire o copiare questi file. Grazie
Original on GitHub
If you are not familiar with where these files go or how to replace them, I would recommend waiting until Max incorporates these changes into the official build. Best to avoid messing up your Esp screen manager install.
-Eric
Original on GitHub
@afyounie thank you for the configuration, it made this quick. The Hosyond 4-inch ESP32-32E display is a board of its own in 0.3.13, which goes live in the coming hours:
@Crazyraf87 you don't need to copy any files: once 0.3.13 is out, update the add-on, open New screen, pick Hosyond 4 inch and flash it over USB from there.
I'll leave this issue open until someone has it running. If you try it, I'd love to hear what works and what doesn't, especially the touch after calibration and the colours.
Got a screen running? Tell others which board you have and what works on the Tessera website. It helps everyone pick a screen that works.
Like my work? Consider buying me a coffee, much appreciated!
Original on GitHub
· Edited
Hi, I'm facing the following issue at the backlight brightness settings: Step between 100% and 95% way too big 100% -> full brightness 95% -> way too dark, not easy to read even in dark environment. 0% to 95% -> The gradations look just right.
Screen FW: 0.13.0 Tessera: 0.4.22
Update: Same behavior on the CYD 2.8" display https://www.amazon.de/dp/B0FF4DTNCG
Original on GitHub
I have a screen calibration issue affecting only one corner. Could it be a firmware problem?
Original on GitHub
Can you elaborate a bit more about your problem?
Original on GitHub
I didn't notice that during my setup
Original on GitHub
I had this issue as well. I attribute it to the hardware as adjacent corners worked fine. I eventually got it to work by using my finger to tap the problem corner. Calibration completed and recognizes taps in the correct location.
Original on GitHub
I am experiencing this as well on both the Hosyond and the CYD 2.8. You should probably start a new issue ticket as this isn't specific to the Hosyond board.
Original on GitHub
@erbstueck @afyounie thanks for reporting this, and sorry it took a while. You were both right, and it was not the screen settings at all.
The backlight was driven at 20 kHz. The part on these boards that switches the backlight cannot keep up at that speed, so only 100 % (always on) looked right, and anything below came out far too dark. It now runs at 1 kHz on the CYD and on this Hosyond 4-inch board. I tested it on a CYD: 95 % now looks almost the same as 100 %, 50 % is clearly half, and even 5 % is still faintly visible, all without any flicker.
It is in ESP Screen Manager 0.4.48 (firmware 0.29.0):
I don't have a Hosyond myself, so I'd love to hear whether it now dims evenly on yours too.
Got a screen running? Tell others which board you have and what works on the Tessera website. It helps everyone pick a screen that works.
Like my work? Consider buying me a coffee, much appreciated!
Original on GitHub
Hi @MaxGramser, successfully tested on both Hosyond 4" and 2.8“ CYD. Works great, thanks for your effort.
Original on GitHub
I finally got a chance to test the latest update on the Hosyond 4 in. Screen brightness works perfectly. Screen configures perfectly with no issues. Thanks for adding the screen to the official release.
-Eric
Original on GitHub