Change f64 to f32 for SI Unit related computation

- Save computational time
- Improve the processing speed of TecSetI cmd
This commit is contained in:
linuswck 2024-02-27 16:26:05 +08:00
parent b1fa0e51c8
commit 76477065be
14 changed files with 89 additions and 88 deletions

View File

@ -26,7 +26,7 @@ stm32f4xx-hal = { version = "0.14.0", features = ["rt", "stm32f407", "usb_fs"] }
stm32-eth = { version = "0.5.2", features = ["stm32f407", "smoltcp-phy", "smoltcp"] } stm32-eth = { version = "0.5.2", features = ["stm32f407", "smoltcp-phy", "smoltcp"] }
ieee802_3_miim = "0.8.0" ieee802_3_miim = "0.8.0"
smoltcp = { version = "0.10.0", default-features = false, features = ["proto-ipv4", "socket-tcp", "log", "medium-ethernet"] } smoltcp = { version = "0.10.0", default-features = false, features = ["proto-ipv4", "socket-tcp", "log", "medium-ethernet"] }
uom = { version = "0.30", default-features = false, features = ["autoconvert", "si", "f64", "use_serde"] } uom = { version = "0.30", default-features = false, features = ["autoconvert", "si", "f32", "use_serde"] }
num-traits = { version = "0.2.15", default-features = false, features = ["libm"] } num-traits = { version = "0.2.15", default-features = false, features = ["libm"] }
usb-device = "0.2.9" usb-device = "0.2.9"
usbd-serial = "0.1.1" usbd-serial = "0.1.1"

View File

@ -17,7 +17,7 @@ use stm32f4xx_hal::{
}; };
use uom::si::electric_current::milliampere; use uom::si::electric_current::milliampere;
use uom::si::{electric_current::ampere, f64::ElectricCurrent}; use uom::si::{electric_current::ampere, f32::ElectricCurrent};
#[cfg(not(feature = "semihosting"))] #[cfg(not(feature = "semihosting"))]
const WATCHDOG_PERIOD: u32 = 4000; const WATCHDOG_PERIOD: u32 = 4000;

View File

