DIY Sensors with ESP32 and ESPHome

A temperature/humidity sensor you built yourself, flashed with no C++ required, reporting straight into Home Assistant with no cloud service in the middle.

What you'll build and why

ESPHome compiles a YAML configuration file into real firmware for an ESP32, handling the sensor-reading and networking code for you -- no C++ required for a standard sensor like this one. Once flashed, the device reports directly into Home Assistant (the prerequisite guide) via ESPHome's native integration, with no cloud service anywhere in the chain -- the data never leaves your network.

Don't build this if: you just want a temperature reading and don't care about integrating it with home automation -- a standalone commercial sensor might be simpler for that narrow case. This guide's value is specifically in feeding real sensor data into Home Assistant for automations.

How it works

  DHT22 sensor  --  wired to the ESP32's GPIO pins
│
▼
ESP32 (running ESPHome firmware)  --  reads the
│                                sensor, connects
│                                to your Wi-Fi
│
│  ESPHome's native API (local network,
│  no cloud involved)
▼
Home Assistant  --  auto-discovers the ESPHome
device, exposes its sensor
readings as entities you can
use in automations/dashboards

ESPHome's native API integration with Home Assistant means the device announces itself on your local network and Home Assistant picks it up automatically -- no separate MQTT broker setup required for this specific path (ESPHome also supports MQTT if you have a specific reason to use it instead, but the native API is the more direct route for a Home-Assistant-first setup).

Before you start

Decision: ESPHome's native API or MQTT? This guide uses ESPHome's native API integration -- simpler, one fewer service to run, and the default recommended path when Home Assistant is your target. MQTT is worth choosing instead if you have other non-Home-Assistant systems that also need this sensor's data, since MQTT is a more general publish/subscribe system multiple consumers can use.

Steps

Step 1: Install the ESPHome dashboard

Easiest as a Home Assistant add-on if you're running Supervisor-enabled Home Assistant (Settings → Add-ons → Add-on Store → ESPHome). Alternatively, standalone via Docker:

services:
esphome:
image: ghcr.io/esphome/esphome:latest
container_name: esphome
network_mode: host
volumes:
- "./esphome-config:/config"
restart: unless-stopped

network_mode: host is needed for ESPHome's device discovery to work correctly on your LAN.

Step 2: Wire the DHT22 to the ESP32

