1
0
forked from M-Labs/kirdy

cmd: Add cmd to get all device settings

This commit is contained in:
linuswck 2024-02-23 11:38:26 +08:00
parent c4135f6ac3
commit c09ccc29cd
8 changed files with 159 additions and 122 deletions

View File

@ -2,6 +2,7 @@ use miniconf::Tree;
use stm32f4xx_hal::timer::CounterUs; use stm32f4xx_hal::timer::CounterUs;
use stm32f4xx_hal::pac::{ADC2, TIM2}; use stm32f4xx_hal::pac::{ADC2, TIM2};
use uom::si::electric_current::ampere; use uom::si::electric_current::ampere;
use uom::si::power::milliwatt;
use crate::laser_diode::ld_ctrl::{LdCtrl, Impedance}; use crate::laser_diode::ld_ctrl::{LdCtrl, Impedance};
use crate::laser_diode::ld_pwr_exc_protector::{LdPwrExcProtector, self}; use crate::laser_diode::ld_pwr_exc_protector::{LdPwrExcProtector, self};
use crate::laser_diode::pd_responsitivity; use crate::laser_diode::pd_responsitivity;
@ -47,12 +48,12 @@ impl Settings{
}; };
} }
#[derive(Clone, Debug, Tree)] #[derive(Deserialize, Serialize, Clone, Copy, Debug, Tree)]
pub struct Settings { struct Settings {
ld_drive_current: ElectricCurrent, ld_drive_current: ElectricCurrent,
ld_drive_current_limit: ElectricCurrent, ld_drive_current_limit: ElectricCurrent,
#[tree]
pd_responsitivity: pd_responsitivity::Parameters, pd_responsitivity: pd_responsitivity::Parameters,
ld_pwr_limit: Power,
} }
impl Default for Settings { impl Default for Settings {
@ -61,6 +62,7 @@ impl Default for Settings {
ld_drive_current: ElectricCurrent::new::<milliampere>(0.0), ld_drive_current: ElectricCurrent::new::<milliampere>(0.0),
ld_drive_current_limit: ElectricCurrent::new::<milliampere>(0.0), ld_drive_current_limit: ElectricCurrent::new::<milliampere>(0.0),
pd_responsitivity: pd_responsitivity::Parameters::default(), pd_responsitivity: pd_responsitivity::Parameters::default(),
ld_pwr_limit: Power::new::<milliwatt>(0.0),
} }
} }
} }
@ -199,4 +201,28 @@ impl LdDrive{
term_status: self.get_term_status(), term_status: self.get_term_status(),
} }
} }
pub fn get_settings_summary(&mut self) -> LdSettingsSummary {
let settings = self.settings;
LdSettingsSummary {
ld_drive_current: LdSettingsSummaryField { value: settings.ld_drive_current, max: Settings::LD_CURRENT_MAX},
ld_drive_current_limit: LdSettingsSummaryField { value: settings.ld_drive_current_limit, max: Settings::LD_CURRENT_MAX},
pd_responsitivity: settings.pd_responsitivity,
ld_pwr_limit: settings.ld_pwr_limit,
}
}
}
#[derive(Deserialize, Serialize, Copy, Clone, Debug, Tree)]
pub struct LdSettingsSummary {
ld_drive_current: LdSettingsSummaryField<ElectricCurrent>,
ld_drive_current_limit: LdSettingsSummaryField<ElectricCurrent>,
pd_responsitivity: pd_responsitivity::Parameters,
ld_pwr_limit: Power,
}
#[derive(Deserialize, Serialize, Copy, Clone, Debug, Tree)]
pub struct LdSettingsSummaryField<T> {
value: T,
max: T,
} }

View File

