I’ve seen a few posts about setting up the ESP32-C6 1.47in display (this one), available for about $20 on Amazon, and the mmwave LD2410c presence sensor, about $12 on Amazon. But I haven’t seen anything about getting the two of them set up together (which was a bit of grief, possibly related to my poor pin-soldering skills), and I haven’t seen anything about LVGL graphics on this display in ESPHome.
My goal was to hook up the presence sensor to the display, and have the display graph the moving and still energy levels every 2 seconds for each of the 8 default distance gates on the LD2410c. Nothing fancy; definitely a work in progress:
I had a lot of trouble getting the LD2410c to communicate using the dedicated TX/RX pins on the ESP32-C6; the ESP32 TX pin worked OK (I could tell it was transmitting by monitoring the LD2410c on the Android app connected via Bluetooth), but the ESP32 RX pin wouldn’t function. It is possible that my pin-soldering job caused this, but I solved it by moving the ESP32 RX lead to a GPIO pin (GPIO13 in my case).
I also had trouble getting LVGL graphics to work on the display, using the (deprecated?) ST7789v ESPHome display component, which most posts I’ve seen seem to mention. Instead, everything worked fine using the ili9xxx display component.
My hookup is
ESP32-C6 LD2410c
Pin 5v → Pin VCC
Pin Gnd → Pin Gnd
Pin Tx → Pin Rx
Pin 13 → Pin Tx
The “out” pin on the LD2410c is unnecessary (but can be used); it functions as a simple GPIO on/off binary sensor for presence.
In my code, I chose to include all of the sensors and switches available; obviously, they’re not all necessary and certainly don’t all have to be made accessible (to Home Assistant, for instance). You can monitor them via the web server. In order to get the graph to work on the display (in order for the LD2410c to output the individual gate data), Engineering Mode on the LD2410c has to be turned on (which I do programmatically on boot).
The code I’m pasting below should work out of the box, just inserting your encryption, ota, and fallback AP passwords. Here’s the ESPHome yaml code:
substitutions:
gate0: "10"
gate1: "48"
gate2: "85"
gate3: "123"
gate4: "160"
gate5: "198"
gate6: "235"
gate7: "273"
gate8: "310"
# gates (in meters) * 100/2 + 10; actual gates are 0, 0.75, 1.5, 2.25, 3, 3.75, 4.5, 5.25, 6 (meters)
esphome:
name: small-screen
friendly_name: Small screen
on_boot:
then:
- switch.turn_on: engineering_mode
esp32:
board: esp32-c6-devkitm-1
variant: esp32c6
framework:
type: esp-idf
sdkconfig_options:
CONFIG_ESPTOOLPY_FLASHSIZE_4MB: y
spi:
clk_pin: GPIO7
mosi_pin: GPIO6
display:
- platform: ili9xxx
id: my_display
model: ST7789V
dc_pin: GPIO15
cs_pin: GPIO14
reset_pin: GPIO21
invert_colors: true
show_test_card: false
dimensions:
height: 172
width: 320
offset_height: 34
offset_width: 0
transform:
swap_xy: true
mirror_x: false
mirror_y: true
color_order: bgr
# Define a PWM output on the ESP32
output:
- platform: ledc
pin: GPIO22
id: backlight_pwm
# Define a monochromatic, dimmable light for the backlight
light:
- platform: monochromatic
output: backlight_pwm
name: "Display Backlight"
id: back_light
restore_mode: ALWAYS_ON
interval:
- interval: 2sec
then:
- lvgl.line.update:
id: move_line
points:
- x: $gate0
y: !lambda return 172-int(id(g0_move).state);
- x: $gate1
y: !lambda return 172-int(id(g1_move).state);
- x: $gate2
y: !lambda return 172-int(id(g2_move).state);
- x: $gate3
y: !lambda return 172-int(id(g3_move).state);
- x: $gate4
y: !lambda return 172-int(id(g4_move).state);
- x: $gate5
y: !lambda return 172-int(id(g5_move).state);
- x: $gate6
y: !lambda return 172-int(id(g6_move).state);
- x: $gate7
y: !lambda return 172-int(id(g7_move).state);
- x: $gate8
y: !lambda return 172-int(id(g8_move).state);
- lvgl.line.update:
id: still_line
points:
- x: $gate0
y: !lambda return 172-int(id(g0_still).state);
- x: $gate1
y: !lambda return 172-int(id(g1_still).state);
- x: $gate2
y: !lambda return 172-int(id(g2_still).state);
- x: $gate3
y: !lambda return 172-int(id(g3_still).state);
- x: $gate4
y: !lambda return 172-int(id(g4_still).state);
- x: $gate5
y: !lambda return 172-int(id(g5_still).state);
- x: $gate6
y: !lambda return 172-int(id(g6_still).state);
- x: $gate7
y: !lambda return 172-int(id(g7_still).state);
- x: $gate8
y: !lambda return 172-int(id(g8_still).state);
lvgl:
pages:
bg_color: 0x000000
bg_opa: COVER
widgets:
- line:
id: move_line
points:
- $gate0,1
line_width: 3
line_color: 0x00FF00 # green
line_rounded: true
bg_opa: TRANSP
- line:
id: still_line
points:
- $gate0,1
line_width: 3
line_color: 0xFF0000 # red
line_rounded: true
bg_opa: TRANSP
###########################################################
uart:
tx_pin: TX
rx_pin: GPIO13 # I used this because I couldn't get the RX pin to work
parity: NONE
data_bits: 8
stop_bits: 1
baud_rate: 256000
ld2410:
id: ld2410_radar
binary_sensor:
- platform: ld2410
has_target:
name: Presence
has_moving_target:
name: Moving Target
has_still_target:
name: Still Target
out_pin_presence_status:
name: out pin presence status
sensor:
- platform: ld2410
light:
name: light
moving_distance:
name : Moving Distance
still_distance:
name: Still Distance
moving_energy:
name: Move Energy
still_energy:
name: Still Energy
detection_distance:
name: Detection Distance
g0:
move_energy:
name: g0 move energy
id: g0_move
still_energy:
name: g0 still energy
id: g0_still
g1:
move_energy:
name: g1 move energy
id: g1_move
still_energy:
name: g1 still energy
id: g1_still
g2:
move_energy:
name: g2 move energy
id: g2_move
still_energy:
name: g2 still energy
id: g2_still
g3:
move_energy:
name: g3 move energy
id: g3_move
still_energy:
name: g3 still energy
id: g3_still
g4:
move_energy:
name: g4 move energy
id: g4_move
still_energy:
name: g4 still energy
id: g4_still
g5:
move_energy:
name: g5 move energy
id: g5_move
still_energy:
name: g5 still energy
id: g5_still
g6:
move_energy:
name: g6 move energy
id: g6_move
still_energy:
name: g6 still energy
id: g6_still
g7:
move_energy:
name: g7 move energy
id: g7_move
still_energy:
name: g7 still energy
id: g7_still
g8:
move_energy:
name: g8 move energy
id: g8_move
still_energy:
name: g8 still energy
id: g8_still
switch:
- platform: ld2410
engineering_mode:
name: "engineering mode"
id: engineering_mode
number:
- platform: ld2410
timeout:
name: timeout
light_threshold:
name: light threshold
max_move_distance_gate:
name: max move distance gate
max_still_distance_gate:
name: max still distance gate
g0:
move_threshold:
name: g0 move threshold
still_threshold:
name: g0 still threshold
g1:
move_threshold:
name: g1 move threshold
still_threshold:
name: g1 still threshold
g2:
move_threshold:
name: g2 move threshold
still_threshold:
name: g2 still threshold
g3:
move_threshold:
name: g3 move threshold
still_threshold:
name: g3 still threshold
g4:
move_threshold:
name: g4 move threshold
still_threshold:
name: g4 still threshold
g5:
move_threshold:
name: g5 move threshold
still_threshold:
name: g5 still threshold
g6:
move_threshold:
name: g6 move threshold
still_threshold:
name: g6 still threshold
g7:
move_threshold:
name: g7 move threshold
still_threshold:
name: g7 still threshold
g8:
move_threshold:
name: g8 move threshold
still_threshold:
name: g8 still threshold
text_sensor:
- platform: ld2410
version:
name: "firmware version"
mac_address:
name: "mac address"
select:
- platform: ld2410
distance_resolution:
name: "distance resolution"
light_function:
name: light function
out_pin_level:
name: out pin level
button:
- platform: restart
icon: mdi:power-cycle
name: "ESP Reboot"
- platform: ld2410
restart:
name: "restart"
query_params:
name: query params
factory_reset:
name: "factory reset"
# Enable logging
logger:
baud_rate: 0
# Enable Home Assistant API
api:
encryption:
key: "your encryption key" # your encryption key has to be entered here
ota:
- platform: esphome
password: "your ota password" # your ota password has to be entered here
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
# Enable fallback hotspot (captive portal) in case wifi connection fails
ap:
ssid: "Small screen Fallback Hotspot"
password: "your fallback password" # your fallback password has to be entered here
captive_portal:
web_server:
port: 80