This write-up will cover making a complete sensor device for ESPHome and Home Assistant use.
You'll also need a 3D printer, a working Home Assistant installation, ESPHome (either as a HA addon or as the CLI), and an MQTT broker (also can be an HA addon).
Make sure your MQTT broker is set up for Home Assistant. The instructions can be found in the addon inside Home Assistant. You'll probably want to follow the instructions by making a new MQTT user and configuring it as an integration. Or you can use your own and just add it as an integration. When you are done, you'll have an MQTT box in Settings > Devices & Services.
Now you need to solder some tiny wires to the back of the Xiao.
Grab a JST female wire, solder the black wire to the - pad and red to the + terminal. The easiest way for me is to apply a blob of solder to each pad, then trim and tin the wire leads. Melt the blobs and push the leads in.
There's one extra step you can take that I didn't. You can solder some resistors to the pads as well to be able to read the battery voltage. Read more about it here.
Solder the terminal block on one side.
We'll be using GND, 3V3, 10, and 7. The other side is unused.
Now attach the SHT30 to the terminal you just soldered. My SHT30 wiring is:
- red 3V3
- black GND
- yellow D7
- green D10
Your wire colors may differ slightly, but for this YAML, D10 is SDA and D7 is SCL.
Let's start working on the ESPHome YAML.
Here's the YAML. In the next steps, I'll go over a few of the items.
esphome: name: sht-xiao esp32: board: seeed_xiao_esp32c3 variant: esp32c3 framework: type: arduino logger: mqtt: broker: homeassistant.local username: mqtt password: !secret mqtt_password birth_message: will_message: on_connect: then: - delay: 1s - deep_sleep.enter: id: _sleep sleep_duration: 5min wifi: ssid: !secret wifi_ssid password: !secret wifi_password power_save_mode: LIGHT fast_connect: true i2c: sda: 10 scl: 20 sensor: - platform: sht3xd id: sht temperature: id: sht_air_temp name: "Temperature" humidity: id: sht_air_rh name: "Humidity" address: 0x44 deep_sleep: id: _sleep run_duration: 10s
Be sure to replace all the
!secret lines with your own information.
And for some reason, this example will only work when the serial terminal is connected. We'll go through a few sections below where this will get fixed.
mqtt: broker: homeassistant.local username: mqtt password: !secret mqtt_password birth_message: will_message: on_connect: then: - delay: 1s - deep_sleep.enter: id: _sleep sleep_duration: 5min
will_message are there to prevent the measurement from showing unavailable. Even though it will be unavailable when the device goes to sleep, I still want to see the last measurement.
on_connect section is where the battery saving comes in. By the time the device has connected to WiFi and the MQTT broker, it has already taken a sensor reading. The
delay: 1s is there to give the device time to send the measurement back to Home Assistant. Then the device goes to sleep for 5 minutes.
sensor section looks like this:
sensor: - platform: sht3xd id: sht temperature: id: sht_air_temp name: "Temperature" humidity: id: sht_air_rh name: "Humidity" address: 0x44
wifi section looks like this:
wifi: ssid: !secret wifi_ssid password: !secret wifi_password power_save_mode: HIGH fast_connect: true
power_save_mode: HIGH is there to save a bit of battery. This might not work in your location since it reduces WiFi signal strength. You can try LIGHT, or if that doesn't work, just delete the line.
fast_connect skips scanning for networks and make connecting faster.
One thing to note here is that
scl is 20. When you use the pins on the Xiao ESP32C3, you need to use the GPIO## to refer to the pins, not the D# or A#.
i2c: sda: 10 scl: 20
logger: section is some bug with the -C3 version or something unique to the Xiao board. When you leave the
logger section, the device will only work with a serial connection. If you disconnect, the device stops working. The fix for this is to just remove the
logger section. This isn't so bad to deal with. You can develop the device on your desk with a serial connection, and when it works, flash it once more with
logger commented out.
Connect the battery, and at this point, we should have a fully functional device. But to really finish it, and to keep it from being pulled apart by gremlins, it needs to be enclosed. For this particular use, it will be an indoor temperature and humidity sensor; in other words, not waterproof.
Since I'm not an expert at 3d CAD, I searched the internet and stumbled on this project, the Ultimate Box Maker. This is a revised project of another version, but this revision makes a box that snaps closed and that's why I choose it.
You may or may not be familiar with OpenSCAD, but you'll need to get a little familiar with it to make the box. Basically, it is a sort of programming language that builds a 3d object.
Download the Ultimate_Box.scad file and open it in OpenSCAD. This is the scad file used in this writeup. With it, you can export STL files for the top, bottom, and both panel inserts. I edited the top shell STL in Fusion360 to add internal rails to the top shell. You can download that file here.
Print the 4 STL files and piece them together. Finish the device by reconnecting the SHT30 through the hole of one of the panels. Seat the battery in the slot, put the Xiao in its slot, and snap it together. Don't forget about the antenna, it fits nicely on the side.
Some improvements might include the following:
- timing the MQTT
on_connectmore precisely, maybe 500ms is enough rather than 1s — 100ms was about as low as it would go and still send data
- the SHT30 can operate in various power-saving modes, confirm which, if any, the ESPHome component uses and use them if available — it already does
- use a larger battery, 260 mAh is small. It will probably be enough to last over a month at least
- use static IP addresses for both the device and the MQTT server — this saved roughly a second of on-time
- add some extra diagnostic measurements like WiFi strength
- figure out the
The device measures about 0.037 mA in deep-sleep. That isn't bad. The tiny 260 mAh battery would last for nearly a year, but the killer is the time awake. It takes several seconds to make a WiFi connection and send the data. Aside from using static IP addresses for everything, I don't see any more ways to save time or power. An equivalent device using LoRa would be awake for significantly shorter amounts of time. Maybe ESPNow?