fshr

The musings of a grumpy hairless ape





ESPHome Presence Sensor

This guide is presented as-is with no guarantee or warranty as to it’s correctness, accuracy, or suitability for purpose. You use the information presented here at your own risk. Please see my general disclaimer for further details.

Introduction

If you’re looking to build a smart home with Home Assistant, one thing you’re most certainly going to need is devices, whether it’s a smart lightstrip, some smart plugs, or something more esoteric and specialised. For anyone searching through the likes of Amazon or Aliexpress there’s an ever growing range of devices available, whether you’re into Zigbee, Z=Wave, Matter, or a less common standard, and most “standard” devices are now pretty much plug-and-play out of the box on any smart home hub (assuming it supports your standard of choice).

But what if you want something a little different? What if you really want that Public Transport Countdown Timer, you absolutely must automate your ergonomic bed, or a robotic cat laser is more your thing - well you’re probably going to need to get a little more creative and do some smart home DIY.

As you may have noticed, all the links in the above paragraph aren’t entirely random, they’re all taken from the ESPHome Discord, specifically the “Show-Off” channel, where ESPHome users can show off their creations.

For the unintiated, ESPHome is a toolbox to allow the (relatively) easy creation of smart devices using off-the-shelf components. This typically means some kind of microcontroller (usually either an ESP32 or ESP8266 variant), and one or more components (sensor / input / output) to provide some means for that microcontroller to talk to the outside world. You then create a YAML configuration file describing what microcontroller and components you’re using and what you want them to do, and ESPHome uses that configuration file to build a custom firmware to run on your device.

The way you connect up the components can vary depending on your specific level of skill, from literal off-the-shelf boards which you connect together with patch cables, through to custom designed all-in-one boards with the specific components you require.

What Are We Building?

Now for the purposes of what we’re going to cover here, we’re staying simple, using off the shelf boards which we can hook up to create a fairly basic mmWave based presence sensor which we can then connect into Home Assistant to detect whether someone’s in the room.

A presence sensor differs from a normal motion sensor in that, while a motion sensor specifically works on motion - whenever it detects a movement it sends a Movement event, and when it stops detecting movement it stops sending events - a presense sensor works on the basis of presence, i.e. when it detects someone in the room, it sends a simple Presence event, and when the room is empty it sends a simple Clear event (they can even still detect presence if someone is asleep in bed for example).

Using mmWave for presence (vs IR or acoustic) also gives advantages in accuracy, plus in my experience mmWave can easily travel through a few mm of plastic, making it a lot easier to build into any other project.

What Are We Not Building?

I won’t be including any sort of case as part of this, this is just covering off a basic “get the sensor piece working”. If you do this, and subsequently design a case for it, let me know and I’ll pop a link to it here :-)


Requirements

If you want to follow along and build your own sensor you’ll need a few things…

A Working Home Assistant install

While you can use ESPHome devices standalone, or with anything which talks MQTT, I personally think that you’ll get the most out of your devices if you partner them with Home Assistant. ESPHome natively integrates with HA very well and it also opens up the ability to link into HA automations, etc.

An ESP32 Board

You’ll need some kind of controller board, preferably ESP32, with header pins attached. I recommend the Waveshare ESP32-S3-Zero-M, you should be able to pick them up for under £5 (ex shipping) from somewhere like Aliexpress. You’re free to use any other board, but the configs I’ll use here will be written for the ESP32-S3-Zero-M, so you’ll need to adapt them if you use anything else.

ESP32-S3-Zero-M
ESP32-S3-Zero-M

A mmWave Presence Sensor

You’ll need some kind of ESPHome supported presence sensor, again with header pins attached. Again I recommend the Hi-Link LD2420, and similar to the ESP32 you should be able to get one for around £2 (ex shipping) from Aliexpress. Also again, you can use a different sensor if you want, but the configs will be written for the LD2420, so you’ll need to adapt them if you use anything else.

LD2420
LD2420

Dupont Jumper Wires

You’ll need some wires to connect the ESP32 to the LD2420. I’d recommend to use “Dupont Jumper Wires (Female-Female)” as they’re preterminated with the right connectors to fit the header pins on the boards. For the purposes of this exercise the shortest and smallest set of cables will be fine (they normallly seem to come as minimum 10cm, and 40 connected wires [we need 4 wires for this]). Again, available for £1-2 from Aliexpress (or I’ve bought from eBay before).

Dupont Female-Female
Dupont Female-Female

A Suitable USB-C Cable

Power and initial programming for the ESP32 board is via a USB cable, specifically USB-C for the ESP32-S3-Zero-M. Depending on your computer’s USB ports (and potentially any external USB PSU you use), this means you’ll need either a USB-C to USB-C, or USB-C to USB-A cable to connect the ESP32 to your PC or PSU. Length depends on your particular requirement/preference, but it does need to be a power and data cable, some cheaper USB-C cables only connect power or data pins and not both.

