board
Network cabinet fan controller
Public Unreviewedby matt
Two independently controlled 12 V fans, Ethernet and Wi-Fi, and an RGB speed display in a custom printed puck. Routed development preview, not approved for manufacture.
main
matt
Add MTA-156 input revision and document enclosure and cable-fit limits
16485bb
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
esphome:
name: fan-controller
friendly_name: Cabinet fan controller
includes:
- control_policy.h
on_boot:
priority: -100
then:
- output.set_level: {id: pwm1, level: 100%}
- output.set_level: {id: pwm2, level: 100%}
- switch.turn_on: pwm_enabled
on_shutdown:
then:
- switch.turn_off: pwm_enabled
esp32:
board: esp32-c3-devkitm-1
flash_size: 4MB
framework:
type: esp-idf
logger:
hardware_uart: UART0
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
reboot_timeout: 0s
api:
reboot_timeout: 0s
encryption:
key: !secret api_encryption_key
ota:
- platform: esphome
password: !secret ota_password
on_begin:
then:
- switch.turn_off: pwm_enabled
on_error:
then:
- output.set_level: {id: pwm1, level: 100%}
- output.set_level: {id: pwm2, level: 100%}
- switch.turn_on: pwm_enabled
output:
- platform: ledc
id: pwm1
pin: GPIO0
frequency: 25000 Hz
channel: 0
- platform: ledc
id: pwm2
pin: GPIO1
frequency: 25000 Hz
channel: 1
switch:
- platform: gpio
id: pwm_enabled
internal: true
pin:
number: GPIO7
inverted: true
restore_mode: ALWAYS_OFF
- platform: template
name: Full speed override
id: full_override
optimistic: true
restore_mode: RESTORE_DEFAULT_ON
status_led:
pin: GPIO10
one_wire:
- platform: gpio
pin: GPIO6
sensor:
- platform: dallas_temp
id: cabinet_temperature
name: Cabinet temperature
update_interval: 5s
resolution: 12
on_value:
then:
- lambda: |-
if (std::isfinite(x)) {
id(last_temperature_ms) = millis();
id(temperature_seen) = true;
}
- platform: pulse_counter
id: rpm1
name: Fan 1 speed
pin: GPIO4
use_pcnt: false
internal_filter: 20us
count_mode:
rising_edge: INCREMENT
falling_edge: DISABLE
update_interval: 5s
unit_of_measurement: rpm
accuracy_decimals: 0
filters:
- multiply: 0.5
- platform: pulse_counter
id: rpm2
name: Fan 2 speed
pin: GPIO5
use_pcnt: false
internal_filter: 20us
count_mode:
rising_edge: INCREMENT
falling_edge: DISABLE
update_interval: 5s
unit_of_measurement: rpm
accuracy_decimals: 0
filters:
- multiply: 0.5
- platform: template
id: demand
name: Fan demand
unit_of_measurement: '%'
accuracy_decimals: 0
update_interval: never
binary_sensor:
- platform: template
id: cooling_fault
name: Cooling fault
device_class: problem
globals:
- id: last_temperature_ms
type: uint32_t
initial_value: '0'
- id: temperature_seen
type: bool
initial_value: 'false'
interval:
- interval: 1s
then:
- lambda: |-
const auto now = millis();
const auto result = fan_controller::decide(
id(cabinet_temperature).state, now-id(last_temperature_ms), now,
id(rpm1).state, id(rpm2).state, id(temperature_seen), id(full_override).state);
id(pwm1).set_level(result.duty);
id(pwm2).set_level(result.duty);
id(demand).publish_state(result.duty*100.0f);
id(cooling_fault).publish_state(result.fault);