Measuring wind speed

Hello chm3r,
Can you please share your automation please ?
I tried to do something like that but without success.

Sincerely,

I’m trying to make my Sparkfun weather kit communicate with my ESP32 via a Sparkfun breakboard. Any one tried this with success? It did work, but on 50%. Example is that my winddirection meter is working but when it rotates quickly it’s recording also the windspeed which is not OK. The Windspeed itselfs won’t register anything.

Via the breakerboard it’s connected with 4 pins to my ESP32, so Y = winddirection which connects to GPIO34. G = windspeed which connects to GPIO14. R = red, 3.3v to 3.3v on esp. And then B = ground, which is connected to ground.

I hope someone can tell me what I do wrong. I really want to make this works.

Breakerboard: SparkFun RJ11 Breakout.

If you use the sparkfun weather kit consisting of windspeed, wind direction and rain sensor, then the wind speed sensor rj11 connects to the wind direction sensor.
Those two sensors are combined in one rj11, to be connected to your esp32.

Pins used are 2,3,4 and 5.
Pins 2 and 3 go to ground.
Pin 4 is the windspeed, goes to an gpio-pin, but connected also to a 10k pull-up resistor to 3.3v.
Pin 5 is the wind direction, goes to an adc-able gpio pin (check the particulars of the esp you’re using, but most likely in the range of gpio pins 34-39). Also this pin needs a 10k pull-up resistor to 3.3v.

Note, as you just measure pulses between pins 3 and 4 for windspeed, and just resistance between pins 2 and 5 for wind direction, you can swap all pins. So either use the above 2,3,4,5 sequence, but also possible 4 and 5 to ground, 3 for windspeed and 2 for wind direction, gives same result.

Hi Wim,

Thanks for the reply!

Hi Wim,

Do you have a working yaml? Windspeed is now working correctly. But the winddirection is a problem for me to calibrate to the right direction.

This is what I got right now:

sensor:
  # Wind Snelheid
  - platform: pulse_meter
    pin:
      number: GPIO13
      mode: INPUT
    name: "Windsnelheid"
    unit_of_measurement: 'km/h'
    accuracy_decimals: 1
    timeout: 5s  # Gaat naar 0 als er 10s geen pulsen zijn
    filters:
      - heartbeat: 2s
      - multiply: 0.04  # 1 pulse/s = 1.2 km/h → 1 pulse/s = 0.04 * pulse_frequency (25 pulses/s = 1s → 1 pulse = 0.04 km/h)
      - sliding_window_moving_average:
          window_size: 4
          send_every: 1

  # Windrichting in graden (ADC)
### ADD WIND DIRECTION
  - platform: adc
    pin: GPIO34
    id: adc_sensor
    name: "ADC Spanning"
    internal: true
    update_interval: 5s
    accuracy_decimals: 3

  - platform: resistance
    sensor: adc_sensor
    id: resistance_sensor
    name: "Windrichting Weerstand"
    resistor: 10kOhm
    configuration: DOWNSTREAM
    internal: true
    accuracy_decimals: 0
    filters:
      - heartbeat: 60s

    on_value:
      - if:
          condition:
            sensor.in_range:
              id: resistance_sensor
              above: 3050
              below: 3200
          then:
            - text_sensor.template.publish:
                id: wind_dir_card
                state: "N"
            - sensor.template.publish:
                id: wind_heading
                state: 0.0

      - if:
          condition:
            sensor.in_range:
              id: resistance_sensor
              above: 1580
              below: 1700
          then:
            - text_sensor.template.publish:
                id: wind_dir_card
                state: "NE"
            - sensor.template.publish:
                id: wind_heading
                state: 45.0

      - if:
          condition:
            sensor.in_range:
              id: resistance_sensor
              above: 250
              below: 350
          then:
            - text_sensor.template.publish:
                id: wind_dir_card
                state: "E"
            - sensor.template.publish:
                id: wind_heading
                state: 90.0

      - if:
          condition:
            sensor.in_range:
              id: resistance_sensor
              above: 550
              below: 650
          then:
            - text_sensor.template.publish:
                id: wind_dir_card
                state: "SE"
            - sensor.template.publish:
                id: wind_heading
                state: 135.0

      - if:
          condition:
            sensor.in_range:
              id: resistance_sensor
              above: 900
              below: 1100
          then:
            - text_sensor.template.publish:
                id: wind_dir_card
                state: "S"
            - sensor.template.publish:
                id: wind_heading
                state: 180.0

      - if:
          condition:
            sensor.in_range:
              id: resistance_sensor
              above: 2300
              below: 2450
          then:
            - text_sensor.template.publish:
                id: wind_dir_card
                state: "SW"
            - sensor.template.publish:
                id: wind_heading
                state: 225.0

      - if:
          condition:
            sensor.in_range:
              id: resistance_sensor
              above: 3900
              below: 4100
          then:
            - text_sensor.template.publish:
                id: wind_dir_card
                state: "W"
            - sensor.template.publish:
                id: wind_heading
                state: 270.0

      - if:
          condition:
            sensor.in_range:
              id: resistance_sensor
              above: 3500
              below: 3700
          then:
            - text_sensor.template.publish:
                id: wind_dir_card
                state: "NW"
            - sensor.template.publish:
                id: wind_heading
                state: 315.0

  # Template voor gradenwaarde van richting
  - platform: template
    id: wind_heading
    name: "Windrichting (graden)"
    unit_of_measurement: "°"
    accuracy_decimals: 0
    update_interval: never

