Configuring Grove Analog interface pin to output Voltage/Current

Hi there,

I was wondering if I can use ESPHome with Seeed’s mmwave Human Detection Kit to output 3.3V on the A0 pin of the Grove Analog Interface when Existence Energy exceeds 10. I also want to be able to set a “calm down” time of 30 secs - so when existence energy exceeds 10, A0 will output 3.3V and won’t output any voltage for the next 30 secs, even if Existence Energy exceeds 10 again within the 30 sec period.

Here’s the esphome yaml config for the human detection kit:

substitutions:
  name: "seeedstudio-mmwave-kit"
  friendly_name: "SeeedStudio mmWave Kit"

esphome:
  name: "${name}"
  friendly_name: "${friendly_name}"
  name_add_mac_suffix: true
  project:
    name: "seeedstudio.mmwave_kit"
    version: "3.0"
  platformio_options:
    board_build.flash_mode: dio
    board_build.mcu: esp32c3

# external_components:
#   - source: github://limengdu/mmwave-kit-external-components@main
#     refresh: 0s

esp32:
  board: esp32-c3-devkitm-1
  variant: esp32c3
  framework:
    type: esp-idf

# Enable logging
logger:
  hardware_uart: USB_SERIAL_JTAG
  level: DEBUG

# Enable Home Assistant API
api:

ota:
  - platform: esphome

wifi:
  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "seeedstudio-mr24hpc1"

captive_portal:

# Sets up Bluetooth LE (Only on ESP32) to allow the user
# to provision wifi credentials to the device.
esp32_improv:
  authorizer: none

# Sets up the improv via serial client for Wi-Fi provisioning.
# Handy if your device has a usb port for the user to add credentials when they first get it.
# improv_serial: # Commented until improv works with usb-jtag on idf

uart:
  id: uart_bus
  baud_rate: 115200
  rx_pin: 4
  tx_pin: 5
  parity: NONE
  stop_bits: 1

seeed_mr24hpc1:
  id: my_seeed_mr24hpc1

text_sensor:
  - platform: seeed_mr24hpc1
    heart_beat:
      name: "Heartbeat"
    product_model:
      name: "Product Model"
    product_id:
      name: "Product ID"
    hardware_model:
      name: "Hardware Model"
    hardware_version:
      name: "Hardware Version"
    keep_away:
      name: "Active Reporting Of Proximity"
    motion_status:
      name: "Motion Information"
    custom_mode_end:
      name: "Custom Mode Status"

binary_sensor:
  - platform: seeed_mr24hpc1
    has_target:
      name: "Presence Information"

sensor:
  - platform: seeed_mr24hpc1
    custom_presence_of_detection:
      name: "Static Distance"
    movement_signs:
      name: "Body Movement Parameter"
    custom_motion_distance:
      name: "Motion Distance"
    custom_spatial_static_value:
      name: "Existence Energy"
    custom_spatial_motion_value:
      name: "Motion Energy"
    custom_motion_speed:
      name: "Motion Speed"
    custom_mode_num:
      name: "Current Custom Mode"

switch:
  - platform: seeed_mr24hpc1
    underlying_open_function:
      name: Underlying Open Function Info Output Switch

button:
  - platform: seeed_mr24hpc1
    restart:
      name: "Module Restart"
    custom_set_end:
      name: "End Of Custom Mode Settings"

select:
  - platform: seeed_mr24hpc1
    scene_mode:
      name: "Scene"
    unman_time:
      name: "Time For Entering No Person State (Standard Function)"
    existence_boundary:
      name: "Existence Boundary"
    motion_boundary:
      name: "Motion Boundary"

number:
  - platform: seeed_mr24hpc1
    sensitivity:
      name: "Sensitivity"
    custom_mode:
      name: "Custom Mode"
    existence_threshold:
      name: "Existence Energy Threshold"
    motion_threshold:
      name: "Motion Energy Threshold"
    motion_trigger:
      name: "Motion Trigger Time"
    motion_to_rest:
      name: "Motion To Rest Time"
    custom_unman_time:
      name: "Time For Entering No Person State (Underlying Open Function)"

How would I need to modify this to achieve the desired result?

Thanks a lot for your help.

You will need to define an output - probably a GPIO switch. No idea what GPIO the grove connect connects to, replace GPIOXX with the correct value - but it would look something like:

switch:
  - platform: gpio
    pin: GPIOXX
    name: "Grove A0 Out"
    id: grove_a0

Define a script that runs mode: single, this means it will not run again if triggered while still running. The 30s timer will be in that script.

script:
  - id: toggle_a0_with_cooldown
    mode: single
    then:
      - switch.turn_on: grove_a0
      - delay: 1s
      - switch.turn_off: grove_a0
      - delay: 30s

Then add a trigger and action on your sensor:

    custom_spatial_static_value:
      name: "Existence Energy"
      on_value_range:
        - above: 10.0
          then:
            - script.execute: toggle_a0_with_cooldown

https://esphome.io/components/script#

2 Likes

Nice choice. You replied while I was writing this: :rofl:

switch:
  - platform: gpio
    pin: GPIO2
    id: my_switch
    name: "Analog pin output"
    

on_value_range:
      - above: 10
        then:
          - script.execute: my_script

script:
  - id: my_script
    mode: single
    then:
      - switch.turn_on: my_switch
      - delay: 100ms
      - switch.turn_off: my_switch
      - delay: 30s

Pin to be verified, gpio2 is A0 pin of Xiao though.

2 Likes

Lol! Looks familiar… :smiley:

Thank you very much @zoogara @Karosm .

I shall try the above and fingers crossed, it does the job.

With the “- above: 10.0” command, it appears as though A0 turns on only when existence energy crosses 10, ie. moves from a value below 10 to a value above 10 (after the 30 sec delay ends). A0 doesn’t turn on when existence energy remains above 10 once the 30 sec delay period ends.

I’m connecting A0 to an analog input on a lorawan sensor, which in turn will uplink once it receives an output signal from A0 - this way I’ll know if someone’s in the room or no. When existence energy stays above 10, it means someone’s definitely around. I can’t capture that at the moment because I receive an uplink only when the value jumps from below 10 to above 10. What I’m looking for is this : if value is 10 or greater than 10 after 30 secs, turn on A0 for 1 sec. Hope this makes sense. Thanks.

Replace on_value_range: with on_value: then add a sensor.in_range: condition.

The on_value_range: trigger only triggers when the value crosses the value. on_value: triggers every time the sensor updates. Make sure the update interval of your sensor is less than the cool-down period.

I’m not in a position to write any code for you but here is the link to the relevant documentation:

You are still going to have issues with timing for this solution. You could fiddle with the script mode, or change it so that you use a timer with an interval of 30s and check the value then, running the script as required.

You could also play with update intervals and delay values…

1 Like

I used on_value: with the sensor.in_range condition and it works brilliantly now! Thanks! Just what I was looking for.

Fortunately the senor value updates every 1 second or something (well below the cool down period) so I didn’t have to change any sensor update interval.