USB-C to USB-A Cable
USB-C to USB-A Cable


ESPHome Install

Once you’ve got all of the above lined up, the next thing you’ll need is a working ESPHome install. For Home Assistant use you can run ESPHome in one of two ways:

Home Assistant Add-In

This installs the ESPHome Device Compiler as an Add-In within Home Assistant. This is the option I’m going to use for the remainder of this guide.

This has the advantages of:

  • It’s neatly integrated into the HA ecosystem
  • It gives you a nice web UI to manage everything with
  • HA prompts you to update ESPHome when a new release comes out
  • You don’t need to worry about a separate ESPHome install to manage
  • You can access it from just about any device with a browser (with the caveat below)

But the disadvantages of:

  • The initial firmware install is best done over a USB connection from the PC you’re working on. If you’re using the web UI this requires WebSerial support which is only available in a Chrome/Edge/Chromium based browser (also see caveat below!). It won’t work from Safafi, Firefox, etc., so you may need to install Chrome/Edge/Chromium if you don’t already have it.
  • The firmware build runs where the ESPHome install is, in this case on the Home Assistant server. Depending on what you’re using for HA this may mean slow compiles and/or higher CPU/RAM/Disk usage on the HA server.
  • This assumes you can install HA Add-Ons. If you’re running HA on Docker, or some other solution where you can’t run Add-Ons you may need to use the command line option.

Additional Caveat - WebSerial also has a requirement for an HTTPS connection to the web server making the serial connection. Unless your Home Assistant server has a valid local HTTPS certificate you won’t be able to make a WebSerial connection fromn the ESPHome Device Compiler.

Luckily ESPHome provide a hosted WebSerial interface at web.esphome.io which will allow us to build a firmware file in the ESPHome Device Compiler, and then separately upload it to the device.

Note this is only for the initial firmware install, and your firmware file stays local through the process.

Command Line

This installs the ESPHome Device Compiler using Docker, or as a local Python app (I would recommend the Python install). This is a more advanced usage for a first time install, so I won’t be using it in this guide, but you’re free to use it if you feel comfortable.

This has the advantages of:

  • The initial firmware install is best done over a USB connection from the PC you’re working on. As you’re running the ESPHome utility from the CLI you can likely access the USB port connection with little issue (you may need to put your account in the ‘dialout’ group in Linux).
  • The firmware build runs where the ESPHome install is, in this case on your PC. Depending on what your PC is you likely have a suitably performant PC to run the compiles quickly and without issue.
  • If you can use a CLI, can install Python, and can create a venv, you can run ESPHome, you don’t need anything else.

But the disadvantages of:

  • It’s not neatly integrated into the HA ecosystem
  • It (mainly) relies on using the CLI (you can run the WebUI locally, but then you may as well run it under HA)
  • You need to manually track new releases and update
  • It’s a separate install to HA that you need to manage
  • You can only use it on the PC it’s installed on (excepting if you have SSH access or similar)

Assumptions

Some of these are assumptions, some are closer to pre-reqs, and/or you may need to do more to get stuff working if you don’t have the following:

Local LAN

Both Home Assistant and ESPHome use mDNS extensively for discovery and stuff talking to each other. In practice, mDNS works best when everything is on the same layer 3 subnet / network / VLAN, and tends to fall over if stuff is sat on different sides of a gateway/router. You can get both HA and ESPHome working with a router between bits of the system, but it’s going to need extra work and configuration. For this guide I’m going to assume that you have everything on the same layer 3 subnet.

WiFI

In general, ESP32 devices connect to the network via WiFi. Therefore I’m going to assume that you have your “Local LAN” above on WiFi, and that you know the SSID and Password to connect to it!

General Technical Ability

It hopefully goes without saying that this is going to be a technical guide, and a general technical ability to know how to connect things up, plug things in, use a command line, write config files, etc. is required. This guide is presented as-is, and work and life commitments mean I unfortunately don’t have the time to answer basic questions of how to connect stuff up, or how to edit config files :-)

You’re Using The Components I’ve Listed

This guide isn’t written as a “set up anything on ESPHome”, it’s going to be written to be specific to what I’ve listed above. You’re free to change what you use and use different bits, but that means you’re also free to work out how to get it working yourself and fix your own issues!

ESPHome Setup

Before we do anything else, there’s one thing we need to do. Open your browser and connect to your Home Assistant instance. In the left hand toolbar click the “ESPHome Device Compiler” icon to open the ESPHome UI:

ESPHome Icon
ESPHome Icon

In the UI, go to the “Secrets” configuration page via the link in the top right of the window:

ESPHome Secrets
ESPHome Secrets

Update the configuration in there with your WiFi SSID and Password, and click “Save” (again top right of the window):

# Your Wi-Fi SSID and password
wifi_ssid: "YourSSIDHere"
wifi_password: "YourPasswordHere"

