Does anyone know how to get this sensor to work with Esphome?

I have been using a sonic sensor (HC-SR04) to measure/alert how full a water softener salt tank is but being inside the salt tank they were corroding and stopped working every few months and needed to be replaced. I naively bought this sensor (the PWM version) thinking is would be a drop in replacement for the HC-SR04, alas it is not.

This is the spec sheet that came with it:

Anyone have any thoughts on how to use it with esphome to get it to do more or less what the HC-SR04 does?

Please post the doc as a pdf, or at least readable!

Could it be as simple as an ā€˜intervalā€™ sensor and a binary_sensor?
The interval would toggle RX every couple seconds, and also store millis() in a global as it does so.
The binary sensor would be wired to TX and has an on_release automation that subtracts the stored millis in the global from millis(), thus telling you the echo-time, from which you can compute the distance.

it have arduino module, so I believe this is something doable

Agree. I looked over the code in Arduinoā€™s ā€˜NewPingā€™ library which seems to work with this device.
Could be implemented in ESPhome using a couple lambdaā€™s, Iā€™ll wager.

Also this

seems like it could work, but the trigger pin would need to be inverted.

Seem like something like this could work. How would you implement an interval sensor in esphome?

Are you using the Arduino ā€œpingā€ sketch with that device? Any thoughts on if esphome has a similar feature? I was not able to find anything to accomplish the same thing. Sorry, long time Home Assistant user but pretty much a beginner at esphome.

Itā€™s just like other top-level components, but a little hard to find in the docs. And I mistakenly called it a sensor.
Take a look:

That is very helpful. I will give it a try next chance I get. Thank you for the pointer.

Let us know for sure either way (working or not).

I thought about using something for my water softener salt level as well but knew the US sensor wouldnā€™t last long.

I think this would be great for that if you can get it to work.

Iā€™m OK using ArduinoIDE or ESPHome too.

Iā€™m sure I am not close yet but here is what I have been able to come up with so far. Largest problem I have found so far is I cannot find a way to get the time with millisecond resolution. Any one have any ideas on how to get that?

Code so far (wont work as is but posing anyways to see if anyone thinks I am already heading down the wrong path):


globals:
  - id: send_millisecond
    type: int
    restore_value: yes
    initial_value: '0'
  - id: receive_millisecond
    type: int
    restore_value: yes
    initial_value: '0'
  - id: diff_millisecond
    type: int
    restore_value: yes
    initial_value: '0'


output:
  - platform: esp8266_pwm
    id: pwm_output
    pin: D3

interval:
  - interval: 1min
    then:
      - globals.set:
          id: send_millisecond
          value: !lambda 'return int(time({get millisecond}))'
      - output.turn_on: pwm_output
      - logger.log: pwm output is running
      - delay: 100ms
      - output.turn_off: pwm_output
      - logger.log: pwm output is stopped


binary_sensor:
  - platform: gpio
    pin: D2
    id: echo_receive_pin
    on_state:  
      then:
        - globals.set:
            id: receive_millisecond
            value: !lambda 'return int(time({get millisecond}))'
        - globals.set:
          id: diff_millisecond
          value: !lambda 'return int(receive_millisecond) - int(send_millisecond);' 


sensor:
  - name: "Last Echo Diff Time"
    id: last_echo_diff_time 
    filters:
      - lambda: return {diff_millisecond};

If I can just get those millisecond values and get the code valid I should be able to do the proper math and figure out the distance.

Any help is greatly appreciated.

Slight update. I was able to get the following code compiled, had to comment out the important parts until I can figure how to get milliseconds.

I do get ā€œpwm output is runningā€ and ā€œpwm output is stoppedā€ in the logs but I never get ā€œD2 Received State Changeā€ so Im not sure the D3 pin ever actually sends a signal through the sensor device.


globals:
  - id: send_millisecond
    type: int
    restore_value: yes
    initial_value: '0'
  - id: receive_millisecond
    type: int
    restore_value: yes
    initial_value: '0'
  - id: diff_millisecond
    type: int
    restore_value: yes
    initial_value: '0'


output:
  - platform: esp8266_pwm
    id: pwm_output
    pin: D3

interval:
  - interval: 1min
    then:
      # - globals.set:
      #     id: send_millisecond
      #     value: !lambda 'return int(time({get millisecond}))'
      - output.turn_on: pwm_output
      - logger.log: pwm output is running
      - delay: 100ms
      - output.turn_off: pwm_output
      - logger.log: pwm output is stopped


binary_sensor:
  - platform: gpio
    pin: D2
    id: echo_receive_pin
    on_state:  
      then:
        - logger.log: D2 Received State Change
    #     - globals.set:
    #         id: receive_millisecond
    #         value: !lambda 'return int(time({get millisecond}))'
    #     - globals.set:
    #       id: diff_millisecond
    #       value: !lambda 'return int(receive_millisecond) - int(send_millisecond);' 