text_sensor:
  - platform: template
    id: wind_dir_card
    name: "Windrichting (kompas)"
    update_interval: never

Hi BliXem,

your problem is likely that the code you are using only takes into account the 8 switches in the windsensor. But … in the SparkFun device, sometimes 2 switches can be closed simultaneously, resulting different wind directions. Your code only shows 8 wind directions, but the resistance values from which those are calculated are not continuous, leaving gaps, and in those gaps you don’t see a wind direction.
I did a full sweep (360 degrees) with small increments, just measuring voltage in first instance. My SparkFun showed 16 different voltages, so 16 different resistance values with associated wind directions. I made a continuous series of resistance values from this on order not to leave any gaps (see my code below). I personally don’t like that I ended up with 16 wind directions, but this is how the SparkFun device works.

So here’s my yaml code

  - platform: adc
    id: source_sensor
    pin: GPIO37
    name: ADC
    attenuation: 12db
    internal: True
    update_interval: 10s
    accuracy_decimals: 3

  - platform: resistance
    sensor: source_sensor
    id: resistance_sensor
    configuration: DOWNSTREAM
    resistor: 10kOhm
    internal: True
    name: Resistance Sensor
    reference_voltage: 3.3V
    accuracy_decimals: 1
    on_value:
      - if:
          condition:
            sensor.in_range:
              id: resistance_sensor
              above: 29000.0
              below: 36999.9
          then:
            - text_sensor.template.publish:
                id: wind_dir_card
                state: "N"
            - sensor.template.publish:
                id: wind_heading
                state: 0.0
      - if:
          condition:
            sensor.in_range:
              id: resistance_sensor
              above: 5000.0
              below: 7399.9
          then:
            - text_sensor.template.publish:
                id: wind_dir_card
                state: "NNE"
            - sensor.template.publish:
                id: wind_heading
                state: 22.5
      - if:
          condition:
            sensor.in_range:
              id: resistance_sensor
              above: 7400.0
              below: 11999.9
          then:
            - text_sensor.template.publish:
                id: wind_dir_card
                state: "NE"
            - sensor.template.publish:
                id: wind_heading
                state: 45.0
      - if:
          condition:
            sensor.in_range:
              id: resistance_sensor
              above: 800.0
              below: 949.9
          then:
            - text_sensor.template.publish:
                id: wind_dir_card
                state: "ENE"
            - sensor.template.publish:
                id: wind_heading
                state: 67.5
      - if:
          condition:
            sensor.in_range:
              id: resistance_sensor
              above: 950.0
              below: 1199.9
          then:
            - text_sensor.template.publish:
                id: wind_dir_card
                state: "E"
            - sensor.template.publish:
                id: wind_heading
                state: 90.0
      - if:
          condition:
            sensor.in_range:
              id: resistance_sensor
              above: 600.0
              below: 799.9
          then:
            - text_sensor.template.publish:
                id: wind_dir_card
                state: "ESE"
            - sensor.template.publish:
                id: wind_heading
                state: 112.5
      - if:
          condition:
            sensor.in_range:
              id: resistance_sensor
              above: 1900.0
              below: 2699.9
          then:
            - text_sensor.template.publish:
                id: wind_dir_card
                state: "SE"
            - sensor.template.publish:
                id: wind_heading
                state: 135.0
      - if:
          condition:
            sensor.in_range:
              id: resistance_sensor
              above: 1200.0
              below: 1899.9
          then:
            - text_sensor.template.publish:
                id: wind_dir_card
                state: "SSE"
            - sensor.template.publish:
                id: wind_heading
                state: 157.5
      - if:
          condition:
            sensor.in_range:
              id: resistance_sensor
              above: 3500.0
              below: 4999.9
          then:
            - text_sensor.template.publish:
                id: wind_dir_card
                state: "S"
            - sensor.template.publish:
                id: wind_heading
                state: 180.0
      - if:
          condition:
            sensor.in_range:
              id: resistance_sensor
              above: 2700.0
              below: 3499.9
          then:
            - text_sensor.template.publish:
                id: wind_dir_card
                state: "SSW"
            - sensor.template.publish:
                id: wind_heading
                state: 202.5
      - if:
          condition:
            sensor.in_range:
              id: resistance_sensor
              above: 14250.0
              below: 18999.9
          then:
            - text_sensor.template.publish:
                id: wind_dir_card
                state: "SW"
            - sensor.template.publish:
                id: wind_heading
                state: 225.0
      - if:
          condition:
            sensor.in_range:
              id: resistance_sensor
              above: 12000.0
              below: 14249.9
          then:
            - text_sensor.template.publish:
                id: wind_dir_card
                state: "WSW"
            - sensor.template.publish:
                id: wind_heading
                state: 247.5
      - if:
          condition:
            sensor.in_range:
              id: resistance_sensor
              above: 100000.0
              below: 150000.9
          then:
            - text_sensor.template.publish:
                id: wind_dir_card
                state: "W"
            - sensor.template.publish:
                id: wind_heading
                state: 270.0
      - if:
          condition:
            sensor.in_range:
              id: resistance_sensor
              above: 37000.0
              below: 51999.9
          then:
            - text_sensor.template.publish:
                id: wind_dir_card
                state: "WNW"
            - sensor.template.publish:
                id: wind_heading
                state: 292.5
      - if:
          condition:
            sensor.in_range:
              id: resistance_sensor
              above: 52000.0
              below: 99999.9
          then:
            - text_sensor.template.publish:
                id: wind_dir_card
                state: "NW"
            - sensor.template.publish:
                id: wind_heading
                state: 315.0
      - if:
          condition:
            sensor.in_range:
              id: resistance_sensor
              above: 19000.0
              below: 28999.9
          then:
            - text_sensor.template.publish:
                id: wind_dir_card
                state: "NNW"
            - sensor.template.publish:
                id: wind_heading
                state: 337.5

  - platform: template
    name: "Wind heading"
    id: wind_heading
    unit_of_measurement: "°"
    accuracy_decimals: 1

