Help with calibrating wind speed on weather station

Hi,

I have had my weather station running for a while now, but the Wind Speed seems to be the only thing that is not quite right.

I am curious as to how people are actually able to calibrate the wind speed? Do you use a known wind speed source? I have tried with a hand help anemometer but the wind fluxgate’s so much its hard to actually calibrate.

Right now, my wind speed is measure between 3000 and 5000km/s which I really hope is not right.

How can I get this right? I have calibrated the rain sensor and everything but the wind I have had so much trouble with. I have a 5 inch anemometer prop.

My code is as follows.

I would appreciate any help with this. Thanks

esphome:
  name: "weather-station"
  friendly_name: "weather-station"
  platform: ESP32
  board: esp-wrover-kit
  comment: 'Ethernet'

# Enable logging
logger:

# Enable Home Assistant API
api:
  encryption:
    key: ""
  on_client_connected:
    - light.turn_on:
         id: led
         brightness: 100%
         red: 0%
         green: 100%
         blue: 0%
         effect: none
  on_client_disconnected:
     - light.control:
         id: led
         state: on
         effect: ERROR

ota:
  - platform: esphome
    password: ""
    
i2c:
  sda: 2
  scl: 4
#  scan: True
  id: bus_a

web_server:
  port: 80
  log: true
  local: True
  include_internal: true
  version: 3
  auth:
    username: !secret web_server_username
    password: !secret web_server_password

ethernet:
  type: LAN8720
  mdc_pin: GPIO23
  mdio_pin: GPIO18
  clk_mode: GPIO0_IN
  phy_addr: 1
  power_pin: GPIO16


  # Optional manual IP
  manual_ip:
    static_ip: 172.16.102.17
    gateway: 172.16.102.1
    subnet: 255.255.255.224

sensor:
####Tempreature & Humidity Start####
  - platform: sht3xd
    temperature:
      name: "Temperature"
    humidity:
      name: "Humidity"
    address: 0x44
    update_interval: 60s
####Tempreature & Humidity END####

####Rainfall Start####
  - platform: pulse_counter
    pin:
      # Don't forget to add a pulling resistor, see README
      number: GPIO15
      mode: INPUT
    unit_of_measurement: 'mm'
    name: "${friendly_name} rain gauge"
    icon: 'mdi:weather-rainy'
    id: rain_gauge
    count_mode:
      rising_edge: DISABLE
      falling_edge: INCREMENT
    internal_filter: 13us
    update_interval: 1s
    filters:
      # Each 0.011" (0.2794mm) of rain causes one momentary contact closure
      - multiply: 0.2
    accuracy_decimals: 4

  - platform: integration
    name: "${friendly_name} rainfall per min"
    id: rain_per_min
    time_unit: min
    unit_of_measurement: 'mm'
    icon: 'mdi:weather-rainy'
    sensor: rain_gauge

  - platform: integration
    name: "${friendly_name} rainfall per hour"
    id: rain_per_hour
    time_unit: h
    unit_of_measurement: 'mm'
    icon: 'mdi:weather-rainy'
    sensor: rain_gauge

  - platform: integration
    name: "${friendly_name} rainfall per day"
    id: rain_per_daily
    time_unit: d
    unit_of_measurement: 'mm'
    icon: 'mdi:weather-rainy'
    sensor: rain_gauge

  - platform: total_daily_energy
    name: "${friendly_name} 24 Hour Rain"
    power_id: rain_gauge
    unit_of_measurement: 'mm'
    icon: 'mdi:weather-rainy'
    filters:
      - multiply: 60
      # x60 To convert to aggregated rain amount
####Rainfall End####

####Sun Start####
  - platform: sun
    name: "Sun elevation"
    type: elevation
    update_interval: 120s

  - platform: sun
    name: "Sun azimuth"
    type: azimuth
    update_interval: 120s
####Sun End####

####Wind Speed Start####
  - platform: pulse_meter
    pin:
      number: GPIO12
      mode: INPUT
    id: wind_speed
    unit_of_measurement: 'm/s'
    name: "${friendly_name} wind speed"
    icon: 'mdi:weather-windy'
    internal_filter: 13us
    timeout: 5s
    filters:
      - multiply: 1.2