These are the credentials that the ESPHome Device Compiler is going to use when building your firmware. We will reference these “secrets” from your configuration file, and it saves having your WiFI details stored separately in every file.

New Device

Once the above is done it’s time to start setting up our new device. In the main ESPHome UI click the “New Device” button in the bottom right corner:

ESPHome New Device
ESPHome New Device

You will likely get a dialog stating that you need to connect the device via USB, that you’re not connecting over HTTPS, and that you can use ESPHome Web. We already know about this from Part 1, so just click “Continue”.

You’ll then be prompted to create a new configuration:

ESPHome Create Config
ESPHome Create Config

Note: What you enter here is quite important as this is used to set the device name advertised over mDNS on your network, and is then used by ESPHome and Home Assistant to find your device for management. This means that it needs to be unique, and it’s also a little fiddly to change after the fact.

I tend to set a name along the lines of “manufacturer-type-uniqueid” here (where the unique ID is the last 6 characters of the device MAC address), e.g. “m5stack-atom-echo-b70634”, but feel free to use what you want.

For the purposes of this guide I’m going to use “waveshare-mini-guide”, so enter that and click “Next”.

You’ll then be prompted to select a device type. We’re using an ESP32-S3, so click that option.

You should then see a new device card appear in the UI window behind the dialog and you’ll get a “Configuration Created” message along with a prompt to create an encryption key for Home Assistant. For now, we’re not going to use any OTA or API keys (you can define them later if you wish), so just click “Skip” to close the window.

Hopefully you should now see your new device card in the UI. It will have a red border (as it’s not on the network), and should have the name you set in the wizard:

ESPHome Device
ESPHome Device

Updating The Config

As part of running the New Device wizard ESPHome has created a basic configuration for us. However we’re serious technical enthusiasts here (!!) so before we do anything else we’re going to replace the config with something of our own. So in the ESPHome UI, on your new device card, click the “Edit” button to open the configuration editor.

In the editor, delete the generated configuration and replace with the following (we’ll go through what it does at the end):

###############################################################################

# Substitutions
substitutions:
  name: waveshare-mini-guide
  friendly_name: Waveshare Mini Guide

# ESPHome Basics
esphome:
  name: ${name}
  friendly_name: ${friendly_name}
  name_add_mac_suffix: false
  platformio_options:
    board_build.flash_mode: dio

# Board Configuration
esp32:
  board: esp32-s3-devkitc-1
  variant: esp32s3
  framework:
    type: esp-idf
    version: recommended
    sdkconfig_options:
      CONFIG_ESP32_S3_BOX_BOARD: "y"

psram:
  mode: quad
  speed: 80MHz

################################################################################

# Wifi Information
wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password
  ap:
    ssid: ${name}
    password: ${name}

captive_portal:

# Enable Home Assistant & ESPHome APIs
api:

ota:
  platform: esphome

# Enable logging
logger:

###############################################################################

# Home Assistant Buttons
button:
  - platform: shutdown
    name: "Shutdown"
  - platform: restart
    name: "Restart"
  - platform: safe_mode
    name: "Restart (Safe Mode)"

###############################################################################

“Save” the new configuration, and click the “X” in the top left to go back to the main UI.

You should see the name on the device card update to reflect the “friendly_name” we set above.

ESPHome Device 2
ESPHome Device 2

The First Firmware

We’re now going to build and upload the first firmware. In the UI on the device card, click the “three dots” and select “Install”. You’ll be prompted as to how you want to install the firmware on your device. As we’re going to use ESPHome Web, choose the “Manual Download” option.

All being well you’ll get a compiler window appear and it will start downloading the various frameworks and tools needed to build your firmware. Depending on the speed of your Home Assistant server this may take a while, so it’s a good opportunity to go do something else while it’s working (make a cup of tea, have lunch, go for a walk, etc.).

Useful Tip If you get errors during the firmware build which aren’t obviously down to a configuration error, it’s often worth cleaning the build files for the device (i.e. remove the temporary build files and start again). ESPHome will try and do this automatically if it detects that it’s needed, but it’s not 100% accurate.

To do this manually, on the device card click the “three dots” and select “Clean Build Files”. It’ll pop up a compiler window and run a manual clean. Once it’s done just try your build again and hopefully it should then work.

Once it’s built you’ll get a prompt to ask you which version you want to download, select “Factory Format” and your browser should download a file “waveshare-mini-guide.factory.bin” to wherever your downloads go. Find where this file is, you’re going to need it in a moment! You can then close the compiler window and go back to the main UI.

Installing the Firmware

Go ahead and plug the ESP32-S3-Mini into your computer (the computer you’re doing all this work on). Then go ahead and open a browser window (remember Chrome/Chromium based or Edge only) and go to web.esphome.io. You should see the ESPHome Web installer with a single card with a state of “Not Connected”:

ESPHome Web
ESPHome Web

At this point we need to put the ESP32 board into programming mode. On the board itself, on the top side of the board, next to the USB connector are a pair of buttons, one for “Boot” and another for “Reset”. They are marked with teeny, tiny letters which are almost impossible to see, so here’s a photo to help:

ESP32 Buttons
ESP32 Buttons

Very carefully hold down the “Boot” button, and while holding press the “Reset” button once. Wait a couple of seconds and then release the “Boot” button. The board should now be in programming mode.

In the web.esphome.io window, click the “Connect” button on the device card. You should get a pop-up that web.esphome.io wants to connect to a serial port:

ESPHome Web Connect
ESPHome Web Connect

Depending on your OS and configuration you will have different options here. In the above I’m using Debian and the option I want to use is the first one “USB JTAG”. Select the appropriate option and click “Connect”. (If you click away before clicking Connect you’ll get a pop-up about not selecting a port, just close the pop-up and try again).

If you don’t see a port, make sure the ESP32 board is properly connected, you’ve put it in programming mode, and you have the right permissions/drivers/etc to connect to USB serial devices. The “No Port Selected” dialog has some guidance on connectivity issues.

All being well, the board will connect and you’ll see the device card change to “Connected”:

ESPHome Web 2
ESPHome Web 2

Ignore the option for “Prepare for first use” and click the “Install” option. You’ll be prompted to choose a file, so click “Choose File” and browse to the “waveshare-mini-guide.factory.bin” file we built and downloaded earlier. With the file selected, click “Install” and wait while it installs the firmware.

All being well, you’ll get a “Configuration Installed” pop-up. You can just click “Close”.

To check the install has worked correctly, click the “Logs” option on the “ESP Device” card. then click the “Reset Device” option on the Logs window. You should hopefully see a whole bunch of device and ESPHome logs rush past, including seeing it connect to your WiFi, and hopefully at some point:

[11:57:50][I][safe_mode:041]: Boot seems successful; resetting boot loop counter
[11:57:50][D][esp32.preferences:114]: Saving 1 preferences to flash...
[11:57:50][D][esp32.preferences:142]: Saving 1 preferences to flash: 0 cached, 1 written, 0 failed

If you now switch back to your ESPHome Device Builder window you should (hopefully) see that it’s now connected to ESPHome:

ESPHome Device 3
ESPHome Device 3

If you’ve got this far and it’s worked….

Congratulations!! You’ve just built and installed your first ESPHome firmware!

If you want to keep the web.esphome.io window open to view logs you can, or you can now close it. We should now be able to see most logs by using the ESPHome Device Builder UI to view logs over the LAN. Just click the “Logs” option on the device card in the ESPHome Device Builder window and choose “Wirelessly”, and a logs window should open and start streaming logs from the device.

If at any point you’re doing troubleshooting and you need to see logging direct from the device (e.g. it’s not booting, or connecting to WiFI), then you can connect the board to your computer again, and use the logs view via web.esphome.io in your troubleshooting

Home Assistant Integration

If you’ve been keeping an eye on your Home Assistant dashboard through all of this, at some point (probably just after installing the firmware and rebooting) you should have seen a notification appear that a new device has been discovered. If you click the notification (or go to “Settings > Devices & Services > Integrations”) you should see that Home Assistant has automatically discovered your new device on the LAN and offered to Add it:

HA Integrations
HA Integrations

Go ahead and click “Add” and follow the prompts. When it’s done you should see an “ESPHome” integration appear in your Home Assistant dashboard. Click on the integration card and you should see your new ESPHome device listed:

HA Integrations ESPHome
HA Integrations ESPHome

Click on the “1 device” link under the device name, and you’ll be taken to the device page, which should look something like:

HA Integrations Device
HA Integrations Device

The three items under “Configuration” are the three Home Assistant Buttons we defined in our device config back at the start, and link across to those actions on the ESP32-S3-Mini (Restart / Safe Mode / Shutdown).

(You can now disconnect the ESP32 from your computer and plug it into a separate USB PSU, or disconnect it completely until the next part!)

Congratulations! You’ve now got a basic ESPHome device built and integrated into Home Assistant. Come back for Part 3 when we’ll add the LD2420 sensor and get presence working.


Config Walkthrough

If you want to know a little more about the config you just applied, here’s a quick walkthrough:

# Substitutions
substitutions:
  name: waveshare-mini-guide
  friendly_name: Waveshare Mini Guide

Substitutions are like variables, you can define them once and then reference them elsewhere in the file. Here we’re defining a device name, and a friendly name.

# ESPHome Basics
esphome:
  name: ${name}
  friendly_name: ${friendly_name}
  name_add_mac_suffix: false
  platformio_options:
    board_build.flash_mode: dio

This sets up the basics of ESPHome on the device, including setting a device name and friendly name. The device name set here is what’s used to generate the device mDNS name. The “platformio_options” are board specific options relating to how ESPHome builds and flashes the firmware.

# Board Configuration
esp32:
  board: esp32-s3-devkitc-1
  variant: esp32s3
  framework:
    type: esp-idf
    version: recommended
    sdkconfig_options:
      CONFIG_ESP32_S3_BOX_BOARD: "y"

psram:
  mode: quad
  speed: 80MHz

This sets the details of the board itself, including the board type (board & variant), as well as which framework we’re using (arduino or esp-idf), and options for that framework. ESP-IDF is the newer framework, but Arduino seems to have better device support in some areas.

# Wifi Information
wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password
  ap:
    ssid: ${name}
    password: ${name}

captive_portal:

Here we set our WiFi details (pulling SSID and password from the Secrets configuration), as well as enabling the backup AP and captive portal in case we can#t connect to WiFi (see the ESPHome docs for more details)

# Enable Home Assistant & ESPHome APIs
api:

ota:
  platform: esphome

# Enable logging
logger:

Here we’re enabling both the Home Assistant API (api:) and ESPHome Over-The-Air (OTA) support. These are needed if you want to manage the device over the LAN from Home Assistant and/or ESPHome respectively. We also enable the logger here so that we can view logs from the board wirelessly or over USB Serial.

# Home Assistant Buttons
button:
  - platform: shutdown
    name: "Shutdown"
  - platform: restart
    name: "Restart"
  - platform: safe_mode
    name: "Restart (Safe Mode)"

Finally we define a set of buttons to display in Home Assistant. The specific “platform” definitions map the buttons to those three functions

(Re)Introducing the Sensor

Before we do anything else, let’s quickly revisit the sensor we’re going to be connecting.

LD2420
LD2420

For the purposes of this guide, we’re going to be using the Hi-Link LD2420. This is a mmWave presence sensor, or in other words it bounces “radar” signals around the room to detect whether there’s anybody “present” within it’s field of view. That field of view is rated up to a distance of around 8m, with a detection angle of ±60°, and while not ideal for covering an entire room, for basic presence detection (e.g. is someone sat in front of it) it’s fine, and it’s simple enough to implement for what we’re doing here.

Connecting the Sensor

Based on the LD2420 documentation, the sensor can be used with either GPIO and UART interfaces, however ESPHome only supports the LD2420 via UART connections, so that’s what we’re going to be using (UART is essentially an RS232 style serial interface).

LD2420 Pins
LD2420 Pins

We’ll be connecting the LS2420 to our ESP32 via a set of Dupont Jumper Wires (Female-Female), and we’ll need 4 cables for the collection (joined or separated):

  • Power 3.3V (marked as 3V3)
  • Power Ground (marked as GND)
  • Serial TX (marked on the LD2420 as OT1)
  • Serial RX (marked on the LD2420 as RX)

As noted in the ESPHome documentation, the module pinouts for the LD2420 vary depending on the firmware version installed. So far, all of the boards I’ve had have been on a firmware later than 1.5.3 have have had Serial TX on OT1, so that is the connectivity I’ll be using here. If you end up with a board with an older firmware you may need to change your wiring.

Connecting the ESP32

Excepting the USB-C connector, the pad based GPIO pins, and the onboard LED and buttons, the ESP32-S3-Zero comes with 16 multipurpose connectors we can use for a variety of purposes, whether as UART, PWN, I2S, ADC, I2C, SPI, or GPIO.

ESP32-S3-Zero Pinout
ESP32-S3-Zero Pinout

The board does have a pair of preset UART0 pins (TX/RX), however as these can be useful for connecting a serial console for debugging we won’t use them for our sensor connection. In addition, the board has 5V, 3V3, and GND pins available for use. As the LS2420 is quite a light power draw we will use the 3V3 and GND pins to provide power to the sensor.

As noted above, we’ll be using the Dupont Jumper Wires to connect to the sensor, and we’ll use GPIOs 1 & 2 for the UART:

  • Power 3.3V (marked as 3V3)
  • Power Ground (marked as GND)
  • Serial TX (marked on the ESP32 as 1 / GP1 / GPIO1)
  • Serial RX (marked on the ESP32 as 2 / GP2 / GPIO2)

You can use any pair of the GPIO pins for TX/RX, I’ve chosen GP1/GP2 only as they’re close to the 3V3 & GND pins and so makes cabling easier.

Plugging Stuff In

Note/Warning 1 - Take care with the 3V3 & GND connections! While it’s only 3.3v DC it’s still possible to damage either the sensor or ESP32 if you connect them incorrectly! If the sensor doesn’t work, and starts to get warm/hot to the touch, you’ve probably got things hooked up wrong and you’re at risk of letting the white smoke out.

Note 2 - You need to cross connect the TX/RX pins between the boards. i.e. the TX on one side goes to RX on the other and vice versa. If you connect TX-TX and RX-RX it won’t work!

Note 3 - The board/sensor pinouts are sometimes shown and/or labelled from the other side of the board from side with the pins. Make sure you mentally flip the pins around in your head when connecting cables so you’re connected to the right pins!

So, with the ESP32 unplugged from power, go ahead and cable up the ESP32 and sensor. For my cabling I’ll be using Dupont wires with Brown, Red, Orange, & Yellow cables, but feel free to use whatever you have available. I’ll be connecting the boards as follows:

ESP32 Pin ESP32 Use Cable Colour LD2420 Use LD2420 Pin
GND Ground Brown Ground GND
3V3 3.3v Red 3.3v 3V3
1 TX Orange RX RX
2 RX Yellow TX OT1

If you’ve followed my colours and cabling your two boards should look like this:

LD2420 Cabling
LD2420 Cabling
ESP32 Cabling
ESP32 Cabling

Assuming you’re happy with your cabling, go ahead and plug the ESP32 into power and wait for it to start up.

To check that all is ok, open a browser page to your HomeAssistant install where you’ve installed ESPHome. Go to the “ESPHome Builder” page and check that your device is still present and is now “Online”".

ESPHome Device 3
ESPHome Device 3

If it shows as “Offline” and/or the ESP32 or LD2420 seem to be getting warm, you’ve possibly connected the cables incorrectly. Unplug the ESP32 and check all cabling before trying again. If you still have issues, unplug the jumper wires completely, and just try the ESP32 on it’s own. If it still doesn’t connect you may need to work through Part 2 again to reset the device.

To check the install has worked correctly, in ESPHome Builder click the “Logs” option on the “ESP Device” card. You should hopefully see a whole bunch of device and ESPHome logs rush past, including seeing it connect to your WiFi, and hopefully at some point:

[11:57:50][I][safe_mode:041]: Boot seems successful; resetting boot loop counter
[11:57:50][D][esp32.preferences:114]: Saving 1 preferences to flash...
[11:57:50][D][esp32.preferences:142]: Saving 1 preferences to flash: 0 cached, 1 written, 0 failed

If you get this far we’re ready to add some new config.

Updating The Config

As part of running through Part 2 we created a basic configuration for the ESP32 which got it booted, connected to WiFi, and talking to Home Assistant. However we’re now going to modify that configuration to include the pieces required for the LD2420 and presence detection.

So in the ESPHome UI, on your new device card, click the “Edit” button to open the configuration editor. In the editor, delete the current configuration and replace with the following (we’ll go through what it does at the end):

###############################################################################

substitutions:
  name: waveshare-mini-guide
  friendly_name: Waveshare Mini Guide Presence

esphome:
  name: ${name}
  friendly_name: ${friendly_name}
  name_add_mac_suffix: false
  platformio_options:
    board_build.flash_mode: dio

esp32:
  board: esp32-s3-devkitc-1
  variant: esp32s3
  framework:
    type: esp-idf
    version: recommended
    sdkconfig_options:
      CONFIG_ESP32_S3_BOX_BOARD: "y"
   
psram:
  mode: quad
  speed: 80MHz

################################################################################

# Wifi information
wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password
  ap:
    ssid: ${name}
    password: ${name}

captive_portal:

# Enable Home Assistant API
api:

ota:
  platform: esphome

# Enable logging
logger:

###############################################################################

uart:
  id: ld2420_uart
  tx_pin: GPIO1
  rx_pin: GPIO2
  baud_rate: 115200
  parity: NONE
  stop_bits: 1

ld2420:

###############################################################################

number:
  - platform: ld2420
    presence_timeout:
      name: Detection Presence Timeout
    min_gate_distance:
      name: Detection Gate Minimum
    max_gate_distance:
      name: Detection Gate Maximum

###############################################################################

button:
  - platform: shutdown
    name: "Shutdown"
  - platform: restart
    name: "Restart"
  - platform: safe_mode
    name: "Restart (Safe Mode)"

  - platform: factory_reset
    disabled_by_default: True
    name: "Factory Reset ESP"
    id: factory_reset_all

  - platform: ld2420
    apply_config:
      name: Apply Config
    factory_reset:
      name: Factory Reset
    restart_module:
      name: Restart Module
    revert_config:
      name: Undo Edits

select:
  - platform: ld2420
    operating_mode:
      name: Operating Mode

###############################################################################

binary_sensor:
  - platform: ld2420
    has_target:
      name: Presence

text_sensor:
  - platform: ld2420
    fw_version:
      name: LD2420 Firmware

sensor:
  - platform: ld2420
    moving_distance:
      name : Moving Distance

################################################################################

“Save” the new configuration, and click the “X” in the top left to go back to the main UI. You should see the name on the device card update to reflect the new “friendly_name” we set above.

The New Firmware

We’re now going to build and upload our updated firmware. In the UI on the device card, click the “three dots” and select “Install”. You’ll be prompted as to how you want to install the firmware on your device. As we’re now on the network we can choose “Wirelessly”. ESPHome will then build the firmware using the new config and deploy it to the ESP32 “OTA” (over the air).

To avoid issues with code dependencies, whenever you add or remove components from a configuration (e.g. the LD2420 component) ESPHome will force a clean of the build files and do a full (i.e. long) build from scratch.

Once the firmware is built and deployed you should hopefully see a whole bunch of device and ESPHome logs rush past, including seeing it connect to your WiFi, including hopefully at some point:

[11:08:55][C][uart.idf:159]: UART Bus 0:
[11:08:55][C][uart.idf:160]:   TX Pin: GPIO1
[11:08:55][C][uart.idf:161]:   RX Pin: GPIO2
[11:08:55][C][uart.idf:163]:   RX Buffer Size: 256
[11:08:55][C][uart.idf:165]:   Baud Rate: 115200 baud
[11:08:55][C][uart.idf:166]:   Data Bits: 8
[11:08:55][C][uart.idf:167]:   Parity: NONE
[11:08:55][C][uart.idf:168]:   Stop bits: 1

to show that it’s successfully configured the UART on the ESP32, and:

[11:08:55][C][ld2420:068]: LD2420:
[11:08:55][C][ld2420:069]:   Firmware Version :  v1.6.1

to show that it’s successfully found the LD2420 sensor.

If you instead see the following:

[11:05:05][W][ld2420:090]: LD2420 Firmware Version v0.0.0 and older are only supported in Simple Mode
[11:05:05][E][component:082]:   Component ld2420 is marked FAILED

then that (in my experience) tends to mean that the serial connections aren’t correct, so check your cabling and try again.

You should also start to see entries along the lines of:

[11:12:39][D][sensor:093]: 'Moving Distance': Sending state 59.00000 cm with 0 decimals of accuracy
[11:12:47][D][sensor:093]: 'Moving Distance': Sending state 105.00000 cm with 0 decimals of accuracy
[11:12:49][D][sensor:093]: 'Moving Distance': Sending state 36.00000 cm with 0 decimals of accuracy
[11:12:53][D][sensor:093]: 'Moving Distance': Sending state 86.00000 cm with 0 decimals of accuracy
[11:13:02][D][sensor:093]: 'Moving Distance': Sending state 21.00000 cm with 0 decimals of accuracy
[11:13:03][D][sensor:093]: 'Moving Distance': Sending state 50.00000 cm with 0 decimals of accuracy

This is the sensor detecting movement (probably yours) and sending a state with the (estimated) distance back to Home Assistant.

Home Assistant

If you’ve got this far and everything has worked, Congratulations!!.

The next step is to see what’s been updated on the Home Assistant side. If you open a new browser tab/page to your Home Assistant instance, and go to “Settings - Devices & services - ESPHome - Waveshare Mini Guide” (click the “1 device” link), you should see the device page for your ESP32 with (hopefully) some updates.

Under the “Sensors” section you should now see 2 new sensors for “Moving Distance” and “Presence”:"

HA Device Sensors
HA Device Sensors

  • Moving Distance - This is an estimate by the sensor of how far away the last seen movement was. Generally I’ve found that this is best taken as a general distance rather than an accurate number, in particular movement which is very close to, or very far from the sensor can confuse it and give inaccurate readings.
  • Presence - This is a true/false style flag as to whether the sensor has detected someone in it’s sensor zone. Note that unlike a motion sensor this isn’t motion detected, but true presence detected (i.e. it will only change with presence, not with motion).

Also under the “Configuration” section you should see a set of new controls:

HA Device Configuration
HA Device Configuration

  • Apply Config - Apply any configuraiton changes made below to the LD2420 (any changes made in HA won’t apply until you click this)
  • Detection Gate Maximum - The maximum distance for movement or presence detection. This is done in 70cm increments (i.e. 1 = 70cm, 2 = 1m40cm, etc.). Defaults to 12, i.e. 8.64m.
  • Detection Gate Minimum - The minimum distance for movement or presence detection. This is done in 70cm increments (i.e. 1 = 70cm, 2 = 1m40cm, etc.). Defaults to 0, i.e. 0cm.
  • Detection Presence Timeout - How long to wait after presence is “lost” before reporting presence as “clear”. Defaults to 30s.
  • Factory Reset - Reset the LD2420 to factory defaults.
  • Operating Mode - Can be used to change the mode of the sensor, e.g. for calibration. I’ve never set this to anything other than “Normal”. See ESPHome Docs for more details.
  • Undo Edits - Undo any changed you’ve made in the HA UI before you’ve done an “Apply Config”

The main controls of interest here are Detection Gate Maximum & Minimum. The sensor is quite sensitive to presence, and if pointing at a doorway or window will happily detect people walking past. Setting the “Detection Gate Maximum” to a lower number (remember multiples of 70cm) can help limit presence to just the area closer to the sensor.

Here’s a quick video showing the sensor in Home Assistant updating as I leave, wait, and then re-enter the room:

Congratulations! You’ve now got an ESPHome based presence sensor built and integrated into Home Assistant. It may be very rough and ready, and not something you would want to hang in your hallway, but hopefully this should give an idea of how to get into building your own ESPHome based devices:

  • If you have a 3D printer, why not design a case to take the ESP32 and LD2420 and sit it on a desk or table somewhere. The mmWave signal will happily work through a couple of mm of plastic, so it could easily be hidden away somewhere.
  • Add a mmWave sensor onto another ESPHome based device. For example, I pair them with ESP32 based eInk or LCD displays to trigger dynamic updates based on whether I’m in front of them or not.

And if you’ve got this far, thanks for reading, and maybe give some feedback via Mastodon!


Config Walkthrough

If you want to know a little more about the config you just applied, here’s another quick walkthrough:

substitutions:
  name: waveshare-mini-guide
  friendly_name: Waveshare Mini Guide Presence

Substitutions are like variables, you can define them once and then reference them elsewhere in the file. Here we’re defining a device name, and a friendly name.

esphome:
  name: ${name}
  friendly_name: ${friendly_name}
  name_add_mac_suffix: false
  platformio_options:
    board_build.flash_mode: dio

This sets up the basics of ESPHome on the device, including setting a device name and friendly name. The device name set here is what’s used to generate the device mDNS name. The “platformio_options” are board specific options relating to how ESPHome builds and flashes the firmware.

esp32:
  board: esp32-s3-devkitc-1
  variant: esp32s3
  framework:
    type: esp-idf
    version: recommended
    sdkconfig_options:
      CONFIG_ESP32_S3_BOX_BOARD: "y"
   
psram:
  mode: quad
  speed: 80MHz

This sets the details of the board itself, including the board type (board & variant), as well as which framework we’re using (arduino or esp-idf), and options for that framework. ESP-IDF is the newer framework, but Arduino seems to have better device support in some areas.

# Wifi information
wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password
  ap:
    ssid: ${name}
    password: ${name}

captive_portal:

Here we set our WiFi details (pulling SSID and password from the Secrets configuration), as well as enabling the backup AP and captive portal in case we can#t connect to WiFi (see the ESPHome docs for more details)

# Enable Home Assistant API
api:

ota:
  platform: esphome

# Enable logging
logger:

Here we’re enabling both the Home Assistant API (api:) and ESPHome Over-The-Air (OTA) support. These are needed if you want to manage the device over the LAN from Home Assistant and/or ESPHome respectively. We also enable the logger here so that we can view logs from the board wirelessly or over USB Serial.

All the new config is now after this point:

uart:
  id: ld2420_uart
  tx_pin: GPIO1
  rx_pin: GPIO2
  baud_rate: 115200
  parity: NONE
  stop_bits: 1

Configure the UART to talk to the LD2420. We give it a unique “id”, tell it the GPIO pins to use for TX/RX, and give it the required serial configuration.

ld2420:

Enable the LD2420 component

number:
  - platform: ld2420
    presence_timeout:
      name: Detection Presence Timeout
    min_gate_distance:
      name: Detection Gate Minimum
    max_gate_distance:
      name: Detection Gate Maximum

Add the controls for configuration of the detection gate and timeout. These will be visible in Home Assistant.

button:
  - platform: shutdown
    name: "Shutdown"
  - platform: restart
    name: "Restart"
  - platform: safe_mode
    name: "Restart (Safe Mode)"

  - platform: factory_reset
    disabled_by_default: True
    name: "Factory Reset ESP"
    id: factory_reset_all

  - platform: ld2420
    apply_config:
      name: Apply Config
    factory_reset:
      name: Factory Reset
    restart_module:
      name: Restart Module
    revert_config:
      name: Undo Edits

Here we define a set of buttons to display in Home Assistant. We have the previous buttons from the prior config (Shutdown, Restart, Safe Mode), plus some new buttons for the LD2420 and a main Factory Reset button (disabled).

select:
  - platform: ld2420
    operating_mode:
      name: Operating Mode

Add the control for selecting the LD2420 operating mode. This will be visible in Home Assistant.

binary_sensor:
  - platform: ld2420
    has_target:
      name: Presence

Add a binary (on/off) sensor for the presence detection. This will be visible in Home Assistant.

text_sensor:
  - platform: ld2420
    fw_version:
      name: LD2420 Firmware

Add a text sensor for the LD2420 firmware. This will be visible in Home Assistant.

sensor:
  - platform: ld2420
    moving_distance:
      name : Moving Distance

Add a generic sensor for the moving distance. This will be visible in Home Assistant.

Note: Any number/button/sensor defined with a platform of “ld2420” will automatically get linked back to that item in the LD2420 component, e.g. the binary Presence sensor will link into the presence state in the sensor and make it available in ESPHome and to Home Assistant.


Posted 10 January 2025

In HomeAutomation SmartHome HomeAssistant ESPHome Updated