forked from M-Labs/kirdy
Use degree celsius as temperature base unit
- Breaking: Erase settings before flashing - except beta in Steinhart-Hart equation - to keep the temperature value set consistent with the value returned - f32 floating point calculation is inaccurate
This commit is contained in:
parent
af73ac8127
commit
3ba8b99084
@ -8,8 +8,7 @@ use uom::si::{electric_current::{ampere, ElectricCurrent},
|
||||
electric_potential::{volt, ElectricPotential},
|
||||
electrical_conductance::{siemens, ElectricalConductance},
|
||||
electrical_resistance::{ohm, ElectricalResistance},
|
||||
power::{watt, Power},
|
||||
thermodynamic_temperature::{degree_celsius, ThermodynamicTemperature}};
|
||||
power::{watt, Power}};
|
||||
|
||||
use crate::{device::{dfu, sys_timer},
|
||||
laser_diode::{laser_diode::{LdDrive, LdSettingsSummary, StatusReport as LdStatusReport},
|
||||
@ -558,7 +557,7 @@ pub fn execute_cmd(
|
||||
Some(ThermostatCmdEnum::SetTemperatureSetpoint) => match cmd.json.data_f32 {
|
||||
Some(val) => {
|
||||
send_response(buffer, ResponseEnum::Acknowledge, None, socket);
|
||||
thermostat.set_temperature_setpoint(ThermodynamicTemperature::new::<degree_celsius>(val));
|
||||
thermostat.set_temperature_setpoint(val);
|
||||
}
|
||||
None => {
|
||||
send_response(
|
||||
@ -722,7 +721,7 @@ pub fn execute_cmd(
|
||||
Some(ThermostatCmdEnum::SetTempMonUpperLimit) => match cmd.json.data_f32 {
|
||||
Some(val) => {
|
||||
send_response(buffer, ResponseEnum::Acknowledge, None, socket);
|
||||
thermostat.set_temp_mon_upper_limit(ThermodynamicTemperature::new::<degree_celsius>(val));
|
||||
thermostat.set_temp_mon_upper_limit(val);
|
||||
}
|
||||
None => {
|
||||
send_response(
|
||||
@ -736,7 +735,7 @@ pub fn execute_cmd(
|
||||
Some(ThermostatCmdEnum::SetTempMonLowerLimit) => match cmd.json.data_f32 {
|
||||
Some(val) => {
|
||||
send_response(buffer, ResponseEnum::Acknowledge, None, socket);
|
||||
thermostat.set_temp_mon_lower_limit(ThermodynamicTemperature::new::<degree_celsius>(val));
|
||||
thermostat.set_temp_mon_lower_limit(val);
|
||||
}
|
||||
None => {
|
||||
send_response(
|
||||
@ -754,7 +753,7 @@ pub fn execute_cmd(
|
||||
Some(ThermostatCmdEnum::SetShT0) => match cmd.json.data_f32 {
|
||||
Some(val) => {
|
||||
send_response(buffer, ResponseEnum::Acknowledge, None, socket);
|
||||
thermostat.set_sh_t0(ThermodynamicTemperature::new::<degree_celsius>(val));
|
||||
thermostat.set_sh_t0(val);
|
||||
}
|
||||
None => {
|
||||
send_response(
|
||||
|
@ -2,8 +2,7 @@ use miniconf::Tree;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use uom::si::{electric_potential::volt,
|
||||
electrical_resistance::ohm,
|
||||
f32::{ElectricPotential, ElectricalResistance, ThermodynamicTemperature},
|
||||
thermodynamic_temperature::degree_celsius};
|
||||
f32::{ElectricPotential, ElectricalResistance}};
|
||||
|
||||
use crate::thermostat::{ad7172, steinhart_hart as sh};
|
||||
const R_INNER: f32 = 2.0 * 5100.0;
|
||||
@ -48,7 +47,7 @@ pub struct PidState {
|
||||
adc_data: Option<u32>,
|
||||
adc_calibration: ad7172::ChannelCalibration,
|
||||
pid_engaged: bool,
|
||||
set_point: ThermodynamicTemperature,
|
||||
set_point: f32,
|
||||
sh: sh::Parameters,
|
||||
controller: Controller,
|
||||
}
|
||||
@ -59,7 +58,7 @@ impl Default for PidState {
|
||||
adc_data: None,
|
||||
adc_calibration: ad7172::ChannelCalibration::default(),
|
||||
pid_engaged: false,
|
||||
set_point: ThermodynamicTemperature::new::<degree_celsius>(0.0),
|
||||
set_point: 0.0,
|
||||
sh: sh::Parameters::default(),
|
||||
controller: Controller {
|
||||
parameters: Parameters::default(),
|
||||
@ -98,8 +97,8 @@ impl PidState {
|
||||
// + x2 * kd
|
||||
// y0 = clip(y0', ymin, ymax)
|
||||
pub fn update_pid(&mut self) -> Option<f64> {
|
||||
let input = self.get_temperature()?.get::<degree_celsius>();
|
||||
let setpoint = self.set_point.get::<degree_celsius>();
|
||||
let input = self.get_temperature()?;
|
||||
let setpoint = self.set_point;
|
||||
let mut output: f64 = self.controller.y1 - setpoint as f64 * f64::from(self.controller.parameters.ki)
|
||||
+ input as f64
|
||||
* f64::from(
|
||||
@ -133,7 +132,7 @@ impl PidState {
|
||||
Some(r)
|
||||
}
|
||||
|
||||
pub fn get_temperature(&self) -> Option<ThermodynamicTemperature> {
|
||||
pub fn get_temperature(&self) -> Option<f32> {
|
||||
let r = self.get_sens()?;
|
||||
let temperature = self.sh.get_temperature(r);
|
||||
Some(temperature)
|
||||
@ -170,15 +169,15 @@ impl PidState {
|
||||
self.controller.y1 = 0.0;
|
||||
}
|
||||
|
||||
pub fn set_pid_setpoint(&mut self, temperature: ThermodynamicTemperature) {
|
||||
pub fn set_pid_setpoint(&mut self, temperature: f32) {
|
||||
self.set_point = temperature;
|
||||
}
|
||||
|
||||
pub fn get_pid_setpoint(&mut self) -> ThermodynamicTemperature {
|
||||
pub fn get_pid_setpoint(&mut self) -> f32 {
|
||||
self.set_point
|
||||
}
|
||||
|
||||
pub fn set_sh_t0(&mut self, t0: ThermodynamicTemperature) {
|
||||
pub fn set_sh_t0(&mut self, t0: f32) {
|
||||
self.sh.t0 = t0
|
||||
}
|
||||
|
||||
|
@ -2,33 +2,32 @@ use miniconf::Tree;
|
||||
use num_traits::float::Float;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use uom::si::{electrical_resistance::ohm,
|
||||
f32::{ElectricalResistance, ThermodynamicTemperature},
|
||||
ratio::ratio,
|
||||
thermodynamic_temperature::{degree_celsius, kelvin}};
|
||||
f32::ElectricalResistance,
|
||||
ratio::ratio};
|
||||
|
||||
/// Steinhart-Hart equation parameters
|
||||
#[derive(Deserialize, Serialize, Copy, Clone, Debug, Tree)]
|
||||
pub struct Parameters {
|
||||
/// Base temperature
|
||||
pub t0: ThermodynamicTemperature,
|
||||
/// Base temperature (Degree Celsius)
|
||||
pub t0: f32,
|
||||
/// Base resistance
|
||||
pub r0: ElectricalResistance,
|
||||
/// Beta
|
||||
/// Beta (Kelvin)
|
||||
pub b: f32,
|
||||
}
|
||||
|
||||
impl Parameters {
|
||||
/// Perform the voltage to temperature conversion.
|
||||
pub fn get_temperature(&self, r: ElectricalResistance) -> ThermodynamicTemperature {
|
||||
let inv_temp = 1.0 / self.t0.get::<kelvin>() + (r / self.r0).get::<ratio>().ln() / self.b;
|
||||
ThermodynamicTemperature::new::<kelvin>(1.0 / inv_temp)
|
||||
pub fn get_temperature(&self, r: ElectricalResistance) -> f32 {
|
||||
let inv_temp = 1.0 / (self.t0 + 273.15) + (r / self.r0).get::<ratio>().ln() / self.b;
|
||||
1.0 / inv_temp - 273.15
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Parameters {
|
||||
fn default() -> Self {
|
||||
Parameters {
|
||||
t0: ThermodynamicTemperature::new::<degree_celsius>(25.0),
|
||||
t0: 25.0,
|
||||
r0: ElectricalResistance::new::<ohm>(10_000.0),
|
||||
b: 3800.0,
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
use miniconf::Tree;
|
||||
use num_traits::Float;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use uom::si::{f32::ThermodynamicTemperature, thermodynamic_temperature::degree_celsius};
|
||||
#[derive(PartialEq, Deserialize, Serialize, Copy, Clone, Default, Debug)]
|
||||
pub enum TempStatusEnum {
|
||||
#[default]
|
||||
@ -25,9 +24,9 @@ pub struct TempMonSettings {
|
||||
}
|
||||
|
||||
pub struct TempMon {
|
||||
pub upper_limit: ThermodynamicTemperature,
|
||||
pub lower_limit: ThermodynamicTemperature,
|
||||
pub set_point: ThermodynamicTemperature,
|
||||
pub upper_limit: f32,
|
||||
pub lower_limit: f32,
|
||||
pub set_point: f32,
|
||||
pub status: TempStatus,
|
||||
state: State,
|
||||
count: u32,
|
||||
@ -38,9 +37,9 @@ pub struct TempMon {
|
||||
impl Default for TempMon {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
upper_limit: ThermodynamicTemperature::new::<degree_celsius>(45.0),
|
||||
lower_limit: ThermodynamicTemperature::new::<degree_celsius>(0.0),
|
||||
set_point: ThermodynamicTemperature::new::<degree_celsius>(0.0),
|
||||
upper_limit: 45.0,
|
||||
lower_limit: 0.0,
|
||||
set_point: 0.0,
|
||||
status: TempStatus {
|
||||
status: TempStatusEnum::Off,
|
||||
over_temp_alarm: false,
|
||||
@ -68,25 +67,25 @@ impl TempMon {
|
||||
const OVER_TEMP_COUNT_LIMIT: u32 = 25;
|
||||
const TEMP_STABLE_COUNT_LIMIT: u32 = 100;
|
||||
|
||||
pub fn set_upper_limit(&mut self, upper_limit: ThermodynamicTemperature) {
|
||||
pub fn set_upper_limit(&mut self, upper_limit: f32) {
|
||||
self.upper_limit = upper_limit;
|
||||
self.is_limit_changed = true;
|
||||
}
|
||||
|
||||
pub fn get_upper_limit(&mut self) -> ThermodynamicTemperature {
|
||||
pub fn get_upper_limit(&mut self) -> f32 {
|
||||
self.upper_limit
|
||||
}
|
||||
|
||||
pub fn set_lower_limit(&mut self, lower_limit: ThermodynamicTemperature) {
|
||||
pub fn set_lower_limit(&mut self, lower_limit: f32) {
|
||||
self.lower_limit = lower_limit;
|
||||
self.is_limit_changed = true;
|
||||
}
|
||||
|
||||
pub fn get_lower_limit(&mut self) -> ThermodynamicTemperature {
|
||||
pub fn get_lower_limit(&mut self) -> f32 {
|
||||
self.lower_limit
|
||||
}
|
||||
|
||||
pub fn set_setpoint(&mut self, set_point: ThermodynamicTemperature) {
|
||||
pub fn set_setpoint(&mut self, set_point: f32) {
|
||||
if self.set_point != set_point {
|
||||
self.is_set_point_changed = true;
|
||||
self.count = 0;
|
||||
@ -99,7 +98,7 @@ impl TempMon {
|
||||
self.state = State::default();
|
||||
}
|
||||
|
||||
pub fn update_status(&mut self, pid_engaged: bool, pwr_on: bool, temp: ThermodynamicTemperature) {
|
||||
pub fn update_status(&mut self, pid_engaged: bool, pwr_on: bool, temp: f32) {
|
||||
match self.state {
|
||||
State::PwrOff => {
|
||||
self.is_set_point_changed = false;
|
||||
@ -135,10 +134,10 @@ impl TempMon {
|
||||
State::PidStartUp | State::PidStable => {
|
||||
let mut is_over_temp = temp > self.upper_limit || temp < self.lower_limit;
|
||||
if self.state != State::PidStartUp {
|
||||
is_over_temp = is_over_temp || (temp.value - self.set_point.value).abs() > 0.5;
|
||||
is_over_temp = is_over_temp || (temp - self.set_point).abs() > 0.5;
|
||||
}
|
||||
|
||||
let is_within_spec: bool = (temp.value - self.set_point.value).abs() < 0.001;
|
||||
let is_within_spec: bool = (temp - self.set_point).abs() < 0.001;
|
||||
if is_over_temp {
|
||||
if self.count > TempMon::OVER_TEMP_COUNT_LIMIT {
|
||||
self.status.status = TempStatusEnum::OverTemp;
|
||||
@ -191,8 +190,8 @@ impl TempMon {
|
||||
|
||||
pub fn get_settings(&mut self) -> TempMonSettings {
|
||||
TempMonSettings {
|
||||
upper_limit: self.upper_limit.get::<degree_celsius>(),
|
||||
lower_limit: self.lower_limit.get::<degree_celsius>(),
|
||||
upper_limit: self.upper_limit,
|
||||
lower_limit: self.lower_limit,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -6,9 +6,8 @@ use serde::{Deserialize, Serialize};
|
||||
use uom::si::{electric_current::ampere,
|
||||
electric_potential::volt,
|
||||
electrical_resistance::ohm,
|
||||
f32::{ElectricCurrent, ElectricPotential, ElectricalResistance, ThermodynamicTemperature},
|
||||
ratio::ratio,
|
||||
thermodynamic_temperature::degree_celsius};
|
||||
f32::{ElectricCurrent, ElectricPotential, ElectricalResistance},
|
||||
ratio::ratio};
|
||||
|
||||
use crate::{sys_timer,
|
||||
thermostat::{ad5680,
|
||||
@ -185,7 +184,7 @@ impl Thermostat {
|
||||
self.temp_mon
|
||||
.update_status(pid_engaged, self.max1968.is_powered_on(), temp);
|
||||
debug!("state.get_pid_engaged(): {:?}", pid_engaged);
|
||||
debug!("Temperature: {:?} degree", temp.get::<degree_celsius>());
|
||||
debug!("Temperature: {:?} degree", temp);
|
||||
data_rdy = true;
|
||||
});
|
||||
data_rdy
|
||||
@ -200,7 +199,7 @@ impl Thermostat {
|
||||
self.set_i(ElectricCurrent::new::<ampere>(pid_output as f32));
|
||||
debug!(
|
||||
"Temperature Set Point: {:?} degree",
|
||||
self.pid_ctrl_ch0.get_pid_setpoint().get::<degree_celsius>()
|
||||
self.pid_ctrl_ch0.get_pid_setpoint()
|
||||
);
|
||||
}
|
||||
None => {}
|
||||
@ -357,7 +356,7 @@ impl Thermostat {
|
||||
let temperature: Option<f32>;
|
||||
|
||||
match self.pid_ctrl_ch0.get_temperature() {
|
||||
Some(val) => temperature = Some(val.get::<degree_celsius>()),
|
||||
Some(val) => temperature = Some(val),
|
||||
None => {
|
||||
temperature = None;
|
||||
}
|
||||
@ -374,10 +373,10 @@ impl Thermostat {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_temperature(&mut self) -> ThermodynamicTemperature {
|
||||
pub fn get_temperature(&mut self) -> f32 {
|
||||
match self.pid_ctrl_ch0.get_temperature() {
|
||||
Some(val) => val,
|
||||
None => ThermodynamicTemperature::new::<degree_celsius>(NAN),
|
||||
None => NAN,
|
||||
}
|
||||
}
|
||||
|
||||
@ -388,7 +387,7 @@ impl Thermostat {
|
||||
fn get_steinhart_hart(&mut self) -> ThermistorParams {
|
||||
let sh = self.pid_ctrl_ch0.get_sh();
|
||||
ThermistorParams {
|
||||
t0: sh.t0.get::<degree_celsius>(),
|
||||
t0: sh.t0,
|
||||
r0: sh.r0,
|
||||
b: sh.b,
|
||||
}
|
||||
@ -396,7 +395,7 @@ impl Thermostat {
|
||||
|
||||
fn apply_steinhart_hart(&mut self, sh: ThermistorParams) {
|
||||
self.pid_ctrl_ch0.apply_sh(Sh_Params {
|
||||
t0: ThermodynamicTemperature::new::<degree_celsius>(sh.t0),
|
||||
t0: sh.t0,
|
||||
r0: sh.r0,
|
||||
b: sh.b,
|
||||
})
|
||||
@ -439,11 +438,11 @@ impl Thermostat {
|
||||
self.pid_ctrl_ch0.set_sh_r0(r0);
|
||||
}
|
||||
|
||||
pub fn set_sh_t0(&mut self, t0: ThermodynamicTemperature) {
|
||||
pub fn set_sh_t0(&mut self, t0: f32) {
|
||||
self.pid_ctrl_ch0.set_sh_t0(t0);
|
||||
}
|
||||
|
||||
pub fn set_temperature_setpoint(&mut self, t: ThermodynamicTemperature) {
|
||||
pub fn set_temperature_setpoint(&mut self, t: f32) {
|
||||
let t = t
|
||||
.min(self.temp_mon.get_upper_limit())
|
||||
.max(self.temp_mon.get_lower_limit());
|
||||
@ -453,16 +452,16 @@ impl Thermostat {
|
||||
|
||||
pub fn apply_temp_mon_settings(&mut self, settings: TempMonSettings) {
|
||||
self.temp_mon
|
||||
.set_upper_limit(ThermodynamicTemperature::new::<degree_celsius>(settings.upper_limit));
|
||||
.set_upper_limit(settings.upper_limit);
|
||||
self.temp_mon
|
||||
.set_lower_limit(ThermodynamicTemperature::new::<degree_celsius>(settings.lower_limit));
|
||||
.set_lower_limit(settings.lower_limit);
|
||||
}
|
||||
|
||||
pub fn set_temp_mon_upper_limit(&mut self, t: ThermodynamicTemperature) {
|
||||
pub fn set_temp_mon_upper_limit(&mut self, t: f32) {
|
||||
self.temp_mon.set_upper_limit(t);
|
||||
}
|
||||
|
||||
pub fn set_temp_mon_lower_limit(&mut self, t: ThermodynamicTemperature) {
|
||||
pub fn set_temp_mon_lower_limit(&mut self, t: f32) {
|
||||
self.temp_mon.set_lower_limit(t);
|
||||
}
|
||||
|
||||
@ -508,7 +507,7 @@ impl Thermostat {
|
||||
ThermostatSettingsSummary {
|
||||
default_pwr_on: self.tec_settings.default_pwr_on,
|
||||
pid_engaged: self.get_pid_engaged(),
|
||||
temperature_setpoint: self.pid_ctrl_ch0.get_pid_setpoint().get::<degree_celsius>(),
|
||||
temperature_setpoint: self.pid_ctrl_ch0.get_pid_setpoint(),
|
||||
tec_settings: self.get_tec_settings(),
|
||||
pid_params: self.get_pid_settings(),
|
||||
temp_adc_settings: TempAdcFilter {
|
||||
@ -549,9 +548,7 @@ impl Thermostat {
|
||||
|
||||
self.set_pid_engaged(settings.pid_engaged);
|
||||
self.pid_ctrl_ch0.apply_pid_params(settings.pid_params);
|
||||
self.set_temperature_setpoint(ThermodynamicTemperature::new::<degree_celsius>(
|
||||
settings.temperature_setpoint,
|
||||
));
|
||||
self.set_temperature_setpoint(settings.temperature_setpoint);
|
||||
if !settings.pid_engaged {
|
||||
self.set_i(settings.tec_settings.i_set.value);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user