diff --git a/README.md b/README.md index 24acff9..0979001 100644 --- a/README.md +++ b/README.md @@ -277,12 +277,11 @@ The thermostat implements a PID control loop for each of the TEC channels, more ## Fan control -Fan control is available for the thermostat revisions with integrated fan system. For this purpose four commands are available: +Fan control commands are available for thermostat revisions with an integrated fan system: 1. `fan` - show fan stats: `fan_pwm`, `abs_max_tec_i`, `auto_mode`, `k_a`, `k_b`, `k_c`. -2. `fan auto` - enable auto speed controller mode, which correlates with fan curve `fcurve`. -3. `fan ` - set the fan power with the value from `1` to `100` and disable auto mode. There is no way to disable the fan. +2. `fan auto` - enable auto speed controller mode, where fan speed is controlled by the fan curve `fcurve`. +3. `fan ` - set the fan power with the value from `1` to `100` and disable auto mode. There is no way to completely disable the fan. Please note that power doesn't correlate with the actual speed linearly. -4. `fcurve ` - set coefficients of the controlling curve `a*x^2 + b*x + c`, where `x` is `abs_max_tec_i/MAX_TEC_I`, -i.e. receives values from 0 to 1 linearly tied to the maximum current. The controlling curve should produce values from 0 to 1, -as below and beyond values would be substituted by 0 and 1 respectively. -5. `fcurve default` - restore fan curve settings to defaults: `a = 1.0, b = 0.0, c = 0.0`. +4. `fcurve ` - set coefficients of the controlling curve `a*x^2 + b*x + c`, where `x` is `abs_max_tec_i/MAX_TEC_I`, a normalized value in range [0,1], +i.e. the (linear) proportion of current output capacity used, on the channel with the largest current flow. The controlling curve is also clamped to [0,1]. +5. `fcurve default` - restore fan curve coefficients to defaults: `a = 1.0, b = 0.0, c = 0.0`. diff --git a/src/channels.rs b/src/channels.rs index a90d886..019c9ad 100644 --- a/src/channels.rs +++ b/src/channels.rs @@ -524,9 +524,9 @@ impl Channels { serde_json_core::to_vec(&summaries) } - pub fn current_abs_max_tec_i(&mut self) -> f64 { - max_by(self.get_tec_i(0).abs().get::(), - self.get_tec_i(1).abs().get::(), + pub fn current_abs_max_tec_i(&mut self) -> ElectricCurrent { + max_by(self.get_tec_i(0).abs(), + self.get_tec_i(1).abs(), |a, b| a.partial_cmp(b).unwrap_or(core::cmp::Ordering::Equal)) } } diff --git a/src/fan_ctrl.rs b/src/fan_ctrl.rs index b95a723..30416f3 100644 --- a/src/fan_ctrl.rs +++ b/src/fan_ctrl.rs @@ -4,7 +4,10 @@ use stm32f4xx_hal::{ pwm::{self, PwmChannels}, pac::TIM8, }; - +use uom::si::{ + f64::ElectricCurrent, + electric_current::ampere, +}; use crate::{ hw_rev::HWSettings, command_handler::JsonBuffer, @@ -50,8 +53,8 @@ impl FanCtrl { fan_ctrl } - pub fn cycle(&mut self, abs_max_tec_i: f32) { - self.abs_max_tec_i = abs_max_tec_i; + pub fn cycle(&mut self, abs_max_tec_i: ElectricCurrent) { + self.abs_max_tec_i = abs_max_tec_i.get::() as f32; if self.fan_auto && self.hw_settings.fan_available { let scaled_current = self.abs_max_tec_i / MAX_TEC_I; // do not limit upper bound, as it will be limited in the set_pwm() diff --git a/src/main.rs b/src/main.rs index 3c01d74..353a161 100644 --- a/src/main.rs +++ b/src/main.rs @@ -185,7 +185,7 @@ fn main() -> ! { server.for_each(|_, session| session.set_report_pending(channel.into())); } - fan_ctrl.cycle(channels.current_abs_max_tec_i() as f32); + fan_ctrl.cycle(channels.current_abs_max_tec_i()); if channels.pid_engaged() { leds.g3.on();