ESP32 (Seeed Xiao-C3) moisture sensor - questions

Hello Everyone,

Let me prephase my post with that I am very new to ESPHome and microelectronics in general

I managed to put together a soil moisture sensor using the following components:

This is the code in ESPHome:
esphome:
  name: wifi-moisture-sensor
  friendly_name: Lawn Moisture Sensor
  on_boot:
    then:
      - switch.turn_on: sensor_power
  on_shutdown:
      then:
      - switch.turn_off: sensor_power

esp32:
  board: esp32-c3-devkitm-1
  framework:
    type: arduino

# Enable logging
logger:

# Enable Home Assistant API
api:
  encryption:
    key: "..."

ota:
  password: "..."

wifi:
  ssid: "..."
  password: "..."
  fast_connect: on
  power_save_mode: LIGHT
  manual_ip:
   static_ip: x.x.x.x
   gateway: x.x.x.x
   subnet: x.x.x.x
   dns1: x.x.x.x

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Lawn Moisture Sensor"
    password: "..."

captive_portal:

sensor:
  - platform: adc
    pin: 
      number: 3
      allow_other_uses: True
    name: "Soil Surface Moisture Voltage"
    id: soil_surface_moisture_voltage
    update_interval: 2s
    attenuation: 11db
  - platform: adc
    pin: 
      number: 3
      allow_other_uses: True
    name: "Soil Moisture"
    unit_of_measurement: "%"
    device_class: MOISTURE
    update_interval: 2s
    attenuation: 11db
    filters:
    - calibrate_linear: 
        - 1.75 ->  100.00 
        - 2.61 ->  0.00
    - lambda: |
       if (x < 0) return 0;
       else if (x > 100) return 100;
       else return (x);
    accuracy_decimals: 0

switch:
  - platform: gpio
    pin: GPIO10
    id: sensor_power
    internal: true

I did my sensor calibration and got ca. 1.75V submerged in a glass of water, ca. 2.61V out in dry air on room temperature. For now I am powering the Xiao via USB-C and using the 3v3 pin to connect the sensor’s VCC pin. This way the sensor works fine.

I am wondering about 2 things:

  • As you can see in the config there is a GPIO pin configured to use as VCC input for the sensor to avoid the sensor draining on the battery whilst the Xiao is in deep sleep (that is to be configured later, I have the code for it). However, when I try to connect the VCC pin to the configured GPIO the sensor readings are no longer consistent. Going back to the 3v3 output pin, the sensor is once again working as it should. What am I doing wrong? Do I need to wire anything else?
  • I would like to add some kind of a battery sensor calculation, as these sensors will be placed outdoors. II am planning to follow this wiring schematic for adding some resistors? What kind of resistors would you recommend to maximize energy efficiency?
Would this code work for me?
  - platform: adc
    pin: 
      number: 4
      allow_other_uses: True
    name: "Battery Life"
    unit_of_measurement: "%"
    device_class: BATTERY
    update_interval: 2s
    attenuation: 11db
    filters:
     - multiply: 2.0
     - calibrate_polynomial: 
        degree: 4
        datapoints:
        - 3.4 ->  0.0
        - 3.6 ->  8.43
        - 3.81 ->  50.06
        - 3.86 ->  57.63
        - 3.92 ->  72.56
        - 3.96 ->  90.96
        - 4.05 ->  100
     - lambda: |
        if (x < 0) return 0; 
        else if (x > 100) return 100;
        else return (x);
        
  - platform: adc
    pin: 
      number: 4
      allow_other_uses: True
    name: "Battery Voltage"
    update_interval: 2s
    attenuation: 11db
    filters:
     - multiply: 2.0

You can’t power almost anything from esp32 gpio. I say almost, because if your load is below 20mA, maybe you can. Gpios are for signals, not for powering.
You are lucky if you didn’t fry your gpio yet.

I recommend you to study little bit electronics and microcontrollers in general. Some arduino book/tutorial for example.

Did you try to switch GND of the sensor instead with the help of a GPIO of your esp32?

Why only maybe? What makes you think the current draw of this sensor is higher than 20mA and why shouldn’t it work even the current draw is less than 20mA? Is that written in an arduino tutorial?

Maybe, because in older datasheets of Esp32 from Espressif max was defined 12mA.
Datasheet for this sensor I have not seen, could be less or more. If sensor powered from 3v3 pin works, but from gpio not, that’s my first subject of problem.
I generally wouldn’t power anything like this from gpio, simply because cinese datasheets and clone-of-the-clone-modules can’t convince me to do it.

Xiao-C3 has a 700mA 3.3V regulator so the sensor connected to the 3.3V pin should be fine.

3V3 - This is the regulated output from the onboard regulator. You can draw 700mA

Trying to power something from a GPIO would be different.

I think these are fair points, especially the last one with datasheets of Chinese clone products. I did try to read up on this, my understanding is that the Xiao can output max 40 mA whilst the sensor would only need 10-15mA at max.

The question becomes then how do you avoid the sensor constantly draining the battery even if the ESP32 controller is in deep sleep?

I though based on what I read and saw online that the GPIO is the more elegant and space-conserving solution, but there could be other ways out there I am not familiar with.

For sure, we are all dealing with these issues with sensors, buck/boost converters, motor drivers and so on.
In your case, just power it with a transistor.

And I’m not saying that it’s not possible to power something from gpio. You can, but it’s not a good practice. If you have a genuine arduino board and you measure your sensors max current draw and it’s below specs then ok.
But if you have clone board and some $0.5 aliexpress sensor (like we often do), it’s a guess work.

3 Likes