#      - sliding_window_moving_average:
#          window_size: 5
#          send_every: 5

  - platform: copy
    name: '${friendly_name} wind speed average'
    icon: 'mdi:weather-windy'
    id: wind_speed_avg
    source_id: wind_speed
    unit_of_measurement: 'm/s'
    filters:
      - throttle_average: 5s

  - platform: copy
    name: '${friendly_name} wind speed (km/h)'
    id: wind_speed_kmh
    source_id: wind_speed
    unit_of_measurement: 'km/h'
    icon: 'mdi:weather-windy'
    filters:
      - multiply: 3.6

  - platform: copy
    name: '${friendly_name} wind speed average (km/h)'
    icon: 'mdi:weather-windy'
    id: wind_speed_kmh_avg
    source_id: wind_speed_avg
    unit_of_measurement: 'km/h'
    filters:
      - multiply: 3.6
    on_value:
      lambda: |-
        if (x < 1) {
          id(wind_scale_code).publish_state("0");
          id(wind_scale).publish_state("Calm");
        } else if (x >= 1 && x < 6) {
          id(wind_scale_code).publish_state("1");
          id(wind_scale).publish_state("Light Air");
        } else if (x >= 6 && x < 12) {
          id(wind_scale_code).publish_state("2");
          id(wind_scale).publish_state("Light Breeze");
        } else if (x >= 12 && x < 20) {
          id(wind_scale_code).publish_state("3");
          id(wind_scale).publish_state("Gentle Breeze");
        } else if (x >= 20 && x < 29) {
          id(wind_scale_code).publish_state("4");
          id(wind_scale).publish_state("Moderate Breeze");
        } else if (x >= 29 && x < 39) {
          id(wind_scale_code).publish_state("5");
          id(wind_scale).publish_state("Fresh Breeze");
        } else if (x >= 39 && x < 50) {
          id(wind_scale_code).publish_state("6");
          id(wind_scale).publish_state("Strong Breeze");
        } else if (x >= 50 && x < 62) {
          id(wind_scale_code).publish_state("7");
          id(wind_scale).publish_state("Near Gale");
        } else if (x >= 62 && x < 75) {
          id(wind_scale_code).publish_state("8");
          id(wind_scale).publish_state("Gale");
        } else if (x >= 75 && x < 89) {
          id(wind_scale_code).publish_state("9");
          id(wind_scale).publish_state("Severe Gale");
        } else if (x >= 89 && x < 103) {
          id(wind_scale_code).publish_state("10");
          id(wind_scale).publish_state("Storm");
        } else if (x >= 103 && x < 118) {
          id(wind_scale_code).publish_state("11");
          id(wind_scale).publish_state("Violent Storm");
        } else if (x >= 118) {
          id(wind_scale_code).publish_state("12");
          id(wind_scale).publish_state("Hurricane Force");
        } else {
          ESP_LOGD("main", "It shouldn't happen (wind_speed_kmh_avg: %f)", x);
        }
####Wind Speed END####

####Wind Direction Start####
  - platform: mlx90393
    address: 0x0c
    id: mlx
#    gain: 1X
    x_axis:
      name: "mlx_x"
      id: "mlx_x"
      resolution: 16BIT
    y_axis:
      name: "mlx_y"
      id: "mlx_y"
      resolution: 16BIT
    z_axis:
      name: "mlx_z"
      resolution: 16BIT
    update_interval: 2s


  - platform: template
    id: 'wind_direction'
    name: 'Wind Direction'
    update_interval: 2s
    lambda: |-
      float w1 = id(mlx_x).state;  // magnetometer X
      float w0 = id(mlx_y).state;  // magnetometer Y
      float w = atan2(w0, w1);     // arctangent2 = radians
      w = (w * 180) / M_PI;    // radians to degrees
      w += 19.50;              // magnetic declination
      w += 50.00;              // seems to be off by 90
      if ( w < 0 ) w += 360.0; // adjust for negatives
      return w;
