logo elektroda
logo elektroda
X
logo elektroda

ESPHome WROOM-02 weather station - shuts down after 5h, what to do?

szyba20 1242 8
ADVERTISEMENT
Treść została przetłumaczona polish » english Zobacz oryginalną wersję tematu
  • #1 20929012
    szyba20
    Level 19  
    Hello
    Some time ago I made a project on a 3D printer for a weather station,
    using the materials on https://github.com/nliaudat/weatherstation?tab=readme-ov-file

    I based the station on the wroom 02 module, because it already uses a built-in socket for 18650, at that time it was one of the better choices for me,
    after adding a voltage divider and LM393, QMC5883L, 5V 0.6A solar panel.

    I set about adapting the Yaml code to my needs, everything in the test phase at home worked quite ok... 18650 cell according to the calculations should last about 30h plus the energy from the panel is known currently very low but in the summer days sufficient.

    I put everything together I tested it works, although I must admit I had to make some corrections to the project from the network.... the biggest misfortune was connecting it by screwing it together like a bolt.... I broke a few cables and changed to L-type connector

    ok to the point, the station worked about 5h after which it said it had enough and shut down at 3.7v :/ I want it to be wireless and support WiFi connectivity.... I can change to 433Mhz but my neighbour is a ham radio operator and he burnt my modules a couple of times already and I would prefer to avoid this :)

    Please advise me whether to look for a solution with support for another cell, bugs in Yaml or forget about it and pull the wire to the station....
    Windrose card configuration screen with wind direction and speed visualization
    Quote:
    esphome:
    name: weather-station
    friendly_name: WEATHER STATION

    esp8266:
    board: esp_wroom_02

    # Enable logging
    logger:

    # Enable Home Assistant API
    api:
    encryption:
    key: !!!!!!!!!!!!!!!!!!!!

    ota:
    password: !!!!!!!!!!!!!!

    wifi:
    networks:
    - ssid: "!!!!!!!!!!
    password: !!!!!!!!!!
    priority : 1
    - ssid: "!!!!!!!!!!!
    password: !!!!!!!!!!!!
    priority : 2
    - ssid: 1!!!!!!!!!!!!!
    password: "!!!!!!!!!!!


    # Enable fallback hotspot (captive portal) in case wifi connection fails
    ap:
    ssid: "WEATHER STATION"
    password: !!!!!!!!!!!!!!!


    captive_portal:

    # sun:
    # latitude: !secret latitude
    # longitude: !secret longitude

    globals:
    - id: enable_magnetometer_serial_output
    type: bool
    restore_value: no
    initial_value: 'false'

    i2c:
    - id: bus_a
    sda: GPIO5
    scl: GPIO4
    scan: True #True only if hmc5883l not detected at address 0x1E
    #frequency: 100kHz (max 400 kHz for hmc5883l)

    sensor:
    - platform: wifi_signal
    name: "${friendly_name} WiFi Signal"

    - platform: adc
    pin: A0
    name: "BATERRY"
    id: BATERRY
    unit_of_measurement: "%"
    accuracy_decimals: 0
    update_interval: 20s
    filters:
    - multiply: 12.2
    - calibrate_linear:
    - 4.25 -> 100
    - 4.13 -> 90
    - 4.06 -> 80
    - 3.99 -> 70
    - 3.92 -> 60
    - 3.85 -> 50
    - 3.78 -> 40
    - 3.71 -> 30
    - 3.64 -> 20
    - 3.57 -> 10
    - 3.48 -> 0
    - 3.39 -> -10

    - platform: uptime
    name: "${friendly_name} Uptime"
    id: uptime_sensor
    update_interval: 60s
    internal: true
    on_raw_value:
    then:
    - text_sensor.template.publish:
    id: uptime_human
    state: !"lambda |-
    int seconds = round(id(uptime_sensor).raw_state);
    int days = seconds / (24 * 3600);
    seconds = seconds % (24 * 3600);
    int hours = seconds / 3600;
    seconds = seconds % 3600;
    int minutes = seconds / 60;
    seconds = seconds % 60;
    return (
    (days ? String(days) + "d " : "") +
    (hours ? String(hours) + "h " : "") +
    (minutes ? String(minutes) + "m " : "") +
    (String(seconds) + "s")
    ).c_str();

    #https://esphome.io/components/sensor/hmc5883l.html?highlight=hmc5883
    #I2C connected : SDA (GPIO21) and SCL (GPIO22)
    - platform: qmc5883l
    address: 0x0D
    field_strength_x:
    name: "HMC5883L Field Strength X"
    internal: true
    id: hmc5883l_x
    field_strength_y:
    name: "HMC5883L Field Strength Y"
    internal: true
    id: hmc5883l_y
    field_strength_z:
    name: "HMC5883L Field Strength Z"
    internal: true
    id: hmc5883l_z
    heading:
    name: "${friendly_name} wind heading"
    id: hmc5883l_heading
    internal: true
    filters:
    - lambda: |-
    if(x < 0){ return x +360;}
    else{return x;}
    oversampling: 256x
    range: 800µT #Supported values are 88µT, 130µT, 190µT, 250µT, 400µT, 470µT, 560µT, 810µT. Default range is ±130µT.
    update_interval: 1s #max 160Hz=6.25ms but that component cannot be under 1s
    id: meteo_station_HMC5883L_magnetometer

    - platform: pulse_meter
    pin:
    number: GPIO13
    unit_of_measurement: 'km/h' #'m/s'
    name: '${friendly_name} wind speed'
    icon: 'mdi:weather-windy'
    internal_filter: 13us
    accuracy_decimals: 1
    #internal: true
    timeout: 1s
    # https://fr.wikipedia.org/wiki/An%C3%A9mom%C3%...m%C3%A8tre_%C3%A0_coupelles_(dit_de_Robinson)
    # [Wind speed in m/s] = 2PI * [anemometer mid cup to axle lenght in m] * [revolution per seconds] * [unknown correction factor]
    # anemometer mid cup to axle lenght = 72.5 mm => 72.5/1000 = 0.0725 m for R
    # rotary encoder pulse per revolution : 36
    # revolution per seconds = pulses /36 /60
    # S = 2PI * 0.0725 * pulses /36 /60 = 0.00021089395
    # Speed m/s => Km/h : *3.6 => 0.00075921822
    # [unknown correction factor or friction] = ~5 => 0.00075921822 *5
    filters:
    - multiply: 0.0037960911 #start at ~2km/h
    # - calibrate_polynomial:
    # degree: 2
    # datapoints: # Map 0.0 (from sensor) to 0.0 (true value)
    # - 5.0 -> 7.5
    # - 10.0 -> x.0
    # - 20.0 -> x.0
    # - 30.0 -> x.0
    # - 40.0 -> 40.0
    # - 50.0 -> 50.0
    # - 60.0 -> 60.0
    id: meteo_station_wind_speed


    - platform: template
    name: '${friendly_name} Wind speed avg 1s'
    unit_of_measurement: 'km/h' #'m/s'
    update_interval: 300ms #60s
    lambda: |-
    return id(meteo_station_wind_speed).state;
    filters:
    - sliding_window_moving_average:
    window_size: 3
    send_every: 3
    send_first_at: 3
    id: meteo_station_wind_speed_avg_1s


    - platform: template
    name: '${friendly_name} Wind speed avg 3s'
    unit_of_measurement: 'km/h' #'m/s'
    update_interval: 1s #60s
    lambda: |-
    return id(meteo_station_wind_speed).state;
    filters:
    - sliding_window_moving_average:
    window_size: 3
    send_every: 3
    send_first_at: 3
    id: meteo_station_wind_speed_avg_3s

    - platform: template
    name: '${friendly_name} Wind speed avg 60s'
    unit_of_measurement: 'km/h' #'m/s'
    update_interval: 1s
    lambda: |-
    return id(meteo_station_wind_speed).state;
    filters:
    - sliding_window_moving_average:
    window_size: 60
    send_every: 60
    send_first_at: 60
    id: meteo_station_wind_speed_avg_60s


    - platform: template
    name: '${friendly_name} Wind speed max'
    unit_of_measurement: 'km/h' #'m/s'
    update_interval: 60s
    lambda: |-
    return id(meteo_station_wind_speed).state;
    filters:
    - max:
    window_size: 5
    send_every: 5
    send_first_at: 2
    id: meteo_station_wind_speed_max


    # - platform: pulse_counter
    # pin:
    # number: GPIO38
    # mode: INPUT_PULLUP
    # unit_of_measurement: 'mm'
    # name: "${friendly_name} rain gauge"
    # icon: 'mdi:weather-rainy'
    # id: rain_gauge
    # internal: true
    # count_mode:
    # rising_edge: DISABLE
    # falling_edge: INCREMENT
    # internal_filter: 13us
    # update_interval: 60s
    # filters:
    # Each 0.011" (0.2794mm) of rain causes one momentary contact closure
    # - multiply: 0.2794
    # 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: total_daily_energy
    # name: "${friendly_name} total daily rain"
    # power_id: rain_gauge
    # unit_of_measurement: 'mm'
    # icon: 'mdi:weather-rainy'
    # x60 To convert to aggregated rain amount
    # filters:
    # - multiply: 60

    # - platform: bme280
    # address: 0x76
    # update_interval: 60s
    # iir_filter: 16x
    # temperature:
    # name: '${friendly_name} temperature'
    # id: bme280_temperature
    # oversampling: 16x
    # humidity:
    # name: "${friendly_name} humidity"
    # id: bme280_humidity
    # oversampling: 16x
    # pressure:
    # name: "${friendly_name} pressure"
    # id: bme280_pressure
    # oversampling: 16x

    # - platform: tsl2561
    # name: "${friendly_name} ambient Light"
    # address: 0x39
    # update_interval: 60s
    # integration_time: 14ms
    # gain: 1x

    # - platform: adc
    # pin: GPIO35
    # name: "${friendly_name} input voltage"
    # icon: mdi:car-battery
    # attenuation: 11db
    # accuracy_decimals: 2
    # filters:
    # - calibrate_linear:
    # - 3.24 -> 12.01
    # - 2.80 -> 10.78


    # - platform: ina219
    # address: 0x40
    # shunt_resistance: 0.1 ohm
    # current:
    # name: "${friendly_name} solar current"
    # power:
    # name: "${friendly_name} solar power"
    # id: solar_power
    # bus_voltage:
    # name: "${friendly_name} solar voltage"
    # icon: mdi:car-battery
    # shunt_voltage:
    # name: "${friendly_name} solar shunt voltage"
    # max_voltage: 26V
    # max_current: 3.2A
    # update_interval: 60s

    # - platform: total_daily_energy
    # name: "${friendly_name} total daily solar energy"
    # power_id: solar_power
    # unit_of_measurement: "Wh"
    # accuracy_decimals: 2


    # - platform: sun
    # name: "${friendly_name} sun elevation"
    # type: elevation
    # update_interval: 120s

    # - platform: sun
    # name: "${friendly_name} Sun azimuth"
    # type: azimuth
    # update_interval: 120s




    - platform: template
    name: "${friendly_name} true heading"
    unit_of_measurement: '°'
    lambda: |-


    // Taken from calibrate.py or magcal
    float hard_iron_bias_x = 41.45884154873271 ;
    float hard_iron_bias_y = -87.79628696573607 ;
    float hard_iron_bias_z = 569.4171225039286 ;


    double soft_iron_bias_xx = 0.5823136909144911 ;
    double soft_iron_bias_xy = 0.007124620314368133 ;
    double soft_iron_bias_xz = -0.024442807568982334 ;


    double soft_iron_bias_yx = 0.00712462031436818 ;
    double soft_iron_bias_y = 0.5906868599676302 ;
    double soft_iron_bias_yz = 0.005356720947343228 ;



    double soft_iron_bias_zx = -0.024442807568982372 ;
    double soft_iron_bias_zy = 0.005356720947343263 ;
    double soft_iron_bias_zz = 0.7210550285247264 ;


    // get values x,y,z and subtract the hard iron offset
    float xm_off = id(hmc5883l_x).state - hard_iron_bias_x;
    float ym_off = id(hmc5883l_y).state - hard_iron_bias_y;
    float zm_off = id(hmc5883l_z).state - hard_iron_bias_z;

    // multiply by the inverse soft iron offset
    float xm_cal = xm_off * soft_iron_bias_xx + ym_off * soft_iron_bias_yx + zm_off * soft_iron_bias_zx;
    float ym_cal = xm_off * soft_iron_bias_xy + ym_off * soft_iron_bias_y + zm_off * soft_iron_bias_zy;
    //not needed : float zm_cal = xm_off * soft_iron_bias_xz + ym_off * soft_iron_bias_yz + zm_off * soft_iron_bias_zz;

    //float heading = atan2(ym_cal, xm_cal);
    float heading = atan2(0 - xm_cal, ym_cal);

    //heading += id(magnetic_declination);

    if(id(enable_magnetometer_serial_output) == true){
    ESP_LOGD("main", "%.1f,%.1f,%.1f", id(hmc5883l_x).state, id(hmc5883l_y).state, id(hmc5883l_z).state);
    }
    // Correct for when signs are reversed.
    if (heading < 0) {
    heading += 2*PI;
    }
    // Check for wrap due to addition of declination.
    if (heading > 2*PI) {
    //heading -= 2*PI;
    }
    float headingDegrees = heading * 180/M_PI; // Convert radians to degrees.
    return headingDegrees;
    update_interval: 1s
    id: meteo_station_wind_true_heading

    text_sensor:
    # - platform: template
    # name: "${friendly_name} wind cardinal direction" #16 cardinals points
    # lambda: |-
    # float deg = id(meteo_station_wind_true_heading).state;
    # if(deg < 0){ deg= 360+deg;}
    # if ((deg >= 11.25) and (deg < 33.75)) {return {"NNE"} ;}
    # else if ((deg >= 33.75) and (deg < 56.25)) {return {"NE"} ;}
    # else if ((deg >= 56.25) and (deg < 78.75)) { return {"ENE"} ;}
    # else if ((deg >= 78.75) and (deg < 101.25)) {return {"E"} ;}
    # else if ((deg >= 101.25) and (deg < 123.75)) {return {"ESE"} ;}
    # else if ((deg >= 123.75) and (deg < 146.25)) {return {"SE"} ;}
    # else if ((deg >= 146.25) and (deg < 168.75)) {return {"SSE"} ;}
    # else if ((deg >= 168.75) and (deg < 191.25)) {return {"S"} ;}
    # else if ((deg >= 191.25) and (deg < 213.75)) {return {"SSW"} ;}
    # else if ((deg >= 213.75) and (deg < 236.25)) {return {"SW"} ;}
    # else if ((deg >= 236.25) and (deg < 258.75)) {return {"WSW"} ;}
    # else if ((deg >= 258.75) and (deg < 281.25)) {return {"W"} ;}
    # else if ((deg >= 281.25) and (deg < 303.75)) {return {"WNW"} ;}
    # else if ((deg >= 303.75) and (deg < 326.25)) {return {"NW"} ;}
    # else if ((deg >= 326.25) and (deg < 348.75)) {return {"NNW"} ;}
    # else {return {"N"} ;}
    # update_interval: 1s
    # id: meteo_station_wind_direction

    - platform: template
    name: "${friendly_name} wind cardinal direction" #8 cardinals points
    lambda: |-
    float deg = id(meteo_station_wind_true_heading).state;
    if(deg < 0){ deg= 360+deg;}
    if ((deg >= 0) and (deg < 22.5)) {return {"N"} ;}
    else if ((deg >= 22.5) and (deg < 56.25)) { return {"NE"} ;}
    else if ((deg >= 56.25) and (deg < 123.75)) { return {"E"} ;}
    else if ((deg >= 123.75) and (deg < 168.75)) {return {"SE"} ;}
    else if ((deg >= 168.75) and (deg < 213.75)) {return {"S"} ;}
    else if ((deg >= 213.75) and (deg < 258.75)) {return {"SW"} ;}
    else if ((deg >= 258.75) and (deg < 303.75)) {return {"W"} ;}
    else if ((deg >= 303.75) and (deg < 348.75)) {return {"NW"} ;}
    else {return {"N"} ;}
    update_interval: 1s
    id: meteo_station_wind_direction


    - platform: template
    name: "${friendly_name} uptime"
    id: uptime_human
    icon: mdi:clock-start
    # - platform: sun
    # name: "${friendly_name} next sunrise"
    # type: sunrise
    # update_interval: 4h
    # - platform: sun
    # name: "${friendly_name} next sunset"
    # type: sunset
    # update_interval: 4h


    time:
    - platform: sntp
    timezone : Europe/Zurich
    #timezone: UTC+1
    servers: [0.pool.ntp.org, 1.pool.ntp.org , 2.pool.ntp.org]
    on_time:
    - seconds: 0
    minutes: 0
    hours: 6
    days_of_week: MON
    then:
    - switch.toggle: switch_meteo_station_reboot
    id: meteo_station_time

    # interval:
    # - interval: 60s
    # then:
    # - sensor.integration.reset: rain_per_min

    web_server:
    port: 80

    switch:
    - platform: restart
    name: "${friendly_name} reboot"
    id: switch_meteo_station_reboot


    - platform: template
    name: "Toogle magnetometer serial output"
    turn_on_action:
    - script.execute: toogle_magnetometer_serial_output


    script:
    - id: toogle_magnetometer_serial_output
    then:
    - lambda: |-
    ESP_LOGD("main", "toogle magnetometer calibration output");
    id(enable_magnetometer_serial_output) = !id(enable_magnetometer_serial_output) ;

    deep_sleep:
    run_duration: 1min
    sleep_duration: 15min
    .
  • ADVERTISEMENT
  • #2 20933837
    khoam
    Level 42  
    Why did you set the 'run_duration' parameter all the way to 1 minute?
  • ADVERTISEMENT
  • #3 20934698
    szyba20
    Level 19  
    More for testing so that I have time to load the changes before it falls asleep.... The station hangs quite high and a ladder with a cable is a nuisance.... i was going to replace it after testing with 10s
  • #4 20934845
    khoam
    Level 42  
    szyba20 wrote:
    I was going to replace this after testing with 10s
    Then there will also be a significant increase in battery life.
    I do not have such a board. Does any LED light up during normal battery operation?
  • #5 20934952
    szyba20
    Level 19  


    someone has thought this through and during operation everything is switched off and only the charging has a red information LED,
    I decided to leave it because the charging rises above 4.5v anyway, the solar panel should be able to cope with this,

    I made a small test today and without the 18650 cell the panel on a cloudy day can run the station (of course there were problems with the communication, etc. ..) in full sun 0.55A and the demand is less than 240mA during transmission.

    In my opinion it should work ... but as I mentioned this is the first time I'm trying to get something working with the cell and panel.

    Added after 6 [minutes]:

    aa I forgot to add the station lives up to about 60% cell charge and gets dead.... i checked the logs from home asisstant and from the router which splits the dhcp and the weather station does not even try to connect to the access point if the power drops below 3.6V - 3.7V,
    after plugging in the laptop and checking the logs it suddenly wakes up and connects to the wifi and sends data :/ after unplugging it again quiet for 4 5H and repeat....
  • ADVERTISEMENT
  • #6 20935019
    khoam
    Level 42  
    Can you measure how much current flows when the ESP8266 is in deep-sleep mode? I'm afraid that the CP2102 chip (USB-UART converter) on this board is responsible for the increased current consumption during deep-sleep, even if you don't use it.


    TP5410 on this board is a step-down voltage converter. If it is to give an output of 3.3V for the ESP8266, then its input cannot be less than approx. 3.65V ( Link ), Have you tried using cells from another manufacturer?
  • #7 20935254
    szyba20
    Level 19  
    I source the cells from broken screwdriver batteries.... according to the charger after double discharging and charging roughly 1800-2200mA although today I was wondering if I should stuff some pack from a tablet or phone but they are probably less resistant to the changing conditions outside....

    tomorrow I'll take the station off the roof because I'm tired of flying to it :) and check everything on the table at home

    With this TP5410 you surprised me a little, I thought that calmly to 3.2 3.0V discharges the cell as far as I know is 3.7V is the nominal value of 18650 and here you give 3.65V :/.
  • #8 20935283
    khoam
    Level 42  
    szyba20 wrote:
    With this TP5410 you surprised me a little, I thought that calmly to 3.2 3.0V discharges the cell as far as I know 3.7V is the nominal value of 18650 and here you give 3.65V :/

    I also don't quite understand the use of exactly this TP chip on this board, but the catalogue note rather not lie :) .
  • ADVERTISEMENT
  • #9 21085032
    szyba20
    Level 19  
    Hello again
    after several replacements of these unfortunate wroom 02 or lolin as it alternates on the forums, I find that either I do not understand something or they themselves, even in deep sleep mode, eat the cells faster than a guinea pig of fresh dairy milk....
    I swapped to esp8266 and fed 12v through an inverter from the car charger 5v to the esp and it has lived for several weeks without failure.
  • Topic summary

    The discussion revolves around a weather station project utilizing the ESPHome WROOM-02 module, which experiences shutdowns after approximately 5 hours of operation. The user initially set a short 'run_duration' for testing purposes, which may have contributed to battery life issues. The station operates on a 18650 lithium-ion cell, supplemented by a solar panel, but struggles to maintain power, particularly when the cell charge drops below 3.6V. Users suggest measuring current consumption during deep sleep mode and consider the impact of the CP2102 USB-UART converter on power usage. The user has experimented with different battery sources and noted that the ESP8266 variant has shown better longevity. Concerns about the TP5410 step-down voltage converter's performance at lower voltages are also raised.
    Summary generated by the language model.
    ADVERTISEMENT