- C++ 84.5%
- Just 8.9%
- C 6.6%
| .gitignore | ||
| config.h | ||
| humiditemp.ino | ||
| justfile | ||
| README.md | ||
| sht40.h | ||
humiditemp
ESP32 + SHT40 temperature/humidity sensor that reports to Home Assistant over MQTT. Entities show up automatically through MQTT discovery.
Wiring
| SHT40 breakout | ESP32 |
|---|---|
| VIN / VCC | 3V3 |
| GND | GND |
| SDA | GPIO21 |
| SCL | GPIO22 |
Keep the sensor a few cm away from the ESP32 (short cable), as the ESP32 warms up when WiFi is on.
Setup
-
Home Assistant needs an MQTT broker (the Mosquitto add-on) and the MQTT integration. Create an HA user for the sensors to log in with.
-
Non-secret settings (SSID, broker IP, MQTT user, pins, intervals) are in
config.h. Passwords come from 1Password: thewifi_item/mqtt_itemIDs in thejustfilepoint at items whosepasswordfield is used.justwrites them tosecrets.h(gitignored) using theopCLI. -
Build and flash (just +
arduino-cli+op):just build # fetch secrets and compile just flash # compile, upload and open the serial monitor PORT=/dev/ttyUSB1 just flash # other serial port just clean # remove build/ and secrets.hbuild/contains the compiled firmware with the passwords embedded; it is gitignored.
The device appears in HA as "Humiditemp XXXXXX" (last six digits of the MAC address), with Temperature, Humidity and WiFi signal entities. Rename it in HA as you like. Every board gets a unique ID, so the same firmware can be flashed onto all of them.
Deep sleep (battery or mains)
Set DEEP_SLEEP 1 in config.h. This works the same on a power supply, where it simply
saves energy and keeps the sensor cooler; leave BATTERY_ADC_PIN at -1 there. Each wake reads the sensor (before WiFi warms the
board), connects, publishes one reading and sleeps for the rest of SLEEP_INTERVAL_S.
A wake typically takes 0.5–1.5 s. The WiFi channel and access point are kept in RTC
memory between wakes to skip scanning.
- HA marks the sensors unavailable if three wakes in a row are missed (
expire_after). - Discovery is re-sent after a cold boot and then once a day, so the sensors come back on their own even if the broker loses its retained messages.
- Battery voltage: wire the battery through a divider (e.g. 2× 100 kΩ) to an
ADC1 pin (GPIO32–39) and set
BATTERY_ADC_PIN. ADC2 pins don't work with WiFi on.
Hardware matters more than firmware for battery life:
- Typical dev boards (DevKitC etc.) draw 5–15 mA while "asleep" because of the USB-serial chip, the power LED and the regulator. Use a low-power board (e.g. FireBeetle ESP32, LOLIN D32, TinyPICO) or a bare module with a low-quiescent LDO (e.g. MCP1700, HT7333).
- Cut the power-LED jumper on the SHT40 breakout (Adafruit: jumper on the back).
- For debugging, flash with
DEEP_SLEEP 0. In sleep mode, serial output only appears during the short wakes.
MQTT topics
humiditemp/<id>/state:{"temperature":21.53,"humidity":45.20,"rssi":-61,"battery":3.98}(batteryonly when enabled)humiditemp/<id>/status:online/offline(last will, always-on mode only)homeassistant/sensor/<id>/<key>/config: discovery messages, retained