DHT22 data pin to an ESP32 GPIO pin (commonly GPIO4, but check your specific board's pinout), VCC to 3.3V, GND to ground. A pull-up resistor between data and VCC is commonly recommended for DHT22 -- check your specific sensor module's documentation, since some breakout boards include this built in already.

Step 3: Create the device configuration

In the ESPHome dashboard, New Device, name it, select ESP32. This generates a base YAML config -- extend it with the sensor:

esphome:
name: workshop-sensor
esp32:
board: esp32dev
framework:
type: arduino
wifi:
ssid: "<your-wifi-ssid>"
password: "<your-wifi-password>"
api:
encryption:
key: "<generated-automatically-by-esphome>"
ota:
- platform: esphome
password: "<generated-automatically-by-esphome>"
sensor:
- platform: dht
pin: GPIO4
model: DHT22
temperature:
name: "Workshop Temperature"
humidity:
name: "Workshop Humidity"
update_interval: 60s

The api and ota sections' keys/passwords are generated automatically by the ESPHome dashboard when you create the device -- don't hand-type placeholder values here.

Step 4: Flash the firmware

For the first flash, connect the ESP32 via USB to the machine running the ESPHome dashboard and choose the USB flashing option in the dashboard. Expected output: ESPHome compiles the firmware and flashes it over the USB connection, then the device reboots and connects to your Wi-Fi.

Subsequent updates can flash over-the-air (OTA) using the ota config above -- no USB cable needed after this first flash.

Step 5: Confirm Home Assistant auto-discovers it

In Home Assistant: Settings → Devices & Services should show a discovered ESPHome device notification shortly after the ESP32 comes online. Accept it, and both Workshop Temperature and Workshop Humidity should appear as new entities.

Verify it works

  • The ESPHome dashboard shows the device online, with live sensor readings visible in its logs
  • Home Assistant shows the device under Settings → Devices & Services → ESPHome, with both sensor entities populated
  • The readings update roughly every 60 seconds (per the configured update_interval) and reflect real changes (breathe near the sensor, or hold it briefly -- humidity/temperature should visibly shift)
  • Failure test: disconnect the ESP32 from power briefly, then reconnect. Confirm it reconnects to Wi-Fi and Home Assistant automatically with no manual re-pairing step -- this is what makes it a reliable long-term sensor rather than one that needs babysitting after every power blip

Secure it

  • What's exposed: ESPHome's native API uses encryption (the api.encryption.key generated in Step 3) -- don't skip this or leave it unconfigured, since it's what keeps the device's local API from being open to anything on your network.
  • OTA update password: similarly generated automatically -- protects against unauthorized firmware pushes to the device over the network.
  • Wi-Fi credentials in the config file: the YAML config contains your Wi-Fi password in plaintext -- keep the ESPHome config directory out of any public repository, or use ESPHome's secrets file feature (secrets.yaml, gitignored) to keep credentials out of the main config.

Back it up and maintain it

What matters: the device's YAML config file -- small, worth version-controlling (with secrets factored out per above). The compiled firmware itself is reproducible from the config at any time, nothing unique to back up there.

Update cadence: ESPHome and Home Assistant both update regularly; OTA makes re-flashing trivial once the initial USB flash is done, so there's little reason to let a device's firmware go stale.

What to monitor: the device's online/offline status in Home Assistant -- a sensor that's gone silent (Wi-Fi issue, power loss, crashed firmware) is easy to miss if you're not watching for it, especially if it feeds an automation you rely on.

Troubleshooting

Logs: ESPHome dashboard's live log view for the device; Home Assistant's own logs (Settings → System → Logs) for integration-side issues.

Symptom Likely cause Diagnostic Fix
Sensor readings show NAN or never populate Wiring issue (wrong pin, no pull-up resistor where needed), or a faulty sensor unit Check the ESPHome device's live logs for sensor read errors Verify wiring against the DHT22's actual pinout; try a different GPIO pin in config if the physical wiring is confirmed correct
Device won't connect to Wi-Fi Wrong SSID/password, or the ESP32's radio doesn't support your Wi-Fi band/security type Check the ESPHome logs during boot for the specific Wi-Fi connection error Fix credentials; confirm your network isn't using a mode (e.g. WPA3-only) the specific ESP32 board doesn't support
OTA update fails Device unreachable on the network, or ota password mismatch between the config and what's already flashed Try re-flashing over USB instead to isolate whether it's OTA-specific Reconnect via USB if OTA is failing and the device is otherwise unreachable
Home Assistant doesn't auto-discover the device mDNS/discovery traffic blocked between the ESP32's network segment and Home Assistant's (common if they're on different VLANs) Confirm both are on the same network segment, or manually add the ESPHome integration with the device's IP Add the integration manually with the IP if cross-VLAN discovery isn't working, or adjust firewall/VLAN rules to allow mDNS
Readings update but seem inaccurate DHT22 units have real accuracy limits (roughly ±0.5°C, ±2-5% RH depending on the specific unit) Compare against a known-accurate reference if precision matters for your use case This may be within the sensor's normal spec -- check the DHT22 datasheet's stated accuracy before assuming a fault

Undo

Power off and disconnect the device -- no persistent state elsewhere is affected. Remove the integration from Home Assistant (Settings → Devices & Services) to stop it from appearing there.

Go further

  • Add more sensor types ESPHome supports (motion, light, air quality, and many others) to the same or additional ESP32 devices
  • Build a Home Assistant automation using the new sensor data (e.g. a notification if workshop humidity crosses a threshold)
  • Explore ESPHome's support for actuators too (relays, displays), not just sensors -- the same YAML-based approach extends to controlling things, not just reading them

Resources

Official documentation:

Source and releases:

Community:

Related DaemonPress projects:


Last verified: 2026-09-21, checked against official ESPHome and Home Assistant documentation.