@ -13,14 +13,14 @@ use serde::{Deserialize, Serialize};
use uom::si::{ use uom::si::{
electric_current::milliampere, electric_current::milliampere,
f64::{ElectricPotential, ElectricCurrent, Power}, f32::{ElectricPotential, ElectricCurrent, Power},
}; };
use uom::{si::{ISQ, SI, Quantity}, typenum::*}; use uom::{si::{ISQ, SI, Quantity}, typenum::*};
// Volt / Ampere // Volt / Ampere
pub type TransimpedanceUnit = Quantity<ISQ<P2, P1, N3, N2, Z0, Z0, Z0>, SI<f64>, f64>; pub type TransimpedanceUnit = Quantity<ISQ<P2, P1, N3, N2, Z0, Z0, Z0>, SI<f32>, f32>;
// Ampere / Volt // Ampere / Volt
type TransconductanceUnit = Quantity<ISQ<N2, N1, P3, P2, Z0, Z0, Z0>, SI<f64>, f64>; type TransconductanceUnit = Quantity<ISQ<N2, N1, P3, P2, Z0, Z0, Z0>, SI<f32>, f32>;
impl Settings{ impl Settings{
pub const LD_CURRENT_MAX: ElectricCurrent = ElectricCurrent { pub const LD_CURRENT_MAX: ElectricCurrent = ElectricCurrent {

View File

@ -8,7 +8,7 @@ use stm32f4xx_hal::{
use uom::si::{ use uom::si::{
ratio::ratio, ratio::ratio,
f64::{ElectricPotential, ElectricCurrent}, f32::{ElectricPotential, ElectricCurrent},
}; };
use crate::laser_diode::max5719::{self, Dac}; use crate::laser_diode::max5719::{self, Dac};
@ -79,9 +79,9 @@ impl LdCtrl {
pub fn set_dac(&mut self, voltage: ElectricPotential, dac_out_v_max: ElectricPotential) -> ElectricPotential { pub fn set_dac(&mut self, voltage: ElectricPotential, dac_out_v_max: ElectricPotential) -> ElectricPotential {
let value = ((voltage / dac_out_v_max).get::<ratio>() let value = ((voltage / dac_out_v_max).get::<ratio>()
* (max5719::MAX_VALUE as f64)) as u32; * (max5719::MAX_VALUE as f32)) as u32;
self.phy.dac.set(value).unwrap(); self.phy.dac.set(value).unwrap();
value as f64 * dac_out_v_max / max5719::MAX_VALUE as f64 value as f32 * dac_out_v_max / max5719::MAX_VALUE as f32
} }
pub fn set_i(&mut self, current: ElectricCurrent, transimpedance: TransimpedanceUnit, dac_out_v_max: ElectricPotential) -> ElectricCurrent { pub fn set_i(&mut self, current: ElectricCurrent, transimpedance: TransimpedanceUnit, dac_out_v_max: ElectricPotential) -> ElectricCurrent {

View File

@ -1,6 +1,6 @@
use stm32f4xx_hal::timer::{CounterUs, Event}; use stm32f4xx_hal::timer::{CounterUs, Event};
use stm32f4xx_hal::pac::{interrupt, Interrupt, TIM2}; use stm32f4xx_hal::pac::{interrupt, Interrupt, TIM2};
use uom::si::{f64::ElectricCurrent, electric_current::ampere}; use uom::si::{f32::ElectricCurrent, electric_current::ampere};
use fugit::{TimerDurationU32, KilohertzU32}; use fugit::{TimerDurationU32, KilohertzU32};
use core::marker::PhantomData; use core::marker::PhantomData;

View File

@ -7,7 +7,7 @@ use stm32f4xx_hal::{
}; };
use uom::si::{ use uom::si::{
electric_potential::millivolt, electric_potential::millivolt,
f64::ElectricPotential, f32::ElectricPotential,
ratio::ratio ratio::ratio
}; };
@ -134,14 +134,14 @@ impl LdPwrExcProtector {
fn convert_sample_to_volt(sample :u16) -> ElectricPotential { fn convert_sample_to_volt(sample :u16) -> ElectricPotential {
if let Some(ref mut wdg ) = LdPwrExcProtector::get() { if let Some(ref mut wdg ) = LdPwrExcProtector::get() {
return ElectricPotential::new::<millivolt>(((u32::from(sample) * wdg.calibrated_vdda) / u32::from(MAX_SAMPLE)) as f64) return ElectricPotential::new::<millivolt>(((u32::from(sample) * wdg.calibrated_vdda) / u32::from(MAX_SAMPLE)) as f32)
} }
ElectricPotential::new::<millivolt>(0.0) ElectricPotential::new::<millivolt>(0.0)
} }
pub fn set_trigger_threshold_v(htr: ElectricPotential){ pub fn set_trigger_threshold_v(htr: ElectricPotential){
if let Some(ref mut wdg ) = LdPwrExcProtector::get() { if let Some(ref mut wdg ) = LdPwrExcProtector::get() {
let code: u32 = ((htr / (ElectricPotential::new::<millivolt>(wdg.calibrated_vdda as f64))).get::<ratio>() * (MAX_SAMPLE as f64)) as u32; let code: u32 = ((htr / (ElectricPotential::new::<millivolt>(wdg.calibrated_vdda as f32))).get::<ratio>() * (MAX_SAMPLE as f32)) as u32;
wdg.pac.htr.write(|w| unsafe {w.bits(code)}); wdg.pac.htr.write(|w| unsafe {w.bits(code)});
} }
} }

View File

@ -1,7 +1,7 @@
use core::{f64::NAN, marker::PhantomData}; use core::{f32::NAN, marker::PhantomData};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use uom::si::{ use uom::si::{
f64::{ f32::{
ElectricCurrent, ElectricCurrent,
Power Power
}, },
@ -11,7 +11,7 @@ use uom::{si::{ISQ, SI, Quantity}, typenum::*};
use miniconf::Tree; 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<f32>, f32>;
#[derive(Deserialize, Serialize, Clone, Copy, Debug, PartialEq, Tree)] #[derive(Deserialize, Serialize, Clone, Copy, Debug, PartialEq, Tree)]
pub struct Parameters { pub struct Parameters {

View File

@ -156,7 +156,7 @@ pub fn send_status_report(buffer: &mut [u8], laser: &mut LdDrive, tec: &mut Ther
// Use a minimal struct for high speed cmd ctrl to reduce processing overhead // Use a minimal struct for high speed cmd ctrl to reduce processing overhead
#[derive(Deserialize, Serialize, Copy, Clone, Debug, Default, Tree)] #[derive(Deserialize, Serialize, Copy, Clone, Debug, Default, Tree)]
pub struct TecSetICmdJson { pub struct TecSetICmdJson {
tec_set_i: f64 tec_set_i: f32
} }
#[derive(Deserialize, Serialize, Copy, Clone, Debug, Default, Tree)] #[derive(Deserialize, Serialize, Copy, Clone, Debug, Default, Tree)]
pub struct TecSetICmd { pub struct TecSetICmd {
@ -229,7 +229,7 @@ pub fn execute_cmd(buffer: &mut [u8], buffer_size: usize, mut laser: LdDrive, mu
laser.ld_open(); laser.ld_open();
} }
Some(LdCmdEnum::SetI) => { Some(LdCmdEnum::SetI) => {
match cmd.json.data_f64 { match cmd.json.data_f32 {
Some(val) => { Some(val) => {
laser.ld_set_i(ElectricCurrent::new::<milliampere>(val)); laser.ld_set_i(ElectricCurrent::new::<milliampere>(val));
} }
@ -239,7 +239,7 @@ pub fn execute_cmd(buffer: &mut [u8], buffer_size: usize, mut laser: LdDrive, mu
} }
} }
Some(LdCmdEnum::SetISoftLimit) => { Some(LdCmdEnum::SetISoftLimit) => {
match cmd.json.data_f64 { match cmd.json.data_f32 {
Some(val) => { Some(val) => {
laser.set_ld_drive_current_limit(ElectricCurrent::new::<milliampere>(val)) laser.set_ld_drive_current_limit(ElectricCurrent::new::<milliampere>(val))
} }
@ -249,7 +249,7 @@ pub fn execute_cmd(buffer: &mut [u8], buffer_size: usize, mut laser: LdDrive, mu
} }
} }
Some(LdCmdEnum::SetPdResponsitivity) => { Some(LdCmdEnum::SetPdResponsitivity) => {
match cmd.json.data_f64 { match cmd.json.data_f32 {
Some(val) => { Some(val) => {
laser.set_pd_responsitivity(ResponsitivityUnit {dimension: PhantomData, units: PhantomData, value: val}) laser.set_pd_responsitivity(ResponsitivityUnit {dimension: PhantomData, units: PhantomData, value: val})
} }
@ -259,7 +259,7 @@ pub fn execute_cmd(buffer: &mut [u8], buffer_size: usize, mut laser: LdDrive, mu
} }
} }
Some(LdCmdEnum::SetPdDarkCurrent) => { Some(LdCmdEnum::SetPdDarkCurrent) => {
match cmd.json.data_f64 { match cmd.json.data_f32 {
Some(val) => { Some(val) => {
laser.set_pd_dark_current(ElectricCurrent::new::<microampere>(val)) laser.set_pd_dark_current(ElectricCurrent::new::<microampere>(val))
} }
@ -269,7 +269,7 @@ pub fn execute_cmd(buffer: &mut [u8], buffer_size: usize, mut laser: LdDrive, mu
} }
} }
Some(LdCmdEnum::SetLdPwrLimit) => { Some(LdCmdEnum::SetLdPwrLimit) => {
match cmd.json.data_f64 { match cmd.json.data_f32 {
Some(val) => { Some(val) => {
laser.set_ld_power_limit(Power::new::<milliwatt>(val)) laser.set_ld_power_limit(Power::new::<milliwatt>(val))
} }
@ -295,7 +295,7 @@ pub fn execute_cmd(buffer: &mut [u8], buffer_size: usize, mut laser: LdDrive, mu
tec.power_down() tec.power_down()
} }
Some(ThermostatCmdEnum::SetTecMaxV) => { Some(ThermostatCmdEnum::SetTecMaxV) => {
match cmd.json.data_f64 { match cmd.json.data_f32 {
Some(val) => { Some(val) => {
tec.set_max_v(ElectricPotential::new::<volt>(val)); tec.set_max_v(ElectricPotential::new::<volt>(val));
} }
@ -305,7 +305,7 @@ pub fn execute_cmd(buffer: &mut [u8], buffer_size: usize, mut laser: LdDrive, mu
} }
} }
Some(ThermostatCmdEnum::SetTecMaxIPos) => { Some(ThermostatCmdEnum::SetTecMaxIPos) => {
match cmd.json.data_f64 { match cmd.json.data_f32 {
Some(val) => { Some(val) => {
tec.set_max_i_pos(ElectricCurrent::new::<ampere>(val)); tec.set_max_i_pos(ElectricCurrent::new::<ampere>(val));
} }
@ -315,7 +315,7 @@ pub fn execute_cmd(buffer: &mut [u8], buffer_size: usize, mut laser: LdDrive, mu
} }
} }
Some(ThermostatCmdEnum::SetTecMaxINeg) => { Some(ThermostatCmdEnum::SetTecMaxINeg) => {
match cmd.json.data_f64 { match cmd.json.data_f32 {
Some(val) => { Some(val) => {
tec.set_max_i_pos(ElectricCurrent::new::<milliampere>(val)); tec.set_max_i_pos(ElectricCurrent::new::<milliampere>(val));
} }
@ -325,7 +325,7 @@ pub fn execute_cmd(buffer: &mut [u8], buffer_size: usize, mut laser: LdDrive, mu
} }
} }
Some(ThermostatCmdEnum::SetTecIOut) => { Some(ThermostatCmdEnum::SetTecIOut) => {
match cmd.json.data_f64 { match cmd.json.data_f32 {
Some(val) => { Some(val) => {
tec.set_i(ElectricCurrent::new::<milliampere>(val)); tec.set_i(ElectricCurrent::new::<milliampere>(val));
} }
@ -335,7 +335,7 @@ pub fn execute_cmd(buffer: &mut [u8], buffer_size: usize, mut laser: LdDrive, mu
} }
} }
Some(ThermostatCmdEnum::SetTemperatureSetpoint) => { Some(ThermostatCmdEnum::SetTemperatureSetpoint) => {
match cmd.json.data_f64 { match cmd.json.data_f32 {
Some(val) => { Some(val) => {
tec.set_temperature_setpoint(ThermodynamicTemperature::new::<degree_celsius>(val)); tec.set_temperature_setpoint(ThermodynamicTemperature::new::<degree_celsius>(val));
} }
@ -351,7 +351,7 @@ pub fn execute_cmd(buffer: &mut [u8], buffer_size: usize, mut laser: LdDrive, mu
tec.set_pid_engaged(false); tec.set_pid_engaged(false);
} }
Some(ThermostatCmdEnum::SetPidKp) => { Some(ThermostatCmdEnum::SetPidKp) => {
match cmd.json.data_f64 { match cmd.json.data_f32 {
Some(val) => { Some(val) => {
tec.set_pid(Kp, val); tec.set_pid(Kp, val);
} }
@ -361,7 +361,7 @@ pub fn execute_cmd(buffer: &mut [u8], buffer_size: usize, mut laser: LdDrive, mu
} }
} }
Some(ThermostatCmdEnum::SetPidKi) => { Some(ThermostatCmdEnum::SetPidKi) => {
match cmd.json.data_f64 { match cmd.json.data_f32 {
Some(val) => { Some(val) => {
tec.set_pid(Ki, val); tec.set_pid(Ki, val);
} }
@ -371,7 +371,7 @@ pub fn execute_cmd(buffer: &mut [u8], buffer_size: usize, mut laser: LdDrive, mu
} }
} }
Some(ThermostatCmdEnum::SetPidKd) => { Some(ThermostatCmdEnum::SetPidKd) => {
match cmd.json.data_f64 { match cmd.json.data_f32 {
Some(val) => { Some(val) => {
tec.set_pid(Kd, val); tec.set_pid(Kd, val);
} }
@ -381,7 +381,7 @@ pub fn execute_cmd(buffer: &mut [u8], buffer_size: usize, mut laser: LdDrive, mu
} }
} }
Some(ThermostatCmdEnum::SetPidOutMin) => { Some(ThermostatCmdEnum::SetPidOutMin) => {
match cmd.json.data_f64 { match cmd.json.data_f32 {
Some(val) => { Some(val) => {
tec.set_pid(Min, val); tec.set_pid(Min, val);
} }
@ -391,7 +391,7 @@ pub fn execute_cmd(buffer: &mut [u8], buffer_size: usize, mut laser: LdDrive, mu
} }
} }
Some(ThermostatCmdEnum::SetPidOutMax) => { Some(ThermostatCmdEnum::SetPidOutMax) => {
match cmd.json.data_f64 { match cmd.json.data_f32 {
Some(val) => { Some(val) => {
tec.set_pid(Max, val); tec.set_pid(Max, val);
} }
@ -433,7 +433,7 @@ pub fn execute_cmd(buffer: &mut [u8], buffer_size: usize, mut laser: LdDrive, mu
tec.set_temp_adc_sinc3_fine_filter(0, val2); tec.set_temp_adc_sinc3_fine_filter(0, val2);
} }
None => { None => {
info!("data_f64 field needs to be set for configuration"); info!("data_f32 field needs to be set for configuration");
} }
} }
} }
@ -455,7 +455,7 @@ pub fn execute_cmd(buffer: &mut [u8], buffer_size: usize, mut laser: LdDrive, mu
} }
} }
Some(ThermostatCmdEnum::SetTempMonUpperLimit) => { Some(ThermostatCmdEnum::SetTempMonUpperLimit) => {
match cmd.json.data_f64 { match cmd.json.data_f32 {
Some(val) => { Some(val) => {
tec.set_temp_mon_upper_limit(ThermodynamicTemperature::new::<degree_celsius>(val)); tec.set_temp_mon_upper_limit(ThermodynamicTemperature::new::<degree_celsius>(val));
} }
@ -465,7 +465,7 @@ pub fn execute_cmd(buffer: &mut [u8], buffer_size: usize, mut laser: LdDrive, mu
} }
} }
Some(ThermostatCmdEnum::SetTempMonLowerLimit) => { Some(ThermostatCmdEnum::SetTempMonLowerLimit) => {
match cmd.json.data_f64 { match cmd.json.data_f32 {
Some(val) => { Some(val) => {
tec.set_temp_mon_lower_limit(ThermodynamicTemperature::new::<degree_celsius>(val)); tec.set_temp_mon_lower_limit(ThermodynamicTemperature::new::<degree_celsius>(val));
} }
@ -478,7 +478,7 @@ pub fn execute_cmd(buffer: &mut [u8], buffer_size: usize, mut laser: LdDrive, mu
tec.clear_temp_mon_alarm(); tec.clear_temp_mon_alarm();
} }
Some(ThermostatCmdEnum::SetShT0) => { Some(ThermostatCmdEnum::SetShT0) => {
match cmd.json.data_f64 { match cmd.json.data_f32 {
Some(val) => { Some(val) => {
tec.set_sh_t0(ThermodynamicTemperature::new::<degree_celsius>(val)); tec.set_sh_t0(ThermodynamicTemperature::new::<degree_celsius>(val));
} }
@ -488,7 +488,7 @@ pub fn execute_cmd(buffer: &mut [u8], buffer_size: usize, mut laser: LdDrive, mu
} }
} }
Some(ThermostatCmdEnum::SetShR0) => { Some(ThermostatCmdEnum::SetShR0) => {
match cmd.json.data_f64 { match cmd.json.data_f32 {
Some(val) => { Some(val) => {
tec.set_sh_r0(ElectricalResistance::new::<ohm>(val)); tec.set_sh_r0(ElectricalResistance::new::<ohm>(val));
} }
@ -498,7 +498,7 @@ pub fn execute_cmd(buffer: &mut [u8], buffer_size: usize, mut laser: LdDrive, mu
} }
} }
Some(ThermostatCmdEnum::SetShBeta) => { Some(ThermostatCmdEnum::SetShBeta) => {
match cmd.json.data_f64 { match cmd.json.data_f32 {
Some(val) => { Some(val) => {
tec.set_sh_beta(val); tec.set_sh_beta(val);
} }

View File

@ -11,7 +11,7 @@ use stm32f4xx_hal::
}, },
}; };
use uom::si::{ use uom::si::{
f64::ElectricPotential, f32::ElectricPotential,
electric_potential::volt, electric_potential::volt,
}; };
use super::{ use super::{
@ -325,15 +325,15 @@ impl Default for ChannelCalibration {
impl ChannelCalibration { impl ChannelCalibration {
pub fn convert_data(&self, data: u32) -> ElectricPotential { pub fn convert_data(&self, data: u32) -> ElectricPotential {
let data = if self.bipolar { let data = if self.bipolar {
(data as i32 - 0x80_0000) as f64 (data as i32 - 0x80_0000) as f32
} else { } else {
data as f64 / 2.0 data as f32 / 2.0
}; };
let data = data / (self.gain as f64 / (0x40_0000 as f64)); let data = data / (self.gain as f32 / (0x40_0000 as f32));
let data = data + (self.offset as i32 - 0x80_0000) as f64; let data = data + (self.offset as i32 - 0x80_0000) as f32;
let data = data / (2 << 23) as f64; let data = data / (2 << 23) as f32;
const V_REF: f64 = 3.3; const V_REF: f32 = 3.3;
ElectricPotential::new::<volt>(data * V_REF / 0.75) ElectricPotential::new::<volt>(data * V_REF / 0.75)
} }
} }

View File

@ -15,7 +15,7 @@ use stm32f4xx_hal::{
use uom::si::{ use uom::si::{
electric_potential::millivolt, electric_potential::millivolt,
f64::ElectricPotential, f32::ElectricPotential,
ratio::ratio, ratio::ratio,
}; };
@ -143,9 +143,8 @@ impl MAX1968 {
pub fn set_dac(&mut self, voltage: ElectricPotential, dac_out_v_max: ElectricPotential) -> ElectricPotential { pub fn set_dac(&mut self, voltage: ElectricPotential, dac_out_v_max: ElectricPotential) -> ElectricPotential {
let value = ((voltage / dac_out_v_max).get::<ratio>() let value = ((voltage / dac_out_v_max).get::<ratio>()
* (ad5680::MAX_VALUE as f64)) as u32; * (ad5680::MAX_VALUE as f32)) as u32;
self.phy.dac.set(value).unwrap(); self.phy.dac.set(value).unwrap();
// TODO: Store the set-ed DAC Voltage Value
voltage voltage
} }
@ -192,7 +191,7 @@ impl MAX1968 {
} }
}; };
let mv = self.pins_adc.sample_to_millivolts(sample as u16); let mv = self.pins_adc.sample_to_millivolts(sample as u16);
ElectricPotential::new::<millivolt>(mv as f64) ElectricPotential::new::<millivolt>(mv as f32)
} }
pub fn set_pwm(&mut self, pwm_pin: PwmPinsEnum, duty: f64, max_duty: f64) -> f64 { pub fn set_pwm(&mut self, pwm_pin: PwmPinsEnum, duty: f64, max_duty: f64) -> f64 {

View File

@ -1,7 +1,7 @@
use miniconf::Tree; use miniconf::Tree;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use uom::si::{ use uom::si::{
electric_potential::volt, electrical_resistance::ohm, f64::{ electric_potential::volt, electrical_resistance::ohm, f32::{
ElectricPotential, ElectricalResistance, ThermodynamicTemperature ElectricPotential, ElectricalResistance, ThermodynamicTemperature
}, thermodynamic_temperature::degree_celsius }, thermodynamic_temperature::degree_celsius
}; };
@ -9,8 +9,8 @@ use crate::thermostat::{
ad7172, ad7172,
steinhart_hart as sh, steinhart_hart as sh,
}; };
const R_INNER: f64 = 2.0 * 5100.0; const R_INNER: f32 = 2.0 * 5100.0;
const VREF_SENS: f64 = 3.3 / 2.0; const VREF_SENS: f32 = 3.3 / 2.0;
#[derive(Deserialize, Serialize, Clone, Copy, Debug, PartialEq, Tree)] #[derive(Deserialize, Serialize, Clone, Copy, Debug, PartialEq, Tree)]
pub struct Parameters { pub struct Parameters {
@ -105,11 +105,11 @@ impl PidState {
pub fn update_pid(&mut self) -> Option<f64> { pub fn update_pid(&mut self) -> Option<f64> {
let input = self.get_temperature()?.get::<degree_celsius>(); let input = self.get_temperature()?.get::<degree_celsius>();
let setpoint = self.set_point.get::<degree_celsius>(); let setpoint = self.set_point.get::<degree_celsius>();
let mut output: f64 = self.controller.y1 - setpoint * f64::from(self.controller.parameters.ki) let mut output: f64 = self.controller.y1 - setpoint as f64 * f64::from(self.controller.parameters.ki)
+ input * f64::from(self.controller.parameters.kp + self.controller.parameters.ki + self.controller.parameters.kd) + input as f64 * f64::from(self.controller.parameters.kp + self.controller.parameters.ki + self.controller.parameters.kd)
- self.controller.x1 * f64::from(self.controller.parameters.kp + 2.0 * self.controller.parameters.kd) - self.controller.x1 * f64::from(self.controller.parameters.kp + 2.0 * self.controller.parameters.kd)
+ self.controller.x2 * f64::from(self.controller.parameters.kd) + self.controller.x2 * f64::from(self.controller.parameters.kd)
+ f64::from(self.controller.parameters.kp) * (setpoint - self.controller.u1); + f64::from(self.controller.parameters.kp) * (setpoint as f64 - self.controller.u1);
if output < self.controller.parameters.output_min.into() { if output < self.controller.parameters.output_min.into() {
output = self.controller.parameters.output_min.into(); output = self.controller.parameters.output_min.into();
} }
@ -117,8 +117,8 @@ impl PidState {
output = self.controller.parameters.output_max.into(); output = self.controller.parameters.output_max.into();
} }
self.controller.x2 = self.controller.x1; self.controller.x2 = self.controller.x1;
self.controller.x1 = input; self.controller.x1 = input as f64;
self.controller.u1 = setpoint; self.controller.u1 = setpoint as f64;
self.controller.y1 = output; self.controller.y1 = output;
Some(output) Some(output)
} }
@ -142,22 +142,22 @@ impl PidState {
Some(temperature) Some(temperature)
} }
pub fn set_pid_params(&mut self, param: PidSettings, val: f64){ pub fn set_pid_params(&mut self, param: PidSettings, val: f32){
match param { match param {
PidSettings::Kp => { PidSettings::Kp => {
self.controller.parameters.kp = val as f32; self.controller.parameters.kp = val;
} }
PidSettings::Ki => { PidSettings::Ki => {
self.controller.parameters.ki = val as f32; self.controller.parameters.ki = val;
} }
PidSettings::Kd => { PidSettings::Kd => {
self.controller.parameters.kd = val as f32; self.controller.parameters.kd = val;
} }
PidSettings::Min => { PidSettings::Min => {
self.controller.parameters.output_min = val as f32; self.controller.parameters.output_min = val;
} }
PidSettings::Max => { PidSettings::Max => {
self.controller.parameters.output_max = val as f32; self.controller.parameters.output_max = val;
} }
} }
} }
@ -185,7 +185,7 @@ impl PidState {
self.sh.r0 = r0 self.sh.r0 = r0
} }
pub fn set_sh_beta(&mut self, beta: f64){ pub fn set_sh_beta(&mut self, beta: f32){
self.sh.b = beta self.sh.b = beta
} }

View File

@ -1,7 +1,7 @@
use num_traits::float::Float; use num_traits::float::Float;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use uom::si::{ use uom::si::{
f64::{ f32::{
ElectricalResistance, ElectricalResistance,
ThermodynamicTemperature, ThermodynamicTemperature,
}, },
@ -19,7 +19,7 @@ pub struct Parameters {
/// Base resistance /// Base resistance
pub r0: ElectricalResistance, pub r0: ElectricalResistance,
/// Beta /// Beta
pub b: f64, pub b: f32,
} }
impl Parameters { impl Parameters {

View File

@ -1,7 +1,7 @@
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use miniconf::Tree; use miniconf::Tree;
use uom::si::{ use uom::si::{
f64::ThermodynamicTemperature, thermodynamic_temperature::degree_celsius f32::ThermodynamicTemperature, thermodynamic_temperature::degree_celsius
}; };
use num_traits::Float; use num_traits::Float;
#[derive(PartialEq, Deserialize, Serialize, Copy, Clone, Default, Debug)] #[derive(PartialEq, Deserialize, Serialize, Copy, Clone, Default, Debug)]
@ -21,8 +21,8 @@ pub struct TempStatus {
#[derive(Deserialize, Serialize, Copy, Clone, Debug, Tree)] #[derive(Deserialize, Serialize, Copy, Clone, Debug, Tree)]
pub struct TempMonSettings { pub struct TempMonSettings {
pub upper_limit: f64, pub upper_limit: f32,
pub lower_limit: f64, pub lower_limit: f32,
} }
pub struct TempMon { pub struct TempMon {

View File

@ -13,7 +13,7 @@ use uom::si::{
electric_potential::volt, electric_potential::volt,
electrical_resistance::ohm, electrical_resistance::ohm,
thermodynamic_temperature::degree_celsius, thermodynamic_temperature::degree_celsius,
f64::{ThermodynamicTemperature, ElectricCurrent, ElectricPotential, ElectricalResistance}, f32::{ThermodynamicTemperature, ElectricCurrent, ElectricPotential, ElectricalResistance},
ratio::ratio, ratio::ratio,
}; };
use miniconf::Tree; use miniconf::Tree;
@ -66,7 +66,7 @@ impl TecSettings{
units: PhantomData, units: PhantomData,
value: 5.0, value: 5.0,
}; };
const MAX_V_DUTY_MAX: f64 = TecSettings::MAX_V_MAX.value / TecSettings::MAX_V_DUTY_TO_CURRENT_RATE.value; const MAX_V_DUTY_MAX: f64 = TecSettings::MAX_V_MAX.value as f64 / TecSettings::MAX_V_DUTY_TO_CURRENT_RATE.value as f64;
const MAX_I_POS_NEG_DUTY_TO_CURRENT_RATE: ElectricCurrent = ElectricCurrent { const MAX_I_POS_NEG_DUTY_TO_CURRENT_RATE: ElectricCurrent = ElectricCurrent {
dimension: PhantomData, dimension: PhantomData,
units: PhantomData, units: PhantomData,
@ -83,8 +83,8 @@ impl TecSettings{
value: 1.0, value: 1.0,
}; };
// .get::<ratio>() is not implemented for const // .get::<ratio>() is not implemented for const
const MAX_I_POS_DUTY_MAX: f64 = TecSettings::MAX_I_POS_CURRENT.value / TecSettings::MAX_I_POS_NEG_DUTY_TO_CURRENT_RATE.value; const MAX_I_POS_DUTY_MAX: f64 = TecSettings::MAX_I_POS_CURRENT.value as f64 / TecSettings::MAX_I_POS_NEG_DUTY_TO_CURRENT_RATE.value as f64;
const MAX_I_NEG_DUTY_MAX: f64 = TecSettings::MAX_I_NEG_CURRENT.value / TecSettings::MAX_I_POS_NEG_DUTY_TO_CURRENT_RATE.value; const MAX_I_NEG_DUTY_MAX: f64 = TecSettings::MAX_I_NEG_CURRENT.value as f64 / TecSettings::MAX_I_POS_NEG_DUTY_TO_CURRENT_RATE.value as f64;
} }
impl Default for TecSettings { impl Default for TecSettings {
@ -176,7 +176,7 @@ impl Thermostat{
if pid_engaged { if pid_engaged {
match state.update_pid() { match state.update_pid() {
Some(pid_output) => { Some(pid_output) => {
self.set_i(ElectricCurrent::new::<ampere>(pid_output)); 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>()); debug!("Temperature Set Point: {:?} degree", self.pid_ctrl_ch0.get_pid_setpoint().get::<degree_celsius>());
} }
None => { } None => { }
@ -213,40 +213,42 @@ impl Thermostat{
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 as f64, TecSettings::MAX_V_DUTY_MAX);
self.tec_settings.max_v_set = duty * TecSettings::MAX_V_DUTY_TO_CURRENT_RATE; self.tec_settings.max_v_set = duty as f32 * TecSettings::MAX_V_DUTY_TO_CURRENT_RATE;
self.tec_settings.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 as f64, TecSettings::MAX_I_POS_DUTY_MAX);
self.tec_settings.max_i_pos_set = duty * TecSettings::MAX_I_POS_NEG_DUTY_TO_CURRENT_RATE; self.tec_settings.max_i_pos_set = duty as f32 * TecSettings::MAX_I_POS_NEG_DUTY_TO_CURRENT_RATE;
self.tec_settings.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 as f64, TecSettings::MAX_I_NEG_DUTY_MAX);
self.tec_settings.max_i_neg_set = duty * TecSettings::MAX_I_POS_NEG_DUTY_TO_CURRENT_RATE; self.tec_settings.max_i_neg_set = duty as f32 * TecSettings::MAX_I_POS_NEG_DUTY_TO_CURRENT_RATE;
self.tec_settings.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 {
self.max1968.adc_read(AdcReadTarget::DacVfb, 16) ElectricPotential::new::<volt>(NAN)
// self.max1968.adc_read(AdcReadTarget::DacVfb, 16)
} }
pub fn get_vref(&mut self) -> ElectricPotential { pub fn get_vref(&mut self) -> ElectricPotential {
self.max1968.adc_read(AdcReadTarget::VREF, 16) // ElectricPotential::new::<volt>(NAN)
self.max1968.adc_read(AdcReadTarget::VREF, 1)
} }
pub fn get_tec_i(&mut self) -> ElectricCurrent { pub fn get_tec_i(&mut self) -> ElectricCurrent {
let vref = self.get_vref(); let vref = self.get_vref();
(self.max1968.adc_read(AdcReadTarget::ITec, 16) - vref) / ElectricalResistance::new::<ohm>(0.4) (self.max1968.adc_read(AdcReadTarget::ITec, 1) - vref) / ElectricalResistance::new::<ohm>(0.4)
} }
pub fn get_tec_v(&mut self) -> ElectricPotential { pub fn get_tec_v(&mut self) -> ElectricPotential {
(self.max1968.adc_read(AdcReadTarget::VTec, 16) - TecSettings::TEC_VSEC_BIAS_V) * 4.0 (self.max1968.adc_read(AdcReadTarget::VTec, 1) - TecSettings::TEC_VSEC_BIAS_V) * 4.0
} }
/// Calibrates the DAC output to match vref of the MAX driver to reduce zero-current offset of the MAX driver output. /// Calibrates the DAC output to match vref of the MAX driver to reduce zero-current offset of the MAX driver output.
@ -285,7 +287,7 @@ impl Thermostat{
best_error = error; best_error = error;
start_value = prev_value; start_value = prev_value;
let vref = (value as f64 / ad5680::MAX_VALUE as f64) * TecSettings::DAC_OUT_V_MAX; let vref = (value as f32 / ad5680::MAX_VALUE as f32) * TecSettings::DAC_OUT_V_MAX;
self.set_center_pt(vref); self.set_center_pt(vref);
} }
prev_value = value; prev_value = value;
@ -349,11 +351,11 @@ impl Thermostat{
self.max1968.get_calibrated_vdda() self.max1968.get_calibrated_vdda()
} }
pub fn set_pid(&mut self, param: PidSettings, val: f64){ pub fn set_pid(&mut self, param: PidSettings, val: f32){
self.pid_ctrl_ch0.set_pid_params(param, val); self.pid_ctrl_ch0.set_pid_params(param, val);
} }
pub fn set_sh_beta(&mut self, beta: f64) { pub fn set_sh_beta(&mut self, beta: f32) {
self.pid_ctrl_ch0.set_sh_beta(beta); self.pid_ctrl_ch0.set_sh_beta(beta);
} }
@ -441,7 +443,7 @@ pub struct TecSettingSummary {
#[derive(Deserialize, Serialize, Clone, Copy, Debug, Tree)] #[derive(Deserialize, Serialize, Clone, Copy, Debug, Tree)]
pub struct ThermistorParams { pub struct ThermistorParams {
t0: f64, t0: f32,
r0: ElectricalResistance, r0: ElectricalResistance,
b: f64 b: f32
} }