@ -1,4 +1,5 @@
use core::{f64::NAN, marker::PhantomData}; use core::{f64::NAN, marker::PhantomData};
use serde::{Deserialize, Serialize};
use uom::si::{ use uom::si::{
f64::{ f64::{
ElectricCurrent, ElectricCurrent,
@ -12,7 +13,7 @@ use miniconf::Tree;
// Ampere / Watt // Ampere / Watt
pub type ResponsitivityUnit = Quantity<ISQ<N2, N1, P3, P1, Z0, Z0, Z0>, SI<f64>, f64>; pub type ResponsitivityUnit = Quantity<ISQ<N2, N1, P3, P1, Z0, Z0, Z0>, SI<f64>, f64>;
#[derive(Clone, Debug, PartialEq, Tree)] #[derive(Deserialize, Serialize, Clone, Copy, Debug, PartialEq, Tree)]
pub struct Parameters { pub struct Parameters {
responsitivity: ResponsitivityUnit, responsitivity: ResponsitivityUnit,
i_dark: ElectricCurrent, i_dark: ElectricCurrent,

View File

@ -13,10 +13,7 @@ use device::{boot::bootup, log_setup, sys_timer};
use uom::fmt::DisplayStyle::Abbreviation; use uom::fmt::DisplayStyle::Abbreviation;
use uom::si::electric_potential::volt; use uom::si::electric_potential::volt;
use uom::si::electric_current::{ampere, milliampere}; use uom::si::electric_current::{ampere, milliampere};
use uom::si::thermodynamic_temperature::degree_celsius; use uom::si::f64::{ElectricPotential, ElectricCurrent};
use uom::si::power::milliwatt;
use uom::si::f64::{ElectricPotential, ElectricCurrent, Power, ThermodynamicTemperature};
use serde::{Serialize, Deserialize};
use stm32f4xx_hal::pac::SCB; use stm32f4xx_hal::pac::SCB;
// If RTT is used, print panic info through RTT // If RTT is used, print panic info through RTT
@ -80,7 +77,6 @@ fn main() -> ! {
let volt_fmt = ElectricPotential::format_args(volt, Abbreviation); let volt_fmt = ElectricPotential::format_args(volt, Abbreviation);
let amp_fmt = ElectricCurrent::format_args(ampere, Abbreviation); let amp_fmt = ElectricCurrent::format_args(ampere, Abbreviation);
let milli_amp_fmt = ElectricCurrent::format_args(milliampere, Abbreviation); let milli_amp_fmt = ElectricCurrent::format_args(milliampere, Abbreviation);
let milli_watt_fmt = Power::format_args(milliwatt, Abbreviation);
let mut should_reset = false; let mut should_reset = false;
@ -118,8 +114,7 @@ fn main() -> ! {
if net::net::eth_is_socket_active() { if net::net::eth_is_socket_active() {
if device_settings.report_readings { if device_settings.report_readings {
unsafe { unsafe {
net::cmd_handler::send_ld_readings(&mut ETH_DATA_BUFFER, &mut laser); net::cmd_handler::send_status_report(&mut ETH_DATA_BUFFER, &mut laser, &mut thermostat);
net::cmd_handler::send_tec_readings(&mut ETH_DATA_BUFFER, &mut thermostat);
} }
} }
} }

View File

@ -9,15 +9,15 @@ use uom::si::{
thermodynamic_temperature::{degree_celsius, ThermodynamicTemperature} thermodynamic_temperature::{degree_celsius, ThermodynamicTemperature}
}; };
use crate::{laser_diode::{laser_diode::{ use crate::{laser_diode::{laser_diode::{
LdDrive, StatusReport as LdStatusReport}, LdDrive, StatusReport as LdStatusReport, LdSettingsSummary},
pd_responsitivity::ResponsitivityUnit pd_responsitivity::ResponsitivityUnit
}, },
net::net, net::net,
thermostat::thermostat::StatusReport as TecStatusReport thermostat::thermostat::StatusReport as TecStatusReport
}; };
use crate::thermostat::thermostat::Thermostat; use crate::thermostat::thermostat::{Thermostat, ThermostatSettingsSummary};
use crate::thermostat::pid_state::PidSettings::*; use crate::thermostat::pid_state::PidSettings::*;
use crate::device::dfu; use crate::device::{dfu, sys_timer};
use log::info; use log::info;
use crate::DeviceSettings; use crate::DeviceSettings;
@ -25,7 +25,9 @@ use crate::DeviceSettings;
enum DeviceCmd { enum DeviceCmd {
#[default] #[default]
Reserved, Reserved,
ReportStatus, SetActiveReportMode,
GetStatusReport,
GetSettingsSummary,
Dfu, Dfu,
} }
@ -43,13 +45,8 @@ enum LdCmdEnum {
// PD Mon Related // PD Mon Related
SetPdResponsitivity, SetPdResponsitivity,
SetPdDarkCurrent, SetPdDarkCurrent,
SetPdILimit,
SetLdPwrLimit, SetLdPwrLimit,
ClearAlarmStatus, ClearAlarm,
// Report Related
GetModInTermStatus,
GetLdStatus,
GetAlramStatus,
} }
#[derive(Deserialize, Serialize, Copy, Clone, Default, Debug)] #[derive(Deserialize, Serialize, Copy, Clone, Default, Debug)]
@ -81,10 +78,6 @@ enum ThermostatCmdEnum {
SetShT0, SetShT0,
SetShR0, SetShR0,
SetShBeta, SetShBeta,
// Report Related
GetTecStatus,
GetPidStatus,
GetShParams,
} }
#[derive(Deserialize, Serialize, Copy, Clone, Debug, Default, Tree)] #[derive(Deserialize, Serialize, Copy, Clone, Debug, Default, Tree)]
@ -102,26 +95,47 @@ pub struct Cmd {
} }
#[derive(Deserialize, Serialize, Copy, Clone, Debug, Tree)] #[derive(Deserialize, Serialize, Copy, Clone, Debug, Tree)]
pub struct TecStatusReportStruct { pub struct StatusReport {
json: TecStatusReport ts: u32,
laser: LdStatusReport,
tec: TecStatusReport,
} }
#[derive(Deserialize, Serialize, Copy, Clone, Debug, Tree)] #[derive(Deserialize, Serialize, Copy, Clone, Debug, Tree)]
pub struct LaserStatusReportStruct { pub struct StatusReportObj {
json: LdStatusReport json: StatusReport
} }
pub fn send_ld_readings(buffer: &mut [u8], laser: &mut LdDrive){ #[derive(Deserialize, Serialize, Copy, Clone, Debug, Tree)]
let status_report = LaserStatusReportStruct { pub struct SettingsSummary {
json: laser.get_status_report() laser: LdSettingsSummary,
thermostat: ThermostatSettingsSummary,
}
#[derive(Deserialize, Serialize, Copy, Clone, Debug, Tree)]
pub struct SettingsSummaryObj {
json: SettingsSummary
}
pub fn send_settings_summary(buffer: &mut [u8], laser: &mut LdDrive, tec: &mut Thermostat){
let settings_summary = SettingsSummaryObj {
json: SettingsSummary {
laser: laser.get_settings_summary(),
thermostat: tec.get_settings_summary(),
}
}; };
let num_bytes = status_report.get_json("/json", buffer).unwrap(); let num_bytes = settings_summary.get_json("/json", buffer).unwrap();
net::eth_send(buffer, num_bytes); net::eth_send(buffer, num_bytes);
} }
pub fn send_tec_readings(buffer: &mut [u8], tec: &mut Thermostat){
let status_report = TecStatusReportStruct { pub fn send_status_report(buffer: &mut [u8], laser: &mut LdDrive, tec: &mut Thermostat){
json: tec.get_status_report() let status_report = StatusReportObj {
json: StatusReport {
ts: sys_timer::now(),
laser: laser.get_status_report(),
tec: tec.get_status_report(),
}
}; };
let num_bytes = status_report.get_json("/json", buffer).unwrap(); let num_bytes = status_report.get_json("/json", buffer).unwrap();
net::eth_send(buffer, num_bytes); net::eth_send(buffer, num_bytes);
@ -146,7 +160,7 @@ pub fn execute_cmd(buffer: &mut [u8], buffer_size: usize, mut laser: LdDrive, mu
} }
should_reset = true; should_reset = true;
} }
Some(DeviceCmd::ReportStatus) => { Some(DeviceCmd::SetActiveReportMode) => {
match cmd.json.data_bool{ match cmd.json.data_bool{
Some(val) => { Some(val) => {
device_settings.report_readings = val; device_settings.report_readings = val;
@ -156,6 +170,12 @@ pub fn execute_cmd(buffer: &mut [u8], buffer_size: usize, mut laser: LdDrive, mu
} }
} }
} }
Some(DeviceCmd::GetStatusReport) => {
send_status_report(buffer, &mut laser, &mut tec);
}
Some(DeviceCmd::GetSettingsSummary) => {
send_settings_summary(buffer, &mut laser, &mut tec);
}
None => { /* Do Nothing */} None => { /* Do Nothing */}
_ => { _ => {
info!("Unimplemented Command") info!("Unimplemented Command")
@ -215,16 +235,6 @@ pub fn execute_cmd(buffer: &mut [u8], buffer_size: usize, mut laser: LdDrive, mu
} }
} }
} }
Some(LdCmdEnum::SetPdILimit) => {
match cmd.json.data_f64 {
Some(val) => {
laser.set_pd_i_limit(ElectricCurrent::new::<milliampere>(val))
}
None => {
info!("Wrong Data type is received")
}
}
}
Some(LdCmdEnum::SetLdPwrLimit) => { Some(LdCmdEnum::SetLdPwrLimit) => {
match cmd.json.data_f64 { match cmd.json.data_f64 {
Some(val) => { Some(val) => {
@ -235,18 +245,9 @@ pub fn execute_cmd(buffer: &mut [u8], buffer_size: usize, mut laser: LdDrive, mu
} }
} }
} }
Some(LdCmdEnum::ClearAlarmStatus) => { Some(LdCmdEnum::ClearAlarm) => {
laser.pd_mon_clear_alarm() laser.pd_mon_clear_alarm()
} }
Some(LdCmdEnum::GetModInTermStatus) => {
info!("Not supported Yet")
}
Some(LdCmdEnum::GetLdStatus) => {
send_ld_readings(buffer, &mut laser);
}
Some(LdCmdEnum::GetAlramStatus) => {
info!("Not supported Yet")
}
None => { /* Do Nothing*/ } None => { /* Do Nothing*/ }
_ => { _ => {
info!("Unimplemented Command") info!("Unimplemented Command")
@ -422,15 +423,6 @@ pub fn execute_cmd(buffer: &mut [u8], buffer_size: usize, mut laser: LdDrive, mu
} }
} }
} }
Some(ThermostatCmdEnum::GetTecStatus) => {
send_tec_readings(buffer, &mut tec);
}
Some(ThermostatCmdEnum::GetPidStatus) => {
info!("Not supported Yet")
}
Some(ThermostatCmdEnum::GetShParams) => {
info!("Not supported Yet")
}
None => { /* Do Nothing*/ } None => { /* Do Nothing*/ }
_ => { _ => {
info!("Unimplemented Command") info!("Unimplemented Command")

View File

@ -1,4 +1,5 @@
use miniconf::Tree; use miniconf::Tree;
use serde::{Deserialize, Serialize};
use uom::si::{ use uom::si::{
electric_potential::volt, electrical_resistance::ohm, f64::{ electric_potential::volt, electrical_resistance::ohm, f64::{
ElectricPotential, ElectricalResistance, ThermodynamicTemperature ElectricPotential, ElectricalResistance, ThermodynamicTemperature
@ -11,7 +12,7 @@ use crate::thermostat::{
const R_INNER: f64 = 2.0 * 5100.0; const R_INNER: f64 = 2.0 * 5100.0;
const VREF_SENS: f64 = 3.3 / 2.0; const VREF_SENS: f64 = 3.3 / 2.0;
#[derive(Clone, Copy, Debug, PartialEq, Tree)] #[derive(Deserialize, Serialize, Clone, Copy, Debug, PartialEq, Tree)]
pub struct Parameters { pub struct Parameters {
/// Gain coefficient for proportional term /// Gain coefficient for proportional term
pub kp: f32, pub kp: f32,
@ -205,6 +206,6 @@ impl PidState {
} }
pub fn get_sh(&mut self) -> sh::Parameters { pub fn get_sh(&mut self) -> sh::Parameters {
unimplemented!() self.sh
} }
} }

View File

@ -1,4 +1,5 @@
use num_traits::float::Float; use num_traits::float::Float;
use serde::{Deserialize, Serialize};
use uom::si::{ use uom::si::{
f64::{ f64::{
ElectricalResistance, ElectricalResistance,
@ -11,7 +12,7 @@ use uom::si::{
use miniconf::Tree; use miniconf::Tree;
/// Steinhart-Hart equation parameters /// Steinhart-Hart equation parameters
#[derive(Clone, Debug, PartialEq, Tree)] #[derive(Deserialize, Serialize, Copy, Clone, Debug, Tree)]
pub struct Parameters { pub struct Parameters {
/// Base temperature /// Base temperature
pub t0: ThermodynamicTemperature, pub t0: ThermodynamicTemperature,

View File

@ -1,8 +1,7 @@
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use miniconf::Tree; use miniconf::Tree;
use uom::si::{ use uom::si::{
thermodynamic_temperature::degree_celsius, f64::ThermodynamicTemperature, thermodynamic_temperature::degree_celsius
f64::ThermodynamicTemperature
}; };
use num_traits::Float; use num_traits::Float;
#[derive(PartialEq, Deserialize, Serialize, Copy, Clone, Default, Debug)] #[derive(PartialEq, Deserialize, Serialize, Copy, Clone, Default, Debug)]
@ -20,9 +19,10 @@ pub struct TempStatus {
pub over_temp_alarm: bool, pub over_temp_alarm: bool,
} }
#[derive(Deserialize, Serialize, Copy, Clone, Debug, Tree)]
pub struct TempMonSettings { pub struct TempMonSettings {
pub upper_limit: ThermodynamicTemperature, pub upper_limit: f64,
pub lower_limit: ThermodynamicTemperature, pub lower_limit: f64,
} }
pub struct TempMon { pub struct TempMon {
@ -70,10 +70,18 @@ impl TempMon {
self.upper_limit = upper_limit; self.upper_limit = upper_limit;
} }
pub fn get_upper_limit(&mut self) -> ThermodynamicTemperature {
self.upper_limit
}
pub fn set_lower_limit(&mut self, lower_limit: ThermodynamicTemperature) { pub fn set_lower_limit(&mut self, lower_limit: ThermodynamicTemperature) {
self.lower_limit = lower_limit; self.lower_limit = lower_limit;
} }
pub fn get_lower_limit(&mut self) -> ThermodynamicTemperature {
self.lower_limit
}
pub fn set_setpoint(&mut self, set_point: ThermodynamicTemperature) { pub fn set_setpoint(&mut self, set_point: ThermodynamicTemperature) {
if self.set_point != set_point { if self.set_point != set_point {
self.is_set_point_changed = true; self.is_set_point_changed = true;
@ -148,8 +156,8 @@ impl TempMon {
pub fn get_settings(&mut self) -> TempMonSettings { pub fn get_settings(&mut self) -> TempMonSettings {
TempMonSettings { TempMonSettings {
upper_limit: self.upper_limit, upper_limit: self.upper_limit.get::<degree_celsius>(),
lower_limit: self.lower_limit, lower_limit: self.lower_limit.get::<degree_celsius>(),
} }
} }
} }

View File

@ -4,8 +4,7 @@ use crate::sys_timer;
use crate::thermostat::ad5680; use crate::thermostat::ad5680;
use crate::thermostat::max1968::{MAX1968, AdcReadTarget, PwmPinsEnum}; use crate::thermostat::max1968::{MAX1968, AdcReadTarget, PwmPinsEnum};
use crate::thermostat::ad7172; use crate::thermostat::ad7172;
use crate::thermostat::pid_state::{PidState, PidSettings}; use crate::thermostat::pid_state::{PidState, PidSettings, Parameters as PidParams};
use crate::thermostat::steinhart_hart;
use crate::thermostat::temp_mon::{TempMon, TempStatus, TempMonSettings}; use crate::thermostat::temp_mon::{TempMon, TempStatus, TempMonSettings};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use log::debug; use log::debug;
@ -27,7 +26,7 @@ pub const R_SENSE: ElectricalResistance = ElectricalResistance {
value: 0.05, value: 0.05,
}; };
#[derive(Clone, Debug, Tree)] #[derive(Deserialize, Serialize, Clone, Copy, Debug, Tree)]
pub struct TecSettings { pub struct TecSettings {
pub center_pt: ElectricPotential, pub center_pt: ElectricPotential,
pub max_v_set: ElectricPotential, pub max_v_set: ElectricPotential,
@ -102,17 +101,25 @@ impl Default for TecSettings {
pub struct Thermostat { pub struct Thermostat {
max1968: MAX1968, max1968: MAX1968,
ad7172: ad7172::AdcPhy, ad7172: ad7172::AdcPhy,
pub tec_setting: TecSettings, pub tec_settings: TecSettings,
pid_ctrl_ch0: PidState, pid_ctrl_ch0: PidState,
temp_mon: TempMon, temp_mon: TempMon,
} }
#[derive(Deserialize, Serialize, Copy, Clone, Debug, Tree)]
pub struct ThermostatSettingsSummary {
tec_settings: TecSettingSummary,
pid_params: PidParams,
temp_mon_settings: TempMonSettings,
thermistor_params: ThermistorParams,
}
impl Thermostat{ impl Thermostat{
pub fn new (max1968: MAX1968, ad7172: ad7172::AdcPhy) -> Self { pub fn new (max1968: MAX1968, ad7172: ad7172::AdcPhy) -> Self {
Thermostat{ Thermostat{
max1968: max1968, max1968: max1968,
ad7172: ad7172, ad7172: ad7172,
tec_setting: TecSettings::default(), tec_settings: TecSettings::default(),
pid_ctrl_ch0: PidState::default(), pid_ctrl_ch0: PidState::default(),
temp_mon: TempMon::default(), temp_mon: TempMon::default(),
} }
@ -126,13 +133,13 @@ impl Thermostat{
fn tec_setup(&mut self) { fn tec_setup(&mut self) {
self.power_down(); self.power_down();
self.tec_setting = TecSettings::default(); self.tec_settings = TecSettings::default();
self.set_i(self.tec_setting.i_set); self.set_i(self.tec_settings.i_set);
self.set_max_v(self.tec_setting.max_v_set); self.set_max_v(self.tec_settings.max_v_set);
self.set_max_i_pos(self.tec_setting.max_i_pos_set); self.set_max_i_pos(self.tec_settings.max_i_pos_set);
self.set_max_i_neg(self.tec_setting.max_i_neg_set); self.set_max_i_neg(self.tec_settings.max_i_neg_set);
} }
fn t_adc_setup(&mut self)->ad7172::ChannelCalibration{ fn t_adc_setup(&mut self)->ad7172::ChannelCalibration{
@ -184,35 +191,35 @@ impl Thermostat{
} }
fn set_center_pt(&mut self, value: ElectricPotential){ fn set_center_pt(&mut self, value: ElectricPotential){
self.tec_setting.center_pt = value; self.tec_settings.center_pt = value;
} }
pub fn set_i(&mut self, i_tec: ElectricCurrent) -> ElectricCurrent { pub fn set_i(&mut self, i_tec: ElectricCurrent) -> ElectricCurrent {
let voltage = i_tec * 10.0 * R_SENSE + self.tec_setting.center_pt; let voltage = i_tec * 10.0 * R_SENSE + self.tec_settings.center_pt;
let voltage = self.max1968.set_dac(voltage, TecSettings::DAC_OUT_V_MAX); let voltage = self.max1968.set_dac(voltage, TecSettings::DAC_OUT_V_MAX);
self.tec_setting.i_set = (voltage - self.tec_setting.center_pt) / (10.0 * R_SENSE); self.tec_settings.i_set = (voltage - self.tec_settings.center_pt) / (10.0 * R_SENSE);
self.tec_setting.i_set self.tec_settings.i_set
} }
pub fn set_max_v(&mut self, max_v: ElectricPotential) -> ElectricPotential { pub fn set_max_v(&mut self, max_v: ElectricPotential) -> ElectricPotential {
let duty = (max_v / TecSettings::MAX_V_DUTY_TO_CURRENT_RATE).get::<ratio>(); let duty = (max_v / TecSettings::MAX_V_DUTY_TO_CURRENT_RATE).get::<ratio>();
let duty = self.max1968.set_pwm(PwmPinsEnum::MaxV, duty, TecSettings::MAX_V_DUTY_MAX); let duty = self.max1968.set_pwm(PwmPinsEnum::MaxV, duty, TecSettings::MAX_V_DUTY_MAX);
self.tec_setting.max_v_set = duty * TecSettings::MAX_V_DUTY_TO_CURRENT_RATE; self.tec_settings.max_v_set = duty * TecSettings::MAX_V_DUTY_TO_CURRENT_RATE;
self.tec_setting.max_v_set self.tec_settings.max_v_set
} }
pub fn set_max_i_pos(&mut self, max_i_pos: ElectricCurrent) -> ElectricCurrent { pub fn set_max_i_pos(&mut self, max_i_pos: ElectricCurrent) -> ElectricCurrent {
let duty = (max_i_pos / TecSettings::MAX_I_POS_NEG_DUTY_TO_CURRENT_RATE).get::<ratio>(); let duty = (max_i_pos / TecSettings::MAX_I_POS_NEG_DUTY_TO_CURRENT_RATE).get::<ratio>();
let duty = self.max1968.set_pwm(PwmPinsEnum::MaxPosI, duty, TecSettings::MAX_I_POS_DUTY_MAX); let duty = self.max1968.set_pwm(PwmPinsEnum::MaxPosI, duty, TecSettings::MAX_I_POS_DUTY_MAX);
self.tec_setting.max_i_pos_set = duty * TecSettings::MAX_I_POS_NEG_DUTY_TO_CURRENT_RATE; self.tec_settings.max_i_pos_set = duty * TecSettings::MAX_I_POS_NEG_DUTY_TO_CURRENT_RATE;
self.tec_setting.max_i_pos_set self.tec_settings.max_i_pos_set
} }
pub fn set_max_i_neg(&mut self, max_i_neg: ElectricCurrent) -> ElectricCurrent { pub fn set_max_i_neg(&mut self, max_i_neg: ElectricCurrent) -> ElectricCurrent {
let duty = (max_i_neg / TecSettings::MAX_I_POS_NEG_DUTY_TO_CURRENT_RATE).get::<ratio>(); let duty = (max_i_neg / TecSettings::MAX_I_POS_NEG_DUTY_TO_CURRENT_RATE).get::<ratio>();
let duty = self.max1968.set_pwm(PwmPinsEnum::MaxNegI, duty, TecSettings::MAX_I_NEG_DUTY_MAX); let duty = self.max1968.set_pwm(PwmPinsEnum::MaxNegI, duty, TecSettings::MAX_I_NEG_DUTY_MAX);
self.tec_setting.max_i_neg_set = duty * TecSettings::MAX_I_POS_NEG_DUTY_TO_CURRENT_RATE; self.tec_settings.max_i_neg_set = duty * TecSettings::MAX_I_POS_NEG_DUTY_TO_CURRENT_RATE;
self.tec_setting.max_i_neg_set self.tec_settings.max_i_neg_set
} }
pub fn get_dac_vfb(&mut self) -> ElectricPotential { pub fn get_dac_vfb(&mut self) -> ElectricPotential {
@ -280,17 +287,16 @@ impl Thermostat{
self.pid_ctrl_ch0.set_pid_engaged(val); self.pid_ctrl_ch0.set_pid_engaged(val);
} }
pub fn get_pid_engaged(&mut self) -> bool { fn get_pid_engaged(&mut self) -> bool {
self.pid_ctrl_ch0.get_pid_engaged() self.pid_ctrl_ch0.get_pid_engaged()
} }
pub fn get_status_report(&mut self) -> StatusReport { pub fn get_status_report(&mut self) -> StatusReport {
StatusReport { StatusReport {
ts: sys_timer::now(),
pid_engaged: self.get_pid_engaged(), pid_engaged: self.get_pid_engaged(),
temp_mon_status: self.temp_mon.get_status(), temp_mon_status: self.temp_mon.get_status(),
temperature: self.pid_ctrl_ch0.get_temperature(), temperature: self.pid_ctrl_ch0.get_temperature(),
i_set: self.tec_setting.i_set, i_set: self.tec_settings.i_set,
tec_i: self.get_tec_i(), tec_i: self.get_tec_i(),
tec_v: self.get_tec_v(), tec_v: self.get_tec_v(),
tec_vref: self.get_vref(), tec_vref: self.get_vref(),
@ -306,21 +312,26 @@ impl Thermostat{
} }
} }
pub fn get_pid_settings(&mut self) -> pid_state::Parameters { fn get_pid_settings(&mut self) -> pid_state::Parameters {
self.pid_ctrl_ch0.get_pid_settings() self.pid_ctrl_ch0.get_pid_settings()
} }
pub fn get_steinhart_hart(&mut self) -> steinhart_hart::Parameters { fn get_steinhart_hart(&mut self) -> ThermistorParams {
self.pid_ctrl_ch0.get_sh() let sh = self.pid_ctrl_ch0.get_sh();
ThermistorParams {
t0: sh.t0.get::<degree_celsius>(),
r0: sh.r0,
b: sh.b,
} }
pub fn get_tec_settings(&mut self) -> TecSettingSummary { }
fn get_tec_settings(&mut self) -> TecSettingSummary {
TecSettingSummary { TecSettingSummary {
center_point: self.tec_setting.center_pt, i_set: TecSettingsSummaryField { value: self.tec_settings.i_set, max: TecSettings::MAX_I_SET },
i_set: TecSettingsSummaryField { value: self.tec_setting.i_set, max: TecSettings::MAX_I_SET }, max_v: TecSettingsSummaryField { value: self.tec_settings.max_v_set, max: TecSettings::MAX_V_MAX },
max_v: TecSettingsSummaryField { value: self.tec_setting.max_v_set, max: TecSettings::MAX_V_MAX }, max_i_pos: TecSettingsSummaryField { value: self.tec_settings.max_i_pos_set, max: TecSettings::MAX_I_POS_CURRENT },
max_i_pos: TecSettingsSummaryField { value: self.tec_setting.max_i_pos_set, max: TecSettings::MAX_I_POS_CURRENT }, max_i_neg: TecSettingsSummaryField { value: self.tec_settings.max_i_neg_set, max: TecSettings::MAX_I_NEG_CURRENT },
max_i_neg: TecSettingsSummaryField { value: self.tec_setting.max_i_neg_set, max: TecSettings::MAX_I_NEG_CURRENT },
} }
} }
@ -345,8 +356,7 @@ impl Thermostat{
} }
pub fn set_temperature_setpoint(&mut self, t: ThermodynamicTemperature) { pub fn set_temperature_setpoint(&mut self, t: ThermodynamicTemperature) {
let temp_mon_settings = self.temp_mon.get_settings(); let t = t.min(self.temp_mon.get_upper_limit()).max(self.temp_mon.get_lower_limit());
let t = t.min(temp_mon_settings.upper_limit).max(temp_mon_settings.lower_limit);
self.pid_ctrl_ch0.set_pid_setpoint(t); self.pid_ctrl_ch0.set_pid_setpoint(t);
self.temp_mon.set_setpoint(t); self.temp_mon.set_setpoint(t);
} }
@ -363,15 +373,22 @@ impl Thermostat{
self.temp_mon.clear_alarm(); self.temp_mon.clear_alarm();
} }
pub fn get_temp_mon_settings(&mut self) -> TempMonSettings { fn get_temp_mon_settings(&mut self) -> TempMonSettings {
self.temp_mon.get_settings() self.temp_mon.get_settings()
} }
pub fn get_settings_summary(&mut self) -> ThermostatSettingsSummary {
ThermostatSettingsSummary {
tec_settings: self.get_tec_settings(),
pid_params: self.get_pid_settings(),
temp_mon_settings: self.get_temp_mon_settings(),
thermistor_params: self.get_steinhart_hart(),
}
}
} }
#[derive(Deserialize, Serialize, Copy, Clone, Debug, Tree)] #[derive(Deserialize, Serialize, Copy, Clone, Debug, Tree)]
pub struct StatusReport { pub struct StatusReport {
ts: u32,
pid_engaged: bool, pid_engaged: bool,
temp_mon_status: TempStatus, temp_mon_status: TempStatus,
temperature: Option<ThermodynamicTemperature>, temperature: Option<ThermodynamicTemperature>,
@ -381,27 +398,23 @@ pub struct StatusReport {
tec_vref: ElectricPotential, tec_vref: ElectricPotential,
} }
#[derive(Tree)] #[derive(Deserialize, Serialize, Copy, Clone, Debug, Tree)]
pub struct TecSettingsSummaryField<T> { pub struct TecSettingsSummaryField<T> {
value: T, value: T,
max: T, max: T,
} }
#[derive(Tree)] #[derive(Deserialize, Serialize, Copy, Clone, Debug, Tree)]
pub struct TecSettingSummary { pub struct TecSettingSummary {
center_point: ElectricPotential,
#[tree]
i_set: TecSettingsSummaryField<ElectricCurrent>, i_set: TecSettingsSummaryField<ElectricCurrent>,
#[tree]
max_v: TecSettingsSummaryField<ElectricPotential>, max_v: TecSettingsSummaryField<ElectricPotential>,
#[tree]
max_i_pos: TecSettingsSummaryField<ElectricCurrent>, max_i_pos: TecSettingsSummaryField<ElectricCurrent>,
#[tree]
max_i_neg: TecSettingsSummaryField<ElectricCurrent>, max_i_neg: TecSettingsSummaryField<ElectricCurrent>,
} }
#[derive(Tree)] #[derive(Deserialize, Serialize, Clone, Copy, Debug, Tree)]
pub struct SteinhartHartSummary { pub struct ThermistorParams {
#[tree] t0: f64,
params: steinhart_hart::Parameters, r0: ElectricalResistance,
b: f64
} }