Just bought new device DFROBOT DFR1221 1.85" round display - I can not find any info how to install esphome on it - any yaml examples ? thanks for help
https://wiki.dfrobot.com/SKU_DFR1221_ESP32_S3_1_85inch_Round_Display_Development_Board
Just bought new device DFROBOT DFR1221 1.85" round display - I can not find any info how to install esphome on it - any yaml examples ? thanks for help
https://wiki.dfrobot.com/SKU_DFR1221_ESP32_S3_1_85inch_Round_Display_Development_Board
I found this repo
- should work with DFR1221 V2.
When I opened it, there is sign :Guition JC3636W518" marked on the board.
The code from Marcin is for different hw. my model is V2 so I had to change GPIO for display and touch. below code with changed pins - this one is working ! ![]()
substitutions:
name: "dfr1221"
friendly_name: "DFRobot-round"
device_description: "ESP32S3-1.8-inch JC3636K518C"
project_name: "iritating.scrollwheel"
project_version: "6.6.6"
esphome:
name: "${name}"
friendly_name: "${friendly_name}"
project:
name: "${project_name}"
version: "${project_version}"
platformio_options:
board_build.flash_mode: dio
board_build.f_flash: 80000000L
board_build.f_cpu: 240000000L
esp32:
board: esp32-s3-devkitc-1
flash_size: 16MB
framework:
type: esp-idf
sdkconfig_options:
CONFIG_ESP32S3_DEFAULT_CPU_FREQ_240: "y"
CONFIG_ESP32S3_DATA_CACHE_64KB: "y"
CONFIG_ESP32S3_DATA_CACHE_LINE_64B: "y"
CONFIG_SPIRAM_FETCH_INSTRUCTIONS: y
CONFIG_SPIRAM_RODATA: y
psram:
mode: octal
logger:
api:
ota:
- platform: esphome
wifi:
ssid: xxx
password: xxx
ap:
ssid: "${friendly_name} Hotspot"
password: "fallbackPassw0rd"
spi:
id: display_qspi
type: quad
clk_pin: 9
data_pins: [11, 12, 13, 14]
i2c:
sda: 7
scl: 8
id: touchscreen_bus
# Deep sleep configuration - wakes up on encoder rotation
deep_sleep:
id: deep_sleep_control
esp32_ext1_wakeup:
mode: ANY_LOW
pins:
- number: GPIO20
allow_other_uses: true
- number: GPIO21
allow_other_uses: true
globals:
- id: current_page
type: int
restore_value: no
initial_value: '1'
- id: pending_cover_position
type: int
restore_value: no
initial_value: '0'
- id: cover_update_pending
type: bool
restore_value: no
initial_value: 'false'
- id: pending_led_brightness
type: int
restore_value: no
initial_value: '25' # 0
- id: led_update_pending
type: bool
restore_value: no
initial_value: 'false'
switch:
- platform: template
name: Antiburn
id: switch_antiburn
icon: mdi:television-shimmer
optimistic: true
entity_category: "config"
turn_on_action:
- logger.log: "Starting Antiburn"
- if:
condition: lvgl.is_paused
then:
- lvgl.resume:
- lvgl.widget.redraw:
- lvgl.pause:
show_snow: true
turn_off_action:
- logger.log: "Stopping Antiburn"
- if:
condition: lvgl.is_paused
then:
- lvgl.resume:
- lvgl.widget.redraw:
touchscreen:
platform: cst816
id: my_touchscreen
interrupt_pin: GPIO41
reset_pin: GPIO40
on_release:
- if:
condition: lvgl.is_paused
then:
- logger.log: "LVGL resuming from touch"
- lvgl.resume:
- lvgl.widget.redraw:
- light.turn_on: display_backlight
light:
- platform: monochromatic
id: display_backlight
name: "Backlight"
output: backlight_pwm
default_transition_length:
milliseconds: 30
initial_state:
brightness: 70%
restore_mode: ALWAYS_ON
font:
- file: "gfonts://Roboto"
id: roboto_20
size: 20
glyphsets:
- GF_Latin_Core
ignore_missing_glyphs: true # Add this line
- file: "gfonts://Roboto"
id: roboto_32
size: 32
glyphsets:
- GF_Latin_Core
ignore_missing_glyphs: true # Add this line
- file: "gfonts://Roboto"
id: roboto_88
size: 88
glyphsets:
- GF_Latin_Core
ignore_missing_glyphs: true # Add this line
output:
- platform: ledc
pin:
number: GPIO15
id: backlight_pwm
time:
- platform: homeassistant
id: homeassistant_time
timezone: Europe/Warsaw
on_time:
- hours: 2,3,4,5
minutes: 5
seconds: 0
then:
- switch.turn_on: switch_antiburn
- hours: 2,3,4,5
minutes: 35
seconds: 0
then:
- switch.turn_off: switch_antiburn
display:
- platform: qspi_dbi
id: my_display
model: CUSTOM
data_rate: 80MHz
color_order: rgb
dimensions:
height: 360
width: 360
cs_pin: 10
reset_pin: 47
invert_colors: true
auto_clear_enabled: false
init_sequence:
- [0xF0, 0x28]
- [0xF2, 0x28]
- [0x73, 0xF0]
- [0x7C, 0xD1]
- [0x83, 0xE0]
- [0x84, 0x61]
- [0xF2, 0x82]
- [0xF0, 0x00]
- [0xF0, 0x01]
- [0xF1, 0x01]
- [0xB0, 0x56]
- [0xB1, 0x4D]
- [0xB2, 0x24]
- [0xB4, 0x87]
- [0xB5, 0x44]
- [0xB6, 0x8B]
- [0xB7, 0x40]
- [0xB8, 0x86]
- [0xBA, 0x00]
- [0xBB, 0x08]
- [0xBC, 0x08]
- [0xBD, 0x00]
- [0xC0, 0x80]
- [0xC1, 0x10]
- [0xC2, 0x37]
- [0xC3, 0x80]
- [0xC4, 0x10]
- [0xC5, 0x37]
- [0xC6, 0xA9]
- [0xC7, 0x41]
- [0xC8, 0x01]
- [0xC9, 0xA9]
- [0xCA, 0x41]
- [0xCB, 0x01]
- [0xD0, 0x91]
- [0xD1, 0x68]
- [0xD2, 0x68]
- [0xF5, 0x00, 0xA5]
- [0xDD, 0x4F]
- [0xDE, 0x4F]
- [0xF1, 0x10]
- [0xF0, 0x00]
- [0xF0, 0x02]
- [
0xE0,
0xF0,
0x0A,
0x10,
0x09,
0x09,
0x36,
0x35,
0x33,
0x4A,
0x29,
0x15,
0x15,
0x2E,
0x34,
]
- [
0xE1,
0xF0,
0x0A,
0x0F,
0x08,
0x08,
0x05,
0x34,
0x33,
0x4A,
0x39,
0x15,
0x15,
0x2D,
0x33,
]
- [0xF0, 0x10]
- [0xF3, 0x10]
- [0xE0, 0x07]
- [0xE1, 0x00]
- [0xE2, 0x00]
- [0xE3, 0x00]
- [0xE4, 0xE0]
- [0xE5, 0x06]
- [0xE6, 0x21]
- [0xE7, 0x01]
- [0xE8, 0x05]
- [0xE9, 0x02]
- [0xEA, 0xDA]
- [0xEB, 0x00]
- [0xEC, 0x00]
- [0xED, 0x0F]
- [0xEE, 0x00]
- [0xEF, 0x00]
- [0xF8, 0x00]
- [0xF9, 0x00]
- [0xFA, 0x00]
- [0xFB, 0x00]
- [0xFC, 0x00]
- [0xFD, 0x00]
- [0xFE, 0x00]
- [0xFF, 0x00]
- [0x60, 0x40]
- [0x61, 0x04]
- [0x62, 0x00]
- [0x63, 0x42]
- [0x64, 0xD9]
- [0x65, 0x00]
- [0x66, 0x00]
- [0x67, 0x00]
- [0x68, 0x00]
- [0x69, 0x00]
- [0x6A, 0x00]
- [0x6B, 0x00]
- [0x70, 0x40]
- [0x71, 0x03]
- [0x72, 0x00]
- [0x73, 0x42]
- [0x74, 0xD8]
- [0x75, 0x00]
- [0x76, 0x00]
- [0x77, 0x00]
- [0x78, 0x00]
- [0x79, 0x00]
- [0x7A, 0x00]
- [0x7B, 0x00]
- [0x80, 0x48]
- [0x81, 0x00]
- [0x82, 0x06]
- [0x83, 0x02]
- [0x84, 0xD6]
- [0x85, 0x04]
- [0x86, 0x00]
- [0x87, 0x00]
- [0x88, 0x48]
- [0x89, 0x00]
- [0x8A, 0x08]
- [0x8B, 0x02]
- [0x8C, 0xD8]
- [0x8D, 0x04]
- [0x8E, 0x00]
- [0x8F, 0x00]
- [0x90, 0x48]
- [0x91, 0x00]
- [0x92, 0x0A]
- [0x93, 0x02]
- [0x94, 0xDA]
- [0x95, 0x04]
- [0x96, 0x00]
- [0x97, 0x00]
- [0x98, 0x48]
- [0x99, 0x00]
- [0x9A, 0x0C]
- [0x9B, 0x02]
- [0x9C, 0xDC]
- [0x9D, 0x04]
- [0x9E, 0x00]
- [0x9F, 0x00]
- [0xA0, 0x48]
- [0xA1, 0x00]
- [0xA2, 0x05]
- [0xA3, 0x02]
- [0xA4, 0xD5]
- [0xA5, 0x04]
- [0xA6, 0x00]
- [0xA7, 0x00]
- [0xA8, 0x48]
- [0xA9, 0x00]
- [0xAA, 0x07]
- [0xAB, 0x02]
- [0xAC, 0xD7]
- [0xAD, 0x04]
- [0xAE, 0x00]
- [0xAF, 0x00]
- [0xB0, 0x48]
- [0xB1, 0x00]
- [0xB2, 0x09]
- [0xB3, 0x02]
- [0xB4, 0xD9]
- [0xB5, 0x04]
- [0xB6, 0x00]
- [0xB7, 0x00]
- [0xB8, 0x48]
- [0xB9, 0x00]
- [0xBA, 0x0B]
- [0xBB, 0x02]
- [0xBC, 0xDB]
- [0xBD, 0x04]
- [0xBE, 0x00]
- [0xBF, 0x00]
- [0xC0, 0x10]
- [0xC1, 0x47]
- [0xC2, 0x56]
- [0xC3, 0x65]
- [0xC4, 0x74]
- [0xC5, 0x88]
- [0xC6, 0x99]
- [0xC7, 0x01]
- [0xC8, 0xBB]
- [0xC9, 0xAA]
- [0xD0, 0x10]
- [0xD1, 0x47]
- [0xD2, 0x56]
- [0xD3, 0x65]
- [0xD4, 0x74]
- [0xD5, 0x88]
- [0xD6, 0x99]
- [0xD7, 0x01]
- [0xD8, 0xBB]
- [0xD9, 0xAA]
- [0xF3, 0x01]
- [0xF0, 0x00]
- [0xF0, 0x01]
- [0xF1, 0x01]
- [0xA0, 0x0B]
- [0xA3, 0x2A]
- [0xA5, 0xC3]
- delay 1ms
- [0xA3, 0x2B]
- [0xA5, 0xC3]
- delay 1ms
- [0xA3, 0x2C]
- [0xA5, 0xC3]
- delay 1ms
- [0xA3, 0x2D]
- [0xA5, 0xC3]
- delay 1ms
- [0xA3, 0x2E]
- [0xA5, 0xC3]
- delay 1ms
- [0xA3, 0x2F]
- [0xA5, 0xC3]
- delay 1ms
- [0xA3, 0x30]
- [0xA5, 0xC3]
- delay 1ms
- [0xA3, 0x31]
- [0xA5, 0xC3]
- delay 1ms
- [0xA3, 0x32]
- [0xA5, 0xC3]
- delay 1ms
- [0xA3, 0x33]
- [0xA5, 0xC3]
- delay 1ms
- [0xA0, 0x09]
- [0xF1, 0x10]
- [0xF0, 0x00]
- [0x2A, 0x00, 0x00, 0x01, 0x67]
- [0x2B, 0x01, 0x68, 0x01, 0x68]
- [0x4D, 0x00]
- [0x4E, 0x00]
- [0x4F, 0x00]
- [0x4C, 0x01]
- delay 10ms
- [0x4C, 0x00]
- [0x2A, 0x00, 0x00, 0x01, 0x67]
- [0x2B, 0x00, 0x00, 0x01, 0x67]
- [0x3A, 0x55]
- [0x21, 0x00]
- [0x11, 0x00]
- delay 120ms
- [0x29, 0x00]
script:
- id: update_cover_position
mode: restart
then:
- delay: 500ms
- if:
condition:
lambda: 'return id(cover_update_pending);'
then:
- logger.log: "Sending cover position to HA"
- homeassistant.service:
service: cover.set_cover_position
data:
entity_id: cover.zaslona_salon
data_template:
position: !lambda 'return to_string(id(pending_cover_position));'
- lambda: 'id(cover_update_pending) = false;'
- id: update_led_brightness
mode: restart
then:
- delay: 500ms
- if:
condition:
lambda: 'return id(led_update_pending);'
then:
- logger.log: "Sending LED brightness to HA"
- homeassistant.service:
service: light.turn_on
data:
entity_id: light.0xa4c1388e095eafba
data_template:
brightness_pct: !lambda 'return to_string(id(pending_led_brightness));'
- lambda: 'id(led_update_pending) = false;'
binary_sensor:
- platform: gpio
id: encoder_pin_a
pin:
number: GPIO20
mode: INPUT_PULLUP
allow_other_uses: true
on_press:
- if:
condition:
lambda: 'return id(current_page) == 1;'
then:
# Page 1 - LED Brightness - Update local value and trigger delayed send
- lambda: |-
int current_brightness = id(led_update_pending) ? id(pending_led_brightness) : (int)id(ha_led_brightness).state;
int new_brightness = current_brightness - 5;
if (new_brightness < 0) new_brightness = 0;
id(pending_led_brightness) = new_brightness;
id(led_update_pending) = true;
- lvgl.label.update:
id: brightness_label
text: !lambda |-
static char buf[8];
snprintf(buf, sizeof(buf), "%d%%", id(pending_led_brightness));
return buf;
- script.execute: update_led_brightness
- if:
condition:
lambda: 'return id(current_page) == 2;'
then:
# Page 2 - Cover Position - Update local value and trigger delayed send
- lambda: |-
int current_pos = id(cover_update_pending) ? id(pending_cover_position) : (int)id(ha_zaslona_procent).state;
int new_pos = current_pos - 10;
if (new_pos < 0) new_pos = 0;
id(pending_cover_position) = new_pos;
id(cover_update_pending) = true;
- lvgl.label.update:
id: zaslona_value
text: !lambda |-
static char buf[8];
snprintf(buf, sizeof(buf), "%d%%", id(pending_cover_position));
return buf;
- script.execute: update_cover_position
- if:
condition: lvgl.is_paused
then:
- logger.log: "LVGL resuming from encoder"
- lvgl.resume:
- lvgl.widget.redraw:
- light.turn_on: display_backlight
- platform: gpio
id: encoder_pin_b
pin:
number: GPIO21
mode: INPUT_PULLUP
allow_other_uses: true
on_press:
- if:
condition:
lambda: 'return id(current_page) == 1;'
then:
# Page 1 - LED Brightness - Update local value and trigger delayed send
- lambda: |-
int current_brightness = id(led_update_pending) ? id(pending_led_brightness) : (int)id(ha_led_brightness).state;
int new_brightness = current_brightness + 5;
if (new_brightness > 100) new_brightness = 100;
id(pending_led_brightness) = new_brightness;
id(led_update_pending) = true;
- lvgl.label.update:
id: brightness_label
text: !lambda |-
static char buf[8];
snprintf(buf, sizeof(buf), "%d%%", id(pending_led_brightness));
return buf;
- script.execute: update_led_brightness
- if:
condition:
lambda: 'return id(current_page) == 2;'
then:
# Page 2 - Cover Position - Update local value and trigger delayed send
- lambda: |-
int current_pos = id(cover_update_pending) ? id(pending_cover_position) : (int)id(ha_zaslona_procent).state;
int new_pos = current_pos + 10;
if (new_pos > 100) new_pos = 100;
id(pending_cover_position) = new_pos;
id(cover_update_pending) = true;
- lvgl.label.update:
id: zaslona_value
text: !lambda |-
static char buf[8];
snprintf(buf, sizeof(buf), "%d%%", id(pending_cover_position));
return buf;
- script.execute: update_cover_position
- if:
condition: lvgl.is_paused
then:
- logger.log: "LVGL resuming from encoder"
- lvgl.resume:
- lvgl.widget.redraw:
- light.turn_on: display_backlight
number:
- platform: template
name: LED Brightness
id: led_brightness
optimistic: true
min_value: 0
max_value: 100
step: 1
unit_of_measurement: "%"
mode: slider
lvgl:
on_idle:
timeout: 30s
then:
- logger.log: "LVGL is idle - preparing for deep sleep"
# - light.turn_off: display_backlight
- lvgl.pause:
- delay: 1800s
- logger.log: "Entering deep sleep"
# - deep_sleep.enter: deep_sleep_control
pages:
# First Page
- id: page_1
widgets:
- obj:
id: background
x: 0
y: 0
width: 360
height: 360
bg_color: 0x000000
border_width: 0
pad_all: 0
- label:
id: led_name
align: top_mid
y: 40
text: "LED"
text_font: roboto_32
text_color: 0xFFFFFF
- label:
id: brightness_label
align: top_mid
y: 70
text_font: roboto_88
text_color: 0xFFFFFF
- label:
id: temperatura_name
align: top_mid
y: 200
text: "Temperatura"
text_font: roboto_20
text_color: 0xFFFFFF
- label:
id: temperatura_label
align: top_mid
y: 230
text_font: roboto_32
text_color: 0xFFFFFF
- label:
id: bateria_label
align: top_mid
y: 300
text_font: roboto_20
text_color: 0xFFFFFF
on_swipe_left:
- lambda: 'id(current_page) = 2;'
- lvgl.page.show:
id: page_2
animation: MOVE_LEFT
on_swipe_right:
- lambda: 'id(current_page) = 3;'
- lvgl.page.show:
id: page_3
animation: MOVE_RIGHT
- id: page_2
widgets:
- obj:
id: background1
x: 0
y: 0
width: 360
height: 360
bg_color: 0x000000
border_width: 0
pad_all: 0
- label:
id: zaslona_name
align: top_mid
y: 40
text: "Zasłona"
text_font: roboto_32
text_color: 0xFFFFFF
- label:
id: zaslona_value
align: top_mid
y: 70
text_font: roboto_88
text_color: 0xFFFFFF
- label:
id: temperatura_name1
align: top_mid
y: 200
text: "Temperatura"
text_font: roboto_20
text_color: 0xFFFFFF
- label:
id: temperatura_label1
align: top_mid
y: 230
text_font: roboto_32
text_color: 0xFFFFFF
- label:
id: bateria_label1
align: top_mid
y: 300
text_font: roboto_20
text_color: 0xFFFFFF
on_swipe_left:
- lambda: 'id(current_page) = 3;'
- lvgl.page.show:
id: page_3
animation: MOVE_LEFT
on_swipe_right:
- lambda: 'id(current_page) = 1;'
- lvgl.page.show:
id: page_1
animation: MOVE_RIGHT
# Page 3
- id: page_3
widgets:
- obj:
id: background2
x: 0
y: 0
width: 360
height: 360
bg_color: 0x000000
border_width: 0
pad_all: 0
- switch:
align: center
id: lampa_salon
on_click:
- homeassistant.service:
service: switch.toggle
data:
entity_id: switch.0x70b3d52b600fde27
on_swipe_left:
- lambda: 'id(current_page) = 1;'
- lvgl.page.show:
id: page_1
animation: MOVE_LEFT
on_swipe_right:
- lambda: 'id(current_page) = 2;'
- lvgl.page.show:
id: page_2
animation: MOVE_RIGHT
sensor:
- platform: homeassistant
id: ha_led_brightness
entity_id: light.0xa4c1388e095eafba
attribute: brightness
filters:
- filter_out: nan
- multiply: 0.392156863
on_value:
then:
- if:
condition:
lambda: 'return !isnan(x);'
then:
- lvgl.label.update:
id: brightness_label
text: !lambda |-
static char buf[8];
snprintf(buf, sizeof(buf), "%d%%", (int)x);
return buf;
- platform: homeassistant
id: ha_zaslona_procent
entity_id: cover.zaslona_salon
attribute: current_position
filters:
- filter_out: nan
on_value:
then:
- lvgl.label.update:
id: zaslona_value
text: !lambda |-
static char buf[8];
snprintf(buf, sizeof(buf), "%d%%", (int)x);
return buf;
- platform: homeassistant
id: ha_temperatura
entity_id: sensor.termometr_salon_temperature
on_value:
then:
- lvgl.label.update:
id: temperatura_label
text: !lambda |-
static char buf[16];
snprintf(buf, sizeof(buf), "%.1f°C", (float)x);
return buf;
- lvgl.label.update:
id: temperatura_label1
text: !lambda |-
static char buf[16];
snprintf(buf, sizeof(buf), "%.1f°C", (float)x);
return buf;
- platform: adc
pin: 1
name: "Battery Voltage"
id: battery_voltage
attenuation: 12db
accuracy_decimals: 2
update_interval: 1s
unit_of_measurement: "V"
icon: mdi:battery-medium
filters:
- multiply: 2.0
- median:
window_size: 7
send_every: 7
send_first_at: 7
- throttle: 1min
on_value:
then:
- component.update: battery_percentage
- platform: template
id: battery_percentage
name: "Battery Percentage"
lambda: return id(battery_voltage).state;
accuracy_decimals: 0
unit_of_measurement: "%"
icon: mdi:battery-medium
filters:
- calibrate_linear:
method: exact
datapoints:
- 2.80 -> 0.0
- 3.10 -> 10.0
- 3.30 -> 20.0
- 3.45 -> 30.0
- 3.60 -> 40.0
- 3.70 -> 50.0
- 3.75 -> 60.0
- 3.80 -> 70.0
- 3.90 -> 80.0
- 4.00 -> 90.0
- 4.20 -> 100.0
- lambda: |-
if (x > 100) return 100;
if (x < 0) return 0;
return x;
on_value:
then:
- lvgl.label.update:
id: bateria_label
text: !lambda |-
static char buf[8];
snprintf(buf, sizeof(buf), "%d%%", (int)x);
return buf;
- lvgl.label.update:
id: bateria_label1
text: !lambda |-
static char buf[8];
snprintf(buf, sizeof(buf), "%d%%", (int)x);
return buf;
- platform: homeassistant
id: lampa_ha
entity_id: switch.0x70b3d52b600fde27
on_value:
then:
- lvgl.widget.update:
id: lampa_salon
state:
checked: !lambda 'return id(lampa_ha).state != 0;'
This is my fork - repository …I will try fo add deep sleep functionality to DFR1221 V2
https://github.com/AdamM68/DFR1221-esphome-HA