A battery-powered SHT30 Sensor for Home Assistant

A battery-powered SHT30 Sensor for Home Assistant

This write-up will cover making a complete sensor device for ESPHome and Home Assistant use.

BOM

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).

1.

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.

2.

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.

3.

Solder the terminal block on one side.

We'll be using GND, 3V3, 10, and 7. The other side is unused.

4.

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.

5.

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.

5.1

Here's the mqtt section:

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

The birth_message and 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.

The 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.

5.2

The 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

5.3

The 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.

5.4

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

5.5

The 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.

6.

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.

6.1

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.

6.2

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.

Everything connected

7.

Some improvements might include the following:

  • timing the MQTT on_connect more 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 serverthis saved roughly a second of on-time
  • add some extra diagnostic measurements like WiFi strength
  • figure out the logger issue

8.

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?