Skip to content
MCU Atlas
ESP32ESP32-C3

XKC-Y25 water-tank monitor: three non-contact level sensors on an ESPHome XIAO ESP32C3

Three XKC-Y25-V sensors stuck to the outside of a plastic tank tell Home Assistant whether the water is above each one. Nothing touches the water. Our version runs from a USB charger.

Difficulty:IntermediateSource available

What it is

Three sensors on the outside of a plastic water tank that tell Home Assistant how full it is, without touching the water.

How hard

Intermediate: three sensors and a level shifter to wire up, then ESPHome from the repo's YAML with three pin numbers changed.

Key Facts

  • Three XKC-Y25-V non-contact capacitive sensors on GPIO3 (D1), GPIO4 (D2) and GPIO5 (D3)
  • Sensors read through a non-metallic tank wall up to 20 mm thick (sensor manual)
  • ESPHome on a Seeed XIAO ESP32C3 (esp-idf); Home Assistant discovers it
  • 4-channel level shifter between the 5 V sensors and the 3.3 V ESP32
  • Power: USB 5V from a wall charger (our adaptation; no mains wiring)
  • MIT licence, by Sergey Varibrus (g1ibby)

About This Project

This build by Sergey Varibrus (g1ibby) watches the level in a stored-water tank without putting anything inside it. Three XKC-Y25-V capacitive sensors attach to the outside of a non-metallic tank wall at the levels you care about, for example low, middle and high. Each one sees whether there is liquid behind the wall at its height. A Seeed Studio XIAO ESP32C3 running ESPHome reads them and reports three binary sensors to Home Assistant, which discovers the device by itself, so you can chart the level and set up automations such as a low-water notification or switching off a pump when the tank is full. The firmware also reports the ESP32's internal temperature. The sensors run on 5 V and send a 5 V signal, so a small 4-channel logic level shifter brings each signal down to the XIAO's 3.3 V. In the creator's build everything sits in an IP67 box with IP68 SP13 plugs for the sensor cables and a breathable vent plug against condensation. Power: the creator's build runs from mains through an AC-DC module wired inside the box. This page shows a USB 5V version instead, and there is no mains wiring in it. The XIAO is powered over USB-C from an ordinary USB wall charger, and its 5V pin, which Seeed's wiki describes as "5v out from the USB port", feeds the sensors and the level shifter's high-voltage side. The three sensors draw 5 mA or less each, according to the sensor manual. This is our adaptation, not the creator's wiring.

Source & Attribution

Source: GitHub
License: MIT
Last verified: 11/1/2026
XKC-Y25 water-tank monitor: three non-contact level sensors on an ESPHome XIAO ESP32C3

Illustration

How to Build It
Wire three XKC-Y25-V sensors through a level shifter to a XIAO ESP32C3, power it from a USB charger, flash the ESPHome YAML and stick the sensors on the outside of the tank.

Steps

  1. 1

    Power (our USB 5V version)

    Power the XIAO over USB-C from an ordinary USB wall charger. Take 5 V from the XIAO's 5V pin, which Seeed's wiki describes as "5v out from the USB port", to the level shifter's HV pin and to each sensor's brown wire. Take 3.3 V from the XIAO's 3V3 pin to the shifter's LV pin, and join all the grounds, including each sensor's blue wire. Don't wire anything to mains. Plug the charger into an indoor socket, or an outdoor socket with a weatherproof cover and GFCI (RCD) protection. The creator's build uses a mains module, and we've left it out.

  2. 2

    Wire the signals

    Sensor 1 yellow to HV1, and LV1 to GPIO3 (D1). Sensor 2 yellow to HV2, and LV2 to GPIO4 (D2). Sensor 3 yellow to HV3, and LV3 to GPIO5 (D3). Leave each sensor's black wire unconnected: in the manual, a floating black wire means the output goes high when the sensor detects liquid. The creator's original build used GPIO9, GPIO10 and GPIO8. We moved the sensors because GPIO8 and GPIO9 are strapping pins that set the boot mode at power-up (Espressif datasheet), and a dry sensor holds its line low, which can stop the XIAO booting after a power cut. If you buy the sensors on AliExpress, select the XKC-Y25-V option (high/low level output), not the NPN, PNP or RS485 versions.

  3. 3

    Box it up

    Mount the XIAO and the shifter in the IP67 box. Fit the three SP13 connectors for the sensor cables and the M12 vent plug in the box wall. Bring the USB cable in through a sealed entry.

  4. 4

    Flash ESPHome

    Create a new ESPHome device from the repo's esphome.yaml (board seeed_xiao_esp32c3, esp-idf framework). In its binary_sensor section, change the three pin numbers to match our wiring: GPIO9 to GPIO3 for Tank Level Sensor 1, GPIO10 to GPIO4 for Sensor 2 and GPIO8 to GPIO5 for Sensor 3. Put wifi_ssid and wifi_password in your secrets.yaml. Our note: the repo's YAML has no API encryption key and no OTA protection. Add an encryption key under api: as a !secret entry in secrets.yaml, and an empty encryption: block under ota:, which reuses that key (ESPHome recommends this over an OTA password). Flash it over USB the first time; after that you can update over Wi-Fi.

  5. 5

    Add it to Home Assistant

    Home Assistant discovers the device through the ESPHome integration. Click Configure, and Tank Level Sensor 1, 2 and 3 appear as binary sensors, along with the ESP32's internal temperature. Use them on a dashboard or in automations, such as a low-water notification.

  6. 6

    Fit the sensors

    Clean the tank wall and attach each sensor to the outside of the non-metallic wall at the level you want to watch, with good contact. The manual allows walls up to 20 mm thick. If a sensor is always on or always off, adjust the sensitivity knob under its back cover (counter-clockwise is more sensitive) and check the wiring.

Not included: Jumper wires or a custom PCB, Home Assistant with the ESPHome integration, Glue to hold the sensors on the tank (the manual suggests AB glue)

Download CSV

Related Projects

whisli sense: ESP32 mmWave presence sensor with climate and light
Illustration
ESP32ESP32-C3
A local presence sensor on a Waveshare ESP32-C3-Zero: an HMMD mmWave radar sees even a person sitting still, plus temperature, humidity and light, a browser panel and optional Home Assistant over MQTT. No licence in the repo.
Intermediate
6 parts listed
ESP32 freezer alarm: a DS18B20 probe that emails you when the freezer warms up
Illustration
ESP32
A build pattern for a temperature alarm: an ESP32, a waterproof DS18B20 probe and a web setup page that emails you when the reading crosses your setpoint.
Intermediate
5 parts listed
SparkFun OpenLog: Arduino-compatible data logger
Illustration
ARDUINOATMEGA328P
A tiny ATmega328-based logger that writes serial data to a microSD card with almost no host code.
Beginner·Code
2 parts listed