Witam
Jakiś czas temu wykonałem projekt na drukarce 3D stacji pogodowej,
korzystając z materiałów zawartych na stronie https://github.com/nliaudat/weatherstation?tab=readme-ov-file
Stacje oparłem na module wroom 02, ponieważ korzysta on już z wbudowanego gniazda dla 18650, wtedy był to dla mnie jeden z lepszych wyborów,
po dodaniu dzielnika napięć oraz LM393, QMC5883L, Panelu solarnego 5V 0,6A.
Zabrałem się za dostosowanie kodu Yaml pod swoje potrzeby, wszystko w fazie testów w domu działało w miarę ok.. ogniwo 18650 według obliczeń powinno wytrzymać jakieś 30h plus energia z panelu wiadomo aktualnie bardzo niska ale w letnie dni wystarczająca.
Złożyłem wszystko do kupy przetestowałem działa, choć nie ukrywam musiałem nanieść kilka poprawek do projektu z sieci.. największy niewypał to łączenie tego za pomocą skręcania jak śrubę... kilka kabli zerwałem przy tym i zmieniłem na łącznik typu L
ok do sedna, stacja podziałała jakieś 5h po czym stwierdziła ze ma dość i wyłączyła się przy 3.7v :/ zależy mi aby była ona bezprzewodowa i obsługiwała łączność WiFi.. mogę zmienić na 433Mhz ale sąsiad jest krótkofalowcem i kilka razy upalił mi już moduły i wolałbym tego uniknąć
Proszę mi podpowiedzieć czy szukać rozwiązania z obsługą innego ogniwa, błędów w Yaml czy zapomnieć o tym i ciągnąc przewód do stacji...
Jakiś czas temu wykonałem projekt na drukarce 3D stacji pogodowej,
korzystając z materiałów zawartych na stronie https://github.com/nliaudat/weatherstation?tab=readme-ov-file
Stacje oparłem na module wroom 02, ponieważ korzysta on już z wbudowanego gniazda dla 18650, wtedy był to dla mnie jeden z lepszych wyborów,
po dodaniu dzielnika napięć oraz LM393, QMC5883L, Panelu solarnego 5V 0,6A.
Zabrałem się za dostosowanie kodu Yaml pod swoje potrzeby, wszystko w fazie testów w domu działało w miarę ok.. ogniwo 18650 według obliczeń powinno wytrzymać jakieś 30h plus energia z panelu wiadomo aktualnie bardzo niska ale w letnie dni wystarczająca.
Złożyłem wszystko do kupy przetestowałem działa, choć nie ukrywam musiałem nanieść kilka poprawek do projektu z sieci.. największy niewypał to łączenie tego za pomocą skręcania jak śrubę... kilka kabli zerwałem przy tym i zmieniłem na łącznik typu L
ok do sedna, stacja podziałała jakieś 5h po czym stwierdziła ze ma dość i wyłączyła się przy 3.7v :/ zależy mi aby była ona bezprzewodowa i obsługiwała łączność WiFi.. mogę zmienić na 433Mhz ale sąsiad jest krótkofalowcem i kilka razy upalił mi już moduły i wolałbym tego uniknąć
Proszę mi podpowiedzieć czy szukać rozwiązania z obsługą innego ogniwa, błędów w Yaml czy zapomnieć o tym i ciągnąc przewód do stacji...
Cytat:esphome:
name: stacja-pogodowa
friendly_name: STACJA POGODOWA
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: "STACJA POGODOWA"
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.25 ms 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_yy = 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_yy + 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