HC-SR04 Ultrasonic Sensor peaks


I have a HC-SR04 Ultrasonic Sensor connected to a nodemcu with ESPHome. Measuring works finde most of the time, but every few seconds I’m getting a wrong value an therefore peaks:

Are there any settings in ESPHome I can adjust to avoid or ignore these readings?

My configuration currently is the following:

  - platform: ultrasonic
    trigger_pin: D1
    echo_pin: D2
    update_interval: 3s
    name: "garagentor"
    timeout: 3m


I had the exact same issue with my ultrasonic sensor. The readings were correct, but there were downward Peaks every now and then.
I solved it by adding a “max” filter to the sensor. I know it’s a bit of a cheaty solution which doesn’t solve the actual problem, but it works very well for my situation.

I don’t think that will work for me because I am measuring the distance to my garage door. When the door is closed, it’s about 2.3m and when it’s opened, it’s about 10cm. The peaks are happening right between those measurements.

But I think I found my problem: I might have wired the sensor incorrectly. I believe I connected it to the 3V pin of the nodemcu instead of the 5V one. I will check on that when I get home.

Connecting the sensor to the 5V did not help, but I found a solution:

I added a filter to the sensor directly in ESPHome

      - median

This will give me an average of the last 5 readings (you can also customize this).

For more info:

I guess it was just a case of RTFM :smiley:

1 Like

same of mine:

Filter median helps, but produce slightly bigger value (similar to max filter).
May be a “not delta” filter would be better - don’t push a new value if differs more than threshold. But it’s not implemented.

I try solution from this:

    - lambda: |-
         float MAX_DIFFERENCE = .03;  // adjust this!
         static float last_value_t = NAN;
         static int count_missed_t = 0;
         if (count_missed_t == 3) last_value_t = x;
         if (isnan(last_value_t) || std::abs(x - last_value_t) < MAX_DIFFERENCE) {
            if (count_missed_t)
               ESP_LOGI("sensor", "New echo value %.3f", x);
            count_missed_t = 0;
            return last_value_t = x;
         } else {
            count_missed_t += 1;
            ESP_LOGW("sensor", "Missed echo value %.3f => %.3f, %d", last_value_t, x, count_missed_t);
            return last_value_t;
    - sliding_window_moving_average:
         window_size: 256
         send_every: 1

This works fine, so having filter “DeltaMax” would be nice.