Содержание
Покопавшись в AliExpress, я наткнулся на вот такую интересную вещь. LILYGO T-Дисплей S3 AMOLED экранная доска. T-Display S3 — это плата для разработки с микроконтроллером ESP32-S3 и встроенным AMOLED-дисплеем, идеально подходящая для проектов IoT с ярким визуальным выводом и более чем достаточной вычислительной мощностью для небольших проектов.
В этой статье я делюсь своим процессом прошивки, настройки и рендеринга контента на этой плате разработки AMOLED с использованием механизма отображения ESPHome. Вы можете использовать его для передачи данных из Home Assistant, создания аккуратных дисплеев статуса и даже использовать его в качестве контроллера.
LILYGO T-Display-S3 AMOLED версия доступна на АлиЭкспресс а также Амазонка.
Различные версии LILYGO T-Display S3
Прежде чем углубляться дальше, важно отметить, что обе версии этой доски —Базовый и Трогать— почти одинаковы, с небольшими различиями в распиновке и функциях. Эти различия в первую очередь касаются сенсорной функциональности версии Touch, имеющей дополнительный Контакт Touch_INT на GPIO21 и Контакт включения питания на GPIO38 для поддержки сенсорного экрана, которого нет в базовой версии.
На данный момент версия 2.0 этой платы имеет следующую распиновку:
- LILYGO T-Display S3 AMOLED базовый
- ESP32-S3R8 Двухъядерный LX7
- AMOLED 1,91 дюйма 240×536
- КСПИ RM67162
- 16 МБ флэш-памяти, 8 МБ PSRAM
- Wi-Fi 802.11, БЛЕ 5.0
- LILYGO T-Display S3 AMOLED Touch
- ESP32-S3R8 Двухъядерный LX7
- AMOLED Touch 1,91 дюйма, 240×536
- КСПИ RM67162
- 16 МБ флэш-памяти, 8 МБ PSRAM
- Wi-Fi 802.11, БЛЕ 5.0
Это руководство основано на AMOLED базовая версия.
Начальная прошивка в ESPHome
Прежде чем мы сможем настроить компонент дисплея и фактически отображать объекты на этой плате, его необходимо инициализировать в ESPHome. Создайте новое устройство в ESPHome, назовите его как хотите и инициализируйте его с помощью следующего кода:
esphome:
name: lilygos3
friendly_name: LILYGO-S3 T-Display
platformio_options:
build_unflags: -Werror=all
board_build.flash_mode: dio
esp32:
board: esp32-s3-devkitc-1
variant: esp32s3
framework:
type: esp-idf
api:
encryption:
key: "XXXXX" #Replace
ota:
- platform: esphome
password: "XXXXX" #Replace
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
ap:
ssid: "S3 Fallback Hotspot"
password: "zQ9tuPKIfFMu"
logger:
После первой вспышки на экране ничего не будет отображаться. Поскольку мы не настроили распиновку для spi
и display
компоненты, плата просто загрузится, и вы сможете получить к ней беспроводной доступ из сети.
Следующим шагом будет настройка компонента дисплея, добавление текстового шрифта и отрисовка чего-нибудь простого с помощью механизма рендеринга дисплея ESPHome. Чтобы это работало, необходимо установить соответствующие контакты. Из официальных изображений распиновки видно, как должна выглядеть конфигурация Базовая версия LILYGO T-Display S3:
spi:
id: qspi_bus
type: quad
clk_pin: GPIO47
data_pins:
- GPIO18
- GPIO7
- GPIO48
- GPIO5
display:
- platform: qspi_amoled
model: RM67162
id: s3_display
update_interval: 1s
dimensions:
height: 536
width: 240
color_order: rgb
brightness: 255
cs_pin: GPIO6
reset_pin: GPIO17
rotation: 0
lambda: |-
it.print(10, 20, id(font_roboto), Color(255, 255, 255), "Hello, SmartHomeScene!");
#Add a simple Google Font
font:
- file: "gfonts://Roboto"
id: font_roboto
size: 20
Если вы видите что-то на дисплее, это означает, что ваша конфигурация правильна и работает:
Понимание механизма рендеринга дисплея ESPHome
Чтобы создать что-то полезное на LILYGO T-Display S3, ESPHome механизм рендеринга дисплея необходимо использовать. Этот движок может выполнять такие задачи, как рисование фигур, отображение текста с использованием пользовательских шрифтов и даже рендеринг изображений. Эта гибкость достигается за счет лямбда-системы ESPHome, которая позволяет писать код C++ для управления дисплеем.
В лямбде можно писать код как в любой лямбда в ESPHome. Отображаемым лямбда-выражениям дополнительно передается переменная с именем it
который представляет объект механизма рендеринга. При рендеринге координат отображения в ESPHome начало координат (0, 0) начинается с верхний левый угол экрана. Координаты X увеличиваются вправо, а координаты Y увеличиваются вниз. Цвета отображаются с использованием значений RGB, обычно в формате 1
где значения варьируются от 0 до 255 для каждого канала. Шрифты определяются путем указания шрифтов и размеров, что позволяет печатать текст в различных стилях. Изображения выводятся на дисплей с использованием растровых данных, обычно предварительно загружаемых или извлекаемых с помощью кода, и визуализируются на основе размещения координат.
Вот как выглядит красный круг с центром посередине, если использовать двух помощников, чтобы получить width
и height
экрана автоматически:
lambda: |-
// Draw a red circle in the middle of the display
it.filled_circle(it.get_width() / 2, it.get_height() / 2, 120, Color(255, 0, 0));
Поворот экрана
Прежде чем экран станет полностью полезным, важно понять параметр конфигурации вращения в ESPHome. Вы можете добавить rotation
на экран и установите для него значение 90
, 180
или 270
градусов, чтобы перевернуть компоненты на экране.
Очень важно отметить, что вращение тесно коррелировано с get_width()
и get_height()
помощники в ESPHome. Если установлено значение 90 или 270 градусов, ширина и высота меняются местами, то есть то, что раньше считалось шириной (более длинная ось), становится высотой, и наоборот. Это гарантирует правильную адаптацию размеров к ориентации дисплея, обеспечивая правильную визуализацию независимо от угла поворота.
Например, если я нарисую простой треугольник, охватывающий доступную ширину и высоту, начиная с координат 0, 0, вот как помощник повлияет на его размер:
Поскольку ширина и высота экрана (оси X и Y) выбираются динамически, размер треугольника будет варьироваться в зависимости от размеров дисплея. Помните об этом при рендеринге контента, поскольку это может повлиять на макет. Это поможет вам избежать разочарований и необходимости постоянно перепрошивать устройство во время тестирования.
Добавление шрифтов
Шрифты можно добавить в компонент отображения ESPHome, загрузив их локально или просто используя Google Шрифты. Вам необходимо назначить идентификаторы каждому шрифту, определить его размер и любые дополнительные символы, если это необходимо. Идентификатор вызывается в лямбда-функции компонента отображения, который отображает запрошенный вами текст с соответствующим шрифтом. Вот как можно определить шрифты:
font:
- file: "fonts/Comic Sans MS.ttf"
id: comic_sans_20
size: 20
bpp: 2
- file: "gfonts://Roboto"
id: roboto_20
size: 20
- file:
type: gfonts
family: Roboto
weight: 900
id: roboto_16
size: 16
....
Вы можете просмотреть дополнительные примеры и параметры конфигурации на странице ESPHome. Компонент шрифта.
Добавление изображений и значков
Подобно шрифтам, изображения можно загружать на устройства ESP32 с совместимыми экранами. Компонент изображения также требуется уникальный идентификатор, который вызывается в лямбда-функции компонента дисплея. Вот как можно определить и изменить размер изображений или значков:
image:
- file: "smarthomescene.png" #Local image
id: my_image
resize: 100x100
type: RGBA #full color image
image:
- file: mdi:alert-outline #MDI Icon
id: alert
resize: 80x80
image:
- file: https://esphome.io/_images/logo.png #URL image
id: esphome_logo
resize: 200x162
Например, предположим, что я хочу визуализировать локальное изображение в центре LILYGO T-Display S3. Мне нужно загрузить изображение в ESPHome
папка, где находится основной .yaml
файл находится. Или я мог бы использовать другую папку в этом каталоге.
display:
.......
lambda: |-
// Render the image in the center of the display
it.image(it.get_width() / 2 - 175, it.get_height() / 2 - 77, id(smarthomescene));
image:
- file: "the-logo.png"
id: smarthomescene
resize: 350x155
type: RGBA
Чтобы центрировать изображение на дисплее S3, вам необходимо вычислить смещение от центра дисплея, вычитая половину размеров изображения. Сначала разделите ширину дисплея на 2, чтобы получить горизонтальный центр. Затем вычтите половину ширины изображения, чтобы расположить его правильно. Например, с Изображение шириной 350 пикселей (the-logo.png), вы вычитаете 175 (половину ширины). То же самое относится и к вертикали: разделите высоту дисплея на 2 и вычтите половину высоты изображения (77 для изображения высотой 155 пикселей). Этот обеспечивает изображение центрируется по обеим осям.
Предоставление объектов из Home Assistant
Как и любое другое устройство ESPHome, вы можете разоблачать датчики и объекты от Home Assistant до LILYGO S3 и используйте его в качестве дисплея состояния или контроллера. Это может включать в себя любую сущность, которую вы пожелаете, желательно ту, для которой вы найдете полезную функциональность. Например, предположим, что я хочу использовать этот дисплей для демонстрации своего офиса. температура и влажность с красивыми иконками. Я хочу, чтобы они располагались горизонтально посередине экрана с правой стороны интересным и читаемым шрифтом. Я хочу, чтобы логотип был меньше слева:
Во-первых, мне нужно сделать два датчика из Home Assistant доступными для платы LILYGO, добавив это в конфигурацию:
sensor:
- platform: homeassistant
entity_id: sensor.office_sensor_temperature
id: office_temperature
name: "Office Temperature"
- platform: homeassistant
entity_id: sensor.office_sensor_humidity
id: office_humidity
name: "Office Humidity"
Далее мне нужно добавить шрифт и изображения (и значки) соответствующего размера. Размер 60×60 пикселей хорошо подходит для значков в моем примере, а сохранение изображения шириной 200 соответствует примерно половине экрана с некоторым пространством между ними:
font:
- file: "gfonts://Audiowide"
id: audiowide_font
size: 40
image:
- file: mdi:thermometer
id: temperature_icon
resize: 60x60
- file: mdi:water_percent
id: humidity_icon
resize: 60x60
- file: "the-logo.png"
id: smarthomescene
resize: 200x88
type: rgba
И, наконец, добавьте в код лямбду рендеринга дисплея. Эта функция использует get_height
помощник для чтения высоты экрана и использования его для центрирования изображения по вертикали (умная домашняя сцена). Остальная часть функции статически устанавливает координаты X и Y для датчиков с соответствующими шрифтами и позиционирует их на экране:
lambda: |-
int screen_height = it.get_height();
it.image(20, (screen_height - 88) / 2, id(smarthomescene));
it.image(260, 40, id(temperature_icon));
it.printf(320, 40, id(audiowide_font), Color(255, 255, 255), "%.1f°C", id(office_temperature).state);
it.image(260, 140, id(humidity_icon));
it.printf(320, 140, id(audiowide_font), Color(255, 255, 255), "%.1f%%", id(office_humidity).state);
Циклическое переключение нескольких страниц отображения
Компонент отображения ESPHome позволяет отображать несколько страниц с различным содержимым и циклически перебирать их по таймеру или по любым входным событиям. Поскольку AMOLED-дисплей LILYGO T-Display S3 оснащен двумя кнопками спереди, мы можем использовать одну из кнопок для изменения информации, отображаемой на экране. Первая кнопка использует GPIO0
который представляет собой связующую булавку, поэтому мы хотим этого избежать. Второй использует GPIO21
который можно бесплатно использовать в этой автоматизации.
В этом примере я создал вторую страницу с приветственным сообщением, сохранил исходную страницу с температурой и влажностью в качестве второй и создал третью страницу с некоторой базовой информацией о моем системном мониторе:
display:
- platform: qspi_amoled
...........
pages:
- id: page1
lambda: |-
it.printf(10, 100, id(audiowide_font), Color(255, 255, 255), "Hello SmartHomeScene!");
- id: page2
lambda: |-
int screen_height = it.get_height();
it.image(20, (screen_height - 88) / 2, id(logo));
it.image(260, 40, id(temperature_icon));
it.printf(320, 40, id(audiowide_font), Color(255, 255, 255), "%.1f°C", id(office_temperature).state);
it.image(260, 140, id(humidity_icon));
it.printf(320, 140, id(audiowide_font), Color(255, 255, 255), "%.1f%%", id(office_humidity).state);
- id: page3
lambda: |-
// CPU Usage
it.image(20, 20, id(cpu_icon)); // CPU icon
it.printf(100, 20, id(audiowide_font), Color(255, 255, 255), "CPU: %.1f%%", id(system_monitor_processor_use).state);
// Memory Usage
it.image(20, 100, id(memory_icon)); // Memory icon
it.printf(100, 100, id(audiowide_font), Color(255, 255, 255), "RAM: %.1fMB", id(system_monitor_memory_use).state);
// Disk Usage
it.image(20, 180, id(harddisk_icon)); // Disk icon
it.printf(100, 180, id(audiowide_font), Color(255, 255, 255), "DISK: %.1fGB", id(system_monitor_disk_use).state);
#Button on GPIO21 as trigger for page cycling
binary_sensor:
- platform: gpio
pin: GPIO21
name: "Page Switch Button"
on_press:
then:
- display.page.show_next: s3_display
- component.update: s3_display
# Fonts and icons for each image used
font:
- file: "gfonts://Audiowide"
id: audiowide_font
size: 40
image:
- file: mdi:thermometer
id: temperature_icon
resize: 60x60
- file: mdi:cpu-64-bit
id: cpu_icon
resize: 60x60
............
# Exposed sensors from Home Assistant
sensor:
- platform: homeassistant
entity_id: sensor.office_sensor_temperature
id: office_temperature
name: "Office Temperature"
name: "CPU Usage"
- platform: homeassistant
entity_id: sensor.system_monitor_memory_use
id: system_monitor_memory_use
name: "Memory Usage"
.............
Краткое содержание
Есть так много всего, что можно сделать с Механизм рендеринга дисплея ESPHome. Это мощный и гибкий инструмент, но его сложно использовать. По моему опыту, для получения желаемого эффекта требуется много перепрошивок, настроек и перепрошивок. Если этой статьи недостаточно для начала, я настоятельно рекомендую вам просмотреть официальную документацию и попытаться понять хотя бы самые основные параметры, прежде чем прошивать этот AMOLED-экран LILYGO T-Display S3.
Плата разработки LILYGO T-Display S3 AMOLED доступна на AliExpress и Amazon. Вот несколько ссылок, где можно приобрести это устройство:
После стольких изменений моего кода мне удалось отобразить некоторые интересные данные о настройке моего офиса. Вот полный конфиг из этой статьи:
Полный пример конфигурации (нажмите, чтобы развернуть)
esphome:
name: lilygos3
friendly_name: LILYGO-S3 T-Display
platformio_options:
build_unflags: -Werror=all
board_build.flash_mode: dio
esp32:
board: esp32-s3-devkitc-1
variant: esp32s3
framework:
type: esp-idf
api:
encryption:
key: "XXXXX"
ota:
- platform: esphome
password: "XXXXX"
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
ap:
ssid: "S3 Fallback Hotspot"
password: "XXXXX"
logger:
level: WARN
# Define QSPI interface for the AMOLED
spi:
id: qspi_bus
type: quad
clk_pin: GPIO47
data_pins:
- GPIO18 # TFT_D0
- GPIO7 # TFT_D1
- GPIO48 # TFT_D2
- GPIO5 # TFT_D3
# Configuration for the RM67162 AMOLED display
display:
- platform: qspi_amoled
model: RM67162
id: s3_display
update_interval: 10s
dimensions:
height: 536
width: 240
color_order: rgb
brightness: 255
cs_pin: GPIO6
reset_pin: GPIO17
rotation: 270
pages:
- id: page1
lambda: |-
it.printf(10, 100, id(audiowide_font), Color(255, 255, 255), "Hello SmartHomeScene!");
- id: page2
lambda: |-
int screen_height = it.get_height();
it.image(20, (screen_height - 88) / 2, id(logo));
it.image(260, 40, id(temperature_icon));
it.printf(320, 40, id(audiowide_font), Color(255, 255, 255), "%.1f°C", id(office_temperature).state);
it.image(260, 140, id(humidity_icon));
it.printf(320, 140, id(audiowide_font), Color(255, 255, 255), "%.1f%%", id(office_humidity).state);
- id: page3
lambda: |-
// CPU Usage
it.image(20, 20, id(cpu_icon)); // CPU icon
it.printf(100, 20, id(audiowide_font), Color(255, 255, 255), "CPU: %.1f%%", id(system_monitor_processor_use).state);
// Memory Usage
it.image(20, 100, id(memory_icon)); // Memory icon
it.printf(100, 100, id(audiowide_font), Color(255, 255, 255), "RAM: %.1fMB", id(system_monitor_memory_use).state);
// Disk Usage
it.image(20, 180, id(harddisk_icon)); // Disk icon
it.printf(100, 180, id(audiowide_font), Color(255, 255, 255), "DISK: %.1fGB", id(system_monitor_disk_use).state);
binary_sensor:
- platform: gpio
pin: GPIO21 # Button on GPIO21
name: "Page Switch Button"
on_press:
then:
- display.page.show_next: s3_display
- component.update: s3_display
font:
- file: "gfonts://Audiowide"
id: audiowide_font
size: 40
image:
- file: mdi:thermometer
id: temperature_icon
resize: 60x60
- file: mdi:water_percent
id: humidity_icon
resize: 60x60
- file: "the-logo.png"
id: logo
resize: 200x88
type: rgba
- file: mdi:tape-drive
id: harddisk_icon
resize: 60x60
- file: mdi:memory
id: memory_icon
resize: 60x60
- file: mdi:cpu-64-bit
id: cpu_icon
resize: 60x60
sensor:
- platform: homeassistant
entity_id: sensor.office_sensor_temperature
id: office_temperature
name: "Office Temperature"
- platform: homeassistant
entity_id: sensor.office_sensor_humidity
id: office_humidity
name: "Office Humidity"
- platform: homeassistant
entity_id: sensor.system_monitor_processor_use
id: system_monitor_processor_use
name: "CPU Usage"
- platform: homeassistant
entity_id: sensor.system_monitor_memory_use
id: system_monitor_memory_use
name: "Memory Usage"
- platform: homeassistant
entity_id: sensor.system_monitor_disk_use
id: system_monitor_disk_use
name: "Disk Usage"
#Toggle green LED under the left button
light:
- platform: binary #Toggle green LED under the left button
name: "Green LED"
output: green_led
output:
- platform: gpio
pin: GPIO38
id: green_led