sensor:
  - platform: template
    name: "Last Echo Diff Time"
    id: last_echo_diff_time 
    # filters:
    #   - lambda: return {diff_millisecond};

Thanks for reading.

I am curious why you commented-out the part where it sets send_millisecond, since it needs that value in order to do the math when it receives an echo.
Also, you might want to store that send_millisecond value after you toggle the TX line and its included delay, since the signal may not actually get sent until the end of that cycle, and you donā€™t want to include your own delay in the turnaround time. (if the signal is sent at the beginning of the toggle, then itā€™s correct as you first had it, storing at the beginning).
Shortcut: instead of int(time({get millisecond})) you can just say ā€˜millis()ā€™ which is ā€˜nowā€™ in system-clock millisecond-time.

Ok, this is some great advice! Getting closer with the following code however I never get ā€œD2 Received State Changeā€ in the log so echo_receive_pin is never receiving a state change. Does it need to turn on a listening mode or something like that? Also likely I will need to change echo_receive_pin from on_state trigger to something that only triggers on one state otherwise it likely will reset diff_millisecond again after the cycle.

Current code:

globals:
  - id: send_millisecond
    type: int
    restore_value: yes
    initial_value: '0'
  - id: diff_millisecond
    type: int
    restore_value: yes
    initial_value: '0'


output:
  - platform: esp8266_pwm
    id: pwm_output
    pin: D3

interval:
  - interval: 1min
    then:
      - logger.log: pwm output is running
      - output.turn_on: pwm_output
      - output.turn_off: pwm_output
      - globals.set:
          id: send_millisecond
          value: !lambda 'return millis();'
      - logger.log: pwm output is stopped


binary_sensor:
  - platform: gpio
    pin: D2
    id: echo_receive_pin
    on_state:  
      then:
        - globals.set:
            id: diff_millisecond
            value: !lambda 'return millis() - int(send_millisecond);'
        - logger.log: D2 Received State Change


sensor:
  - platform: template
    name: "Last Echo Diff Time"
    id: last_echo_diff_time 
    filters:
      - lambda: return id(diff_millisecond);

Thanks again!

You should be fine with it as it is, no need to change the lambdas just yet.
And you may be onto something about pin D2 and what it expects and how itā€™s configured.
Take a look at the various options under Pin Schema (link below), and see if perhaps it needs, or doesnā€™t need, a pullup/pulldown set, inverted, etc.
Because itā€™s connected to an active-logic device, you probably donā€™t want any pullup or pulldown.
And one might expect that setting a sensor on GPIO would automatically put the pin in receive mode, it might not hurt to specify that explicitly.

I set D2 to ā€œinput: trueā€ and D3 to ā€œoutput:trueā€ and tried every combination of inverted for both pins and got the same results, also tried commenting ā€œoutput.turn_off: pwm_outputā€ just to see if I could ever get a state change on echo_receive_pin and I never do. I also tried setting the output pin to ā€œopen_drain: trueā€ and still nothing.

Current code is below but I still get no indication that there is ever a state change on the input pin.

globals:
  - id: send_millisecond
    type: int
    restore_value: yes
    initial_value: '0'
  - id: diff_millisecond
    type: int
    restore_value: yes
    initial_value: '0'

output:
  - platform: esp8266_pwm
    id: pwm_output
    pin:
      number: D3
      # inverted: true
      # frequency: 1000 Hz
      mode:
        output: true

interval:
  - interval: 1min
    then:
      - logger.log: pwm output is running
      - output.turn_on: pwm_output
      - output.turn_off: pwm_output
      - globals.set:
          id: send_millisecond
          value: !lambda 'return millis();'
      - logger.log: pwm output is stopped

binary_sensor:
  - platform: gpio
    id: echo_receive_pin
    pin:
      number: D2
      mode:
        input: true
      # inverted: true
    on_state:  
      then:
        - globals.set:
            id: diff_millisecond
            value: !lambda 'return millis() - int(send_millisecond);'
        - logger.log: D2 Received State Change


sensor:
  - platform: template
    name: "Last Echo Diff Time"
    id: last_echo_diff_time 
    filters:
      - lambda: 'return id(diff_millisecond);'

Does this device not have an arduino library?

I think someone above said there was but in effort to not add an additional layer (already using several other esphome devices), wanting to learn esphome better, and in the spirit of just trying, I wanted to see if it is possible in esphome before giving up.

I think with glyndonā€™s help we have gotten pretty close. Iā€™m sure the answer is somewhere in the spec sheet posted above but it is either worded oddly or it is over my head and I am missing something.

If there is a library then it is possible in esphome.