####END Wind Direction####


####FAN Switch Start####
#switch:
#  - platform: gpio
#    pin: 25
#    name: "Fan"
#    inverted: True
####Fan Switch END####

####Status LED Start####
light:
  - platform: fastled_clockless
    id: led
    name: "LED"
    pin: 14
    chipset: WS2812
    num_leds: 1
    rgb_order: GRB
    restore_mode: ALWAYS_OFF
    effects:
      - lambda:
          name: "ERROR"
          update_interval: 1s
          lambda: |-
            static bool state = false;
            auto call = id(led).turn_on();
            call.set_transition_length(500);
            call.set_rgb(1, 0, 0);
            if (!state) {
              call.set_brightness(1);
            } else {
              // If using 0, it freaks Home Assistant UI.
              call.set_brightness(0.01);
            }
            call.perform();
            state = !state;
      - lambda:
          name: "BOOT"
          update_interval: 1s
          lambda: |-
            static bool state = false;
            auto call = id(led).turn_on();
            call.set_transition_length(500);
            call.set_rgb(0, 1, 0);
            if (!state) {
              call.set_brightness(1);
            } else {
              // If using 0, it freaks Home Assistant UI.
              call.set_brightness(0.01);
            }
            call.perform();
            state = !state;
####Status LED END####

####Rain Reset Timer Start####
interval:
  - interval: 60s
    then:
      - sensor.integration.reset: rain_per_min

####Rain Reset Timer END####

####Time Start####
time:
  - platform: homeassistant
####Time End####

text_sensor:
  - platform: sun
    name: Sun Next Sunrise
    type: sunrise
  - platform: sun
    name: Sun Next Sunset
    type: sunset

  - platform: template
    name: '${friendly_name} Beaufort wind scale code'
    icon: 'mdi:tailwind'
    id: wind_scale_code

  - platform: template
    name: '${friendly_name} Beaufort wind scale'
    icon: 'mdi:tailwind'
    id: wind_scale
    update_interval: never

button:
  - platform: restart
    name: "Weather Station Reboot"

Manufacturer didn’t supply any information for pulse/speed conversion??

You need to calibrate the pulse_meter sensor to some known wind speed.
Remove the multiply 1.2
Output is pulses/minute.
Observe what it outputs while also measuring with your hand held anemometer.
Post what you get.

No, these devices certainly we not designed to be modified.

I have reached out to the manufacturer for the pulse count, they gave me the anemometer size, I replied asking for pulse count.

Will do and will let you know

So im not sure if this helps at all, but just a basic RAW pulse counter, obv the wind is blowing.

image

It’s very hard to me to imagine that wind speed pulse sensor is giving 3000 pulses/minute. While possible, not probable.
Does it react to different speeds?

I should provide the code in case I messed something up. This is using GPIO12 on a WT32-ETH01

  - platform: pulse_meter
    pin:
      number: GPIO12
      mode: INPUT
    id: wind_speed
    name: Wind Speed Raw Pulse

My questions to support,

Q: Could you please provide me the details of the dimensions for the propeller on the Kestrelmet 6000 Anemometer?
A. It is a 5 inch diameter anemometer.

Q. Also would you happen to know how many pulses per rotation the pulse counter is?
A. This is proprietary, sorry.

They dont want to share.

Shit, do I need a pullup or pull down resistor over the pulse_counter?

Elon is talking about going to Mars and you’re already living in the middle of Jupiter’s giant red eye storm. Noice.

Making the multiply value very small, brings my pulse counts down significantly, this is obviously guessing.

    filters:
      - multiply: 0.003086

image

I think your best bet is to calibrate with a known measurement like your handheld. Instead of wind, use a more consistent source like an oscillating fan.

How do I know the fans wind speed haha

in your orignal post you mentioned a hand held anemometer?

Yea I’ll have to find it,

The the plan is, measure the wind speed of the fan, then adjust the multiplier value until the weather station matches the speed of the fan?

Is this a sufficient method to calibrate? Can I assume that different wind speeds will be correct?