text_sensor:
  - platform: template
    name: "Wind direction"
    id: wind_dir_card

I also give my yaml part for the wind speed, as I noticed you use a multiplication value of 0.04, which looks correct if you read the SparkFun manual. However, see post #3 in this thread, this guy has been testing the Sparkfun, and there appears to be an error in translation from the Chinese manual to the English version. The windspeed mentioned in the manual (2.4km/hr) does not give 1 click, but one rotation of the cups, but one rotation gives 2 clicks, so the multiplication factor should be 0.02 (this guy even tested the Sparkfun by sticking the windspeed meter out of his car window, and comparing driving speed and measured windspeed).

Here is the yaml part of the windspeed:

  - platform: pulse_meter
    pin:
      number: GPIO23
      mode: INPUT
    id: wind_speed
    unit_of_measurement: 'km/h'
    name: "Wind speed meter"
    icon: 'mdi:weather-windy'
    device_class: wind_speed
    state_class: measurement
    accuracy_decimals: 2
    internal_filter: 10ms
    timeout: 2s
    filters:
      - multiply: 0.02   # 2.4 km/hr / 60 pulses / 2 clicks per rotation
      - heartbeat: 2s
      - throttle_average: 2s

And another issue: I faced some problems with doing the statistics on the ESP32. Also from an article on this forum, I only send wind-speed from the ESP to HA, and do all statistics in HA itself, using the statistics platform. Much easier to derive 1-min / 10-min mean windspeed and wind gusts. (Same for rain fall, also here using HA-statistics).

If you are interested I can give you the complete yaml (and associated HA statistics sensors), my weather station now includes an SHT-30 outdoor temp/humidity sensor (Adafruit SHT30), BME280 (temp, humidity and pressure), rain fall (SparkFun) and an SDS011 particle sensor (fijnstof) 2.5 ppm and 10 ppm.

1 Like

Hi Wim, thanks again! I think this is good for now. :).

Did you connect it to the same 3.3v pin? I’ve got 2 3v3 pins and 2 ground.

Doesn’t matter, both (all) 3.3v pins are connected to each other, same for ground pins

Hmm, okay. Then something goes wrong at my setup because it register only S, SE, E. Will check that later and redo the resistors.