Open patfelst opened 4 days ago
Patrick, Yes, your modification to the yaml is correct, using the one sensor calculated "fan_set_speed" and making the ".set_speed" to each of the fan components. Basically the algo does jus t the proportional and integral parts of the PID. It simply determines the "error", the weighed (PTEMP) difference between the desired temperature and the actual temp and uses the weighed (ITEMP) sum of the error to arrive at fan_speed. A higher PTEMP will cause the fan speed to ramp more aggressively proportional to the difference between target and actual. A setting of 10-20 is typical. ITEMP has less effect but in effect and is the scaling factor of the running sum of the temperature difference. 0.1 to 0.5 are typical ranges.
Why did we not use the D term? We just found it was unnecessary to get good results with the algo.
Why did we not use the PID controller in ESPHome? It was because we could not have a manual control over the fan with their PID component.
The issue with the one-wire/dallas temp component not finding sensors? Yes this is a problem I have been trying the ESPHome developers to fix since their schema change in July to DS18B20 sensors. 2024.7.3 Broke Platform Dallas_temp · Issue #6119 · esphome/issues (github.com)https://github.com/esphome/issues/issues/6119
Do make sure the screw terminals are tight. But what we are seeing is not related to hardware, but compilation of ESPHome. Some yamls using the new one-wire/dallas temp schema will work and other fail with the errors:
13:55:05 | [W] | [component:170] | Component dallas_temp.sensor cleared Warning flag 13:55:05 | [W] | [dallas.temp.sensor:139] | 'AVfan1 Temperature 3' - Scratch pad checksum invalid! 13:55:05 | [W] | [component:157] | Component dallas_temp.sensor set Warning flag: scratch pad checksum invalid 13:55:05 | [W] | [dallas.temp.sensor:139] | 'AVfan1 Temperature 1' - Scratch pad checksum invalid! 13:55:05 | [W] | [component:157] | Component dallas_temp.sensor set Warning flag: scratch pad checksum invalid 13:55:05 | [W] | [dallas.temp.sensor:139] | 'AVfan1 Temperature 2' - Scratch pad checksum invalid! 13:55:05 | [W] | [component:157] | Component dallas_temp.sensor set Warning flag: scratch pad checksum invalid
And in-house we have not been able to determine the root cause of this but it does seems to be isolated to the ESP32 as one of our ESP32-S3 board compilations never exhibited the problem. If you flash the attached factory flashed .bin it will work, then flash your compiled version and it will not. It is highly frustrating and I wish I had a definitive answer for you. All I can say is rearrange your code and see if it works.
Regarding the schematic, the one on Github is the version 2.0 board, the version 2.1, just removed a one-wire connector, J1, and added a AHT20 sensor and a open-collector header on GPIO26 as J1 I have attached that schematic for you.
Lastly, if for example you want to use multiple sensors in different areas of you rack you could use an average or other weighing of multiple sensors to derive the "fan_actual_temp" value to feed to the Lambda function.
Hope this helps and few free to inquire with any issue you might have.
Best regards, Frank
From: Patrick Felstead @.> Sent: Tuesday, September 17, 2024 5:18 PM To: ESP32andmore/ECB @.> Cc: Subscribed @.***> Subject: [ESP32andmore/ECB] A few questions and Dallas temp sensors stopped working (Issue #1)
Hi there. I received my ECB last week (Australia), it's really nicely designed board and well documented. I have mine up and running in a 19" server rack, it's driving a 4x fan tray mounted in the top of the rack.
It's working well and from Home Assistant I can turn fans on/off, control speed %, and see individual speed sensors RPM. For my application I've started modifying the ESPHome yaml (the API version, not MQTT) to essentially drive all 4 fans in parallel using only one Dallas temp sensor (see modified code below). For testing, I've initially connected two Dallas sensors, but will probably only need to use one I think.
I was wondering if you could explain the fan speed control lambda code in pseudo code terms? These are the lines I'm talking about: https://github.com/ESP32andmore/ECB/blob/edcfcdddc9d27accf10c0419ec6700f9bfbd6c28/ESPhome/avfan1.yaml#L437-L459
It looks like you may have implemented your own PID controller, but only using P and I terms. Is there a reason you didn't use the PID built into HA? And how did you come up withe the ptemp and itemp values and should I modify these?
To parallel the fan control with temp sensor 1, this is what I came up with, and it seems to work ok:
- lambda: !lambda |
// Patrick's mod for all 4 fans to act in parallel based on Fan 1 auto setting and temp sensor 1 temperature
if (id(auto_fan1).state) {
float fan_actual_temp = id(temp1).state;
float fan_desired_temp = id(set_target_temp_1).state;
float diff = fan_actual_temp - fan_desired_temp;
id(fan1_sum) =id(fan1_sum) + diff;
float fan_pdiff=diff * $ptemp;
float fan_idiff= id(fan1_sum) * $itemp;
float fan_set_speed = fan_pdiff + fan_idiff;
if (fan_set_speed >100) fan_set_speed =100;
if (fan_set_speed <10) fan_set_speed=1;
if (id(fan1_sum) >100) id(fan1_sum) = 100;
if (id(fan1_sum) < -100) id(fan1_sum) = -100;
if (fan_set_speed <10) {
fan_set_speed=1;
// Turn off fan 1
auto calloff1 = id(fan1_speed).turn_off();
calloff1.set_speed(fan_set_speed);
calloff1.perform();
// Turn off fan 2
auto calloff2 = id(fan2_speed).turn_off();
calloff2.set_speed(fan_set_speed);
calloff2.perform();
// Turn off fan 3
auto calloff3 = id(fan3_speed).turn_off();
calloff3.set_speed(fan_set_speed);
calloff3.perform();
// Turn off fan 4
auto calloff4 = id(fan4_speed).turn_off();
calloff4.set_speed(fan_set_speed);
calloff4.perform();
} else {
// Set fan 1 speed
auto call1 = id(fan1_speed).turn_on();
call1.set_speed(fan_set_speed);
call1.perform();
// Set fan 2 speed
auto call2 = id(fan2_speed).turn_on();
call2.set_speed(fan_set_speed);
call2.perform();
// Set fan 3 speed
auto call3 = id(fan3_speed).turn_on();
call3.set_speed(fan_set_speed);
call3.perform();
// Set fan 4 speed
auto call4 = id(fan4_speed).turn_on();
call4.set_speed(fan_set_speed);
call4.perform();
}
}
This was working ok for a day or so, but now my Dallas temp sensors are not being detected. I don't even see their addresses in the debug log any more. I've not had time to double check the screw terminal connections yet, will do so on the weekend. Is there anything else that could cause this problem?
Assuming I get them working again, would there be any benefit in me doing the 4 fans in parallel using two temp sensors somehow?
Just a small note, I think there might be an error in the schematic for J1 as it shows it conencted to the GPIO27 one-wire bus along with J2 and J3. The docs say J1 is connected to GPIO26. image.png (view on web)https://github.com/user-attachments/assets/cd8c5362-1330-4e27-a48b-84bb0846d3a1
Apologies for the long issue.
— Reply to this email directly, view it on GitHubhttps://github.com/ESP32andmore/ECB/issues/1, or unsubscribehttps://github.com/notifications/unsubscribe-auth/BKCWDYUWKCHLKX4KZ4GIBSLZXCMDFAVCNFSM6AAAAABOMKISUOVHI2DSMVQWIX3LMV43ASLTON2WKOZSGUZTEMJXG42DSNQ. You are receiving this because you are subscribed to this thread.
Thanks for your reponses Frank. Unfortunately as you replied by email, I didn't get the schematic attachment. Maybe you could update the github at some stage?
There is another project like this, and they use a proxy fan so they can use ESPHome PID and also have manual control. Have a look https://github.com/patrickcollins12/esphome-fan-controller/blob/3e850aab559fa558fd9f0713665c326b9b364699/console-fan.yaml#L277
Through trial and error I found that if I remove the web server component, the Dallas sensors work again. It's quite repeatable, i.e. if I add it back in, they stop working again. It must be some kind of ESP32 memory issue, as the docs say "Please note that enabling this component will take up a lot of memory and may decrease stability, especially on ESP8266".
I like the idea of averaging two sensors, with one at the bottom and another at the top of the rack.
Thanks Patrick
Hi, I just bought 2 fan control boards with the intention to use 2 temp sensors, average it and control all 4 fans with just that. I have not been able yet to play with the dallas sensors, probably will check it out during then weekend. @patfelst since the usecase looks similar, would you share your config? working with the same or similar config might help fixing the issue.
@ESP32andmore I would suggest a simpler "starter" config with a more minimal approach.
Sure happy to share my config, its not tidied up yet. Will do in the next comment.
Tend to agree the example yaml is overly complex, for example the majority of the diagnositcs are not needed, nor is the web server IMO. Also the LCD display code should be removed as many people will not use it.
Perhaps a second yaml could be included in the repo with single "auto fan" control and single temp sensor for 4 fans.
My cut down yaml, with two Dallas sensors, but only one being used for 4x fan control.
EDIT: Now a minimal configuration.
# Four automatically controlled PWM fan outputs (J4-J7), each set by four target temperatures, maintained by four Dallas sensor's temperatures. MQTT enabled. Home Assistant API disabled. DHCP enabled.
# Other control configurations available with modification of Dallas platform LAMBDA function. Contact us at esp32andmore@gmail.com for no cost customization.
# From Tindie https://www.tindie.com/products/esp32/esp32-control-board-ver-21/
# Github instructions https://github.com/ESP32andmore/ECB/tree/main?tab=readme-ov-file
substitutions:
devicename: "pwm-fanctrl"
fdevicename: PWM Rack Fan Ctrl
ip: 192.168.20.145 # For static IP adressing
alarm_temp: "30" # Threshold for alarm when implemented
ptemp: "20"
itemp: "0.1"
# Connect your Dallas sensors with logger: DEBUG enabled (factory flash default).
# Open the ESPHome webtool, connect to the ECB board, view the "Logs" window, hit "Reset",
# and search for Dallas scan addresses and replace the below addresses with your unique ones.
dallasaddress1: "0x5f00000dfd4e7228"
dallasaddress2: "0xf200000dfca2d528"
esphome:
name: ${devicename}
friendly_name: ${fdevicename}
comment: Quad PWM fan controller from Tindie "ESP32andmore - ECB"
esp32:
# board: wemos_d1_mini32
board: esp32dev
framework:
type: arduino
preferences:
flash_write_interval: 10min
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
# Enable fallback hotspot (captive portal) in case wifi connection fails
ap:
ssid: "Avfan1 Fallback Hotspot"
password: "QBcMjLhesbQV"
captive_portal:
ota:
- platform: esphome
api:
encryption:
key: "cO14KqV..............................................dsIXGzks="
logger:
level: INFO
globals:
- id: fan_sum
type: float
restore_value: no
initial_value: "0"
number:
- platform: template
id: set_target_temp
name: Target Temp
optimistic: True
min_value: 15
max_value: 50
initial_value: "26"
step: 1
restore_value: True
unit_of_measurement: °C
device_class: "TEMPERATURE"
- platform: template
id: set_alarm_temp
name: Alarm Temp
optimistic: True
min_value: 15
max_value: 80
initial_value: ${alarm_temp}
step: 1
restore_value: true
unit_of_measurement: °C
device_class: "TEMPERATURE"
switch:
- platform: restart
name: Restart
- platform: gpio
name: Relay 0
pin: GPIO18
id: relay_0
restore_mode: restore_default_off
- platform: template
id: auto_fan
name: Fan Auto Mode
restore_mode: RESTORE_DEFAULT_ON
optimistic: true
turn_off_action:
- fan.turn_off: fan1_speed
- fan.turn_off: fan2_speed
- fan.turn_off: fan3_speed
- fan.turn_off: fan4_speed
- platform: gpio
id: oc_port
name: OC Port
restore_mode: ALWAYS_OFF
pin:
number: 26
mode:
output: true
pullup: true
one_wire:
- platform: gpio
pin: GPIO27
output:
- platform: ledc
pin: GPIO13
id: fan1
frequency: 25600Hz
- platform: ledc
pin: GPIO14
id: fan2
frequency: 25600Hz
- platform: ledc
pin: GPIO25
id: fan3
frequency: 25600Hz
- platform: ledc
pin: GPIO32
id: fan4
frequency: 25600Hz
- platform: ledc
pin:
number: GPIO2
ignore_strapping_warning: True
id: alarm_led
light:
- platform: monochromatic
id: alarm_light
output: alarm_led
name: Alarm Light
effects:
- pulse:
name: "Fast Pulse"
transition_length: 0.5s
update_interval: 0.5s
min_brightness: 0%
max_brightness: 100%
i2c:
# - id: bus_a
# sda: GPIO21
# scl: GPIO22
# scan: false
- id: bus_b
sda: GPIO16
scl: GPIO17
scan: False
frequency: 800khz
sensor:
- platform: aht10
i2c_id: bus_b
address: 0x38
variant: AHT20
temperature:
id: temp0
name: Onboard Temperature
filters:
- filter_out: NaN
- offset: -4.0
humidity:
name: Onboard Humidity
update_interval: 5s
- platform: pulse_counter
pin: GPIO33
unit_of_measurement: "rpm"
name: Fan speed 1
update_interval: 5s
filters:
- multiply: 0.5
- platform: pulse_counter
pin: GPIO34
unit_of_measurement: "rpm"
name: Fan speed 2
update_interval: 5s
filters:
- multiply: 0.5
- platform: pulse_counter
pin: GPIO35
unit_of_measurement: "rpm"
name: Fan speed 3
update_interval: 5s
filters:
- multiply: 0.5
- platform: pulse_counter
pin: GPIO39
unit_of_measurement: "rpm"
name: Fan speed 4
update_interval: 5s
filters:
- multiply: 0.5
- platform: wifi_signal
name: WiFi
update_interval: 30s
- platform: uptime
name: Uptime
update_interval: 30s
- platform: dallas_temp
address: ${dallasaddress1}
update_interval: 2s
id: temp1
filters:
- filter_out: NaN
- offset: 0.0
unit_of_measurement: "°C"
name: Temperature 1
on_value:
- if:
condition:
for:
time: 10s
condition:
lambda: "return id(temp1).state >= id(set_alarm_temp).state;"
then:
- light.turn_on:
id: alarm_light
effect: "Fast Pulse"
- lambda: !lambda |-
id(alarm_sen).publish_state(true);
else:
- light.turn_off:
id: alarm_light
- lambda: !lambda |-
id(alarm_sen).publish_state(false);
# example using GLOBAL to maintain persistant SUM for each fan
- lambda: !lambda |
// Patrick's mod for all 4 fans to act in parallel based on Fan 1 auto setting and temp sensor 1 temperature
if (id(auto_fan).state) {
float fan_actual_temp = id(temp1).state;
float fan_desired_temp = id(set_target_temp).state;
float diff = fan_actual_temp - fan_desired_temp;
id(fan_sum) =id(fan_sum) + diff;
float fan_pdiff=diff * $ptemp;
float fan_idiff= id(fan_sum) * $itemp;
float fan_set_speed = fan_pdiff + fan_idiff;
if (fan_set_speed >100) fan_set_speed =100;
if (fan_set_speed <10) fan_set_speed=1;
if (id(fan_sum) >100) id(fan_sum) = 100;
if (id(fan_sum) < -100) id(fan_sum) = -100;
if (fan_set_speed <10) {
fan_set_speed=1;
// Turn off fan 1
auto calloff1 = id(fan1_speed).turn_off();
calloff1.set_speed(fan_set_speed);
calloff1.perform();
// Turn off fan 2
auto calloff2 = id(fan2_speed).turn_off();
calloff2.set_speed(fan_set_speed);
calloff2.perform();
// Turn off fan 3
auto calloff3 = id(fan3_speed).turn_off();
calloff3.set_speed(fan_set_speed);
calloff3.perform();
// Turn off fan 4
auto calloff4 = id(fan4_speed).turn_off();
calloff4.set_speed(fan_set_speed);
calloff4.perform();
} else {
// Set fan 1 speed
auto call1 = id(fan1_speed).turn_on();
call1.set_speed(fan_set_speed);
call1.perform();
// Set fan 2 speed
auto call2 = id(fan2_speed).turn_on();
call2.set_speed(fan_set_speed);
call2.perform();
// Set fan 3 speed
auto call3 = id(fan3_speed).turn_on();
call3.set_speed(fan_set_speed);
call3.perform();
// Set fan 4 speed
auto call4 = id(fan4_speed).turn_on();
call4.set_speed(fan_set_speed);
call4.perform();
}
}
- platform: dallas_temp
address: ${dallasaddress2}
update_interval: 2s
id: temp2
filters:
- filter_out: NaN
- offset: 0.0 #Calibration
unit_of_measurement: "°C"
name: Temperature 2
fan:
- platform: speed
output: fan1
id: fan1_speed
name: Fan1 Speed
restore_mode: RESTORE_DEFAULT_OFF
- platform: speed
output: fan2
id: fan2_speed
name: Fan2 Speed
restore_mode: RESTORE_DEFAULT_OFF
- platform: speed
output: fan3
id: fan3_speed
name: Fan3 Speed
restore_mode: RESTORE_DEFAULT_OFF
- platform: speed
output: fan4
id: fan4_speed
name: Fan4 Speed
restore_mode: RESTORE_DEFAULT_OFF
text_sensor:
- platform: version
name: Version
binary_sensor:
- platform: template
id: alarm_sen
name: Alarm
icon: mdi:fire
Patrick, Thanks for the share. Actually there is a one sensor to many fans YAML auto-control on Github (avfan1-to-m.yaml) ESPhome. And yes the diagnostics is too rich but as it is an example those can easily be stripped out. I have a run-time selectable version of sensors to fans but it has not been fully tested. All your ideas and suggestion are valuable as time permits they will be implemented.
Best Regards, Frank
From: Patrick Felstead @.> Sent: Thursday, September 19, 2024 5:50 AM To: ESP32andmore/ECB @.> Cc: ESP32andmore @.>; Mention @.> Subject: Re: [ESP32andmore/ECB] A few questions and Dallas temp sensors stopped working (Issue #1)
Sure happy to share my config, its not tidied up yet. Will do in the next comment.
Tend to agree the example yaml is overly complex, for example the majority of the diagnositcs are not needed image.png (view on web)https://github.com/user-attachments/assets/41702acd-3a39-4c23-be2f-87ee1a7b9f6f
Perhaps a second yaml could be included in the repo with single "auto fan" control and single temp sensor for 4 fans.
— Reply to this email directly, view it on GitHubhttps://github.com/ESP32andmore/ECB/issues/1#issuecomment-2360529661, or unsubscribehttps://github.com/notifications/unsubscribe-auth/BKCWDYV2JUFOWNB26PXYM3LZXKM6RAVCNFSM6AAAAABOMKISUOVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDGNRQGUZDSNRWGE. You are receiving this because you were mentioned.
Hi there. I received my ECB last week (Australia), it's really nicely designed board and well documented. I have mine up and running in a 19" server rack, it's driving a 4x fan tray mounted in the top of the rack.
It's working well and from Home Assistant I can turn fans on/off, control speed %, and see individual speed sensors RPM. For my application I've started modifying the ESPHome yaml (the API version, not MQTT) to essentially drive all 4 fans in parallel using only one Dallas temp sensor (see modified code below). For testing, I've initially connected two Dallas sensors, but will probably only need to use one I think.
I was wondering if you could explain the fan speed control lambda code in pseudo code terms? These are the lines I'm talking about: https://github.com/ESP32andmore/ECB/blob/edcfcdddc9d27accf10c0419ec6700f9bfbd6c28/ESPhome/avfan1.yaml#L437-L459
It looks like you may have implemented your own PID controller, but only using P and I terms. Is there a reason you didn't use the PID built into HA? And how did you come up withe the
ptemp
anditemp
values and should I modify these?To parallel the fan control with temp sensor 1, this is what I came up with, and it seems to work ok:
This was working ok for a day or so, but now my Dallas temp sensors are not being detected. I don't even see their addresses in the debug log any more. I've not had time to double check the screw terminal connections yet, will do so on the weekend. Is there anything else that could cause this problem?
Assuming I get them working again, would there be any benefit in me doing the 4 fans in parallel using two temp sensors somehow?
Just a small note, I think there might be an error in the schematic for J1 as it shows it conencted to the GPIO27 one-wire bus along with J2 and J3. The docs say J1 is connected to GPIO26.
Apologies for the long issue.