A temperature and presence node with ESP32-C3, SHT30 and LD2410C radar
This page was translated automatically from Italian. Read the original
A commercial WiFi thermostat costs about thirty euros, often depends on an app and a cloud, and suffers from humidity in the bathroom. With an ESP32-C3 SuperMini, an SHT30 probe on a cable and, if you want, an LD2410C radar, you can build a node that measures temperature and humidity, knows if someone is in the room, and communicates with Home Assistant via MQTT or the ESPHome API. These are the sensor nodes of ORFHAn, but they also work standalone, with any home automation system.
What you need
| Component | Why | Indicative cost |
|---|---|---|
| ESP32-C3 SuperMini | small, WiFi, two free hardware serials | about €4 |
| SHT30 or SHT31 probe on a cable, IP65 or IP67 | steel head: withstands bathroom steam | about €4 |
| LD2410C Radar (optional) | detects even someone staying still, unlike a PIR | about €6 |
| Flush-mounted 230 V → 5 V power supply | one per room, inside the old thermostat box | about €15 |
Probes with the -F suffix have a PTFE membrane that protects the sensor without slowing down the reading. Branded modules cost much more than generic probes on a cable, and they offer nothing extra for home use.
The connections
The probe goes on the I²C: VCC to 3V3, GND to ground, SDA to GPIO8, SCL to GPIO9. Wire colors vary from one manufacturer to another: follow the labels.
The radar goes on a serial port: VCC to 5V, GND to ground, the radar’s TX to GPIO4 (the ESP32 input) and the radar’s RX to GPIO5. TX and RX are crossed: connecting them straight is the most common mistake, and the symptom is a radar that seems powered on but sends nothing. The radar requires 5 V of power, but its serial signals are 3.3 V and go directly to the ESP32. If you want to be sure, use a tester to measure the radar’s TX pin while powered: it should read about 3.3 V.
A warning about pins 8 and 9. On the ESP32-C3, these are boot pins: the chip reads them at power-on to decide how to start, and ESPHome flags this during compilation. It works with the I²C above, but it must be tested the right way: after uploading the firmware, unplug the USB, switch off and then switch on the power from the power supply, and check that the node restarts. If it doesn’t restart from a cold start, move the I²C to another pair of pins.
Power supply, in the wall box
The old thermostat’s flush-mount box is the natural home for the node, but 230 V and 5 V electronics coexist inside it. Use a certified module with declared galvanic isolation, fix it securely, and check that no 230 V conductor can touch the board. The node consumes very little: any 5 W module is sufficient.
Often, a four-wire cable from the old controller already arrives in the box. It can be reused, but first it must be disconnected from the controller, the voltage must be measured (it is not guaranteed to be 12 or 24 V), and you must figure out where the other end leads.
ESPHome configuration
The essentials lie in a few lines. This is a minimal skeleton, to be completed with WiFi, MQTT, or API:
esp32:
board: esp32-c3-devkitm-1
i2c:
sda: GPIO8
scl: GPIO9
uart:
rx_pin: GPIO4 # from the radar TX
tx_pin: GPIO5 # to the radar RX
baud_rate: 256000
parity: NONE
stop_bits: 1
ld2410:
sensor:
- platform: sht3xd
temperature:
name: "Temperatura"
humidity:
name: "Umidità"
update_interval: 60s
binary_sensor:
- platform: ld2410
has_target:
name: "Presenza"
In the project, the files are divided into three: the board model (pinout only), some packages containing the common logic (network, climate, presence), and one file for each node, containing the name, the room, and a few other details. For a new node, you only copy the node file; for a different module, you copy the model and change the pins.
Two tips that cost us time:
- A missing component is not an error. If a node does not have the probe, ESPHome writes at startup that the sensor is marked FAILED: this only means it is not responding, and those entities are not published. This way, the same firmware works for nodes with only the probe, only the radar, or both.
- If you only use MQTT, disable the API reboot. By default, the ESPHome API reboots the node if no client connects for 15 minutes, and with data on MQTT, that client never arrives. The symptom is a node that reboots every fifteen minutes with
No clients; rebootingin the log. This is resolved withreboot_timeout: 0sunderapi:.
To upload it for the first time, USB is enough. Some SuperMini clones do not have automatic reboot and get stuck on Connecting…: hold down BOOT, press and release RESET, then release BOOT. From the second time onwards, the firmware is updated via the network.
Presence: teaching the radar where the room ends
A 24 GHz radar sees through doors and thin walls: someone passing in the hallway is, to it, inside the room. For this reason, the node does not send raw distances to Home Assistant, but a single piece of already cleaned-up information: someone is inside (Presence) and is moving (Motion). The filter discards targets further than a threshold, which is measured with the node already mounted in its final position, via your phone, on the node’s web page:
- Center: stand directly under the sensor and take your first step. The node measures for ten seconds and tells you at what distance it sees you. This is used to understand if it actually sees you.
- Boundary: stand at the last point that should count as “inside”, for example on the door threshold, and take the second step. The threshold becomes the measured distance plus a tolerance, which is 30 cm by default, and remains saved even after a reboot.
- Verification: walk out the door, and presence should turn off within five seconds; walk back in, and it must turn back on.
If presence stays on while you are outside, lower the tolerance and repeat the second step. If it turns off while you are sitting near the door, increase it. In a large room, also check how far the radar looks: each LD2410C gate is worth 75 cm, and with gate 4 you reach 3.75 m.
The node already handles the radar bounces: it waits two seconds before changing state and five before declaring the room empty. Do not add another delay of a few seconds in Home Assistant: they would add up. Usage-related timings, such as turning off the light after ten minutes of absence, should instead remain in the automations. And if the radar does not respond, presence remains unknown, not off: an automation that must withstand a failure should be written based on “is on”, not on “is not off”.
Two radars, and the ESP8266
An ESP32-C3 can handle two radars, for example in a living room to monitor two directions: the second goes to GPIO20 (from its TX) and GPIO21 (to its RX). ESPHome supports it and it worked in the project, but online there are reports of instability, with status != 0x01 errors in the log. If you see them, the practical solution is a second node: it only costs a few euros.
An ESP8266 is fine for the probe alone. It can handle at most one radar, on its single hardware serial moved to other pins: at 256000 baud, a software serial loses data as soon as the WiFi interrupts it. Warning: ESPHome still accepts a configuration with two radars on an ESP8266 because it checks the schema and not the physics.
What is proven
- ESP32-C3 nodes with SHT3x probe and LD2410C radar: tested on hardware, including two radars on the same node and distance calibration.
- ESP8266 with radar: the configuration passes ESPHome checks, but has never been tested on a real module.
- Interval connection (the temperature-only node connects every three minutes, sends the values, and disconnects, so as not to occupy connections on the broker): compiled, not yet tested on a live node.
The complete ESPHome files, the design for the ESP8266, and the installation guide are in the ORFHAn repository.