Compare commits

...

6 Commits

Author SHA1 Message Date
41cd60be63 PwmLimits: Save user value into flash
In place of the machine value derived from the pwm duty.
2024-08-09 16:21:14 +08:00
0d48e0df43 PwmSummary: max -> user_value 2024-08-09 16:18:51 +08:00
23979d25d0 get_i -> get_i_set 2024-08-09 13:36:26 +08:00
13effa388e Orignal get_i 2024-08-09 13:36:02 +08:00
ced3363232 Move PwmLimits into its own file 2024-08-09 11:17:43 +08:00
ce1ee5a2fe PwmLimits: uom 2024-08-09 11:07:33 +08:00
6 changed files with 59 additions and 43 deletions

View File

@ -16,6 +16,7 @@ use uom::si::{
use crate::{ use crate::{
ad7172, ad7172,
pid, pid,
pwm_limits::PwmLimits,
steinhart_hart as sh, steinhart_hart as sh,
command_parser::CenterPoint, command_parser::CenterPoint,
}; };
@ -32,6 +33,7 @@ pub struct ChannelState {
pub center: CenterPoint, pub center: CenterPoint,
pub dac_value: ElectricPotential, pub dac_value: ElectricPotential,
pub i_set: ElectricCurrent, pub i_set: ElectricCurrent,
pub pwm_limits: PwmLimits,
pub pid_engaged: bool, pub pid_engaged: bool,
pub pid: pid::Controller, pub pid: pid::Controller,
pub sh: sh::Parameters, pub sh: sh::Parameters,
@ -48,6 +50,11 @@ impl ChannelState {
center: CenterPoint::Vref, center: CenterPoint::Vref,
dac_value: ElectricPotential::new::<volt>(0.0), dac_value: ElectricPotential::new::<volt>(0.0),
i_set: ElectricCurrent::new::<ampere>(0.0), i_set: ElectricCurrent::new::<ampere>(0.0),
pwm_limits: PwmLimits {
max_v: ElectricPotential::new::<volt>(0.0),
max_i_pos: ElectricCurrent::new::<ampere>(0.0),
max_i_neg: ElectricCurrent::new::<ampere>(0.0),
},
pid_engaged: false, pid_engaged: false,
pid: pid::Controller::new(pid::Parameters::default()), pid: pid::Controller::new(pid::Parameters::default()),
sh: sh::Parameters::default(), sh: sh::Parameters::default(),

View File

@ -134,9 +134,12 @@ impl Channels {
voltage voltage
} }
pub fn get_i(&mut self, channel: usize) -> ElectricCurrent { pub fn get_i_set(&mut self, channel: usize) -> (ElectricCurrent, ElectricCurrent) {
let i_set = self.channel_state(channel).i_set; let center_point = self.get_center(channel);
i_set let r_sense = ElectricalResistance::new::<ohm>(R_SENSE);
let voltage = self.get_dac(channel);
let i_set = (voltage - center_point) / (10.0 * r_sense);
(i_set, self.channel_state(channel).i_set)
} }
/// i_set DAC /// i_set DAC
@ -390,19 +393,19 @@ impl Channels {
pub fn get_max_v(&mut self, channel: usize) -> (ElectricPotential, ElectricPotential) { pub fn get_max_v(&mut self, channel: usize) -> (ElectricPotential, ElectricPotential) {
let max = 4.0 * ElectricPotential::new::<volt>(3.3); let max = 4.0 * ElectricPotential::new::<volt>(3.3);
let duty = self.get_pwm(channel, PwmPin::MaxV); let duty = self.get_pwm(channel, PwmPin::MaxV);
(duty * max, MAX_TEC_V) (duty * max, self.channel_state(channel).pwm_limits.max_v)
} }
pub fn get_max_i_pos(&mut self, channel: usize) -> (ElectricCurrent, ElectricCurrent) { pub fn get_max_i_pos(&mut self, channel: usize) -> (ElectricCurrent, ElectricCurrent) {
let max = ElectricCurrent::new::<ampere>(3.0); let max = ElectricCurrent::new::<ampere>(3.0);
let duty = self.get_pwm(channel, PwmPin::MaxIPos); let duty = self.get_pwm(channel, PwmPin::MaxIPos);
(duty * max, MAX_TEC_I) (duty * max, self.channel_state(channel).pwm_limits.max_i_pos)
} }
pub fn get_max_i_neg(&mut self, channel: usize) -> (ElectricCurrent, ElectricCurrent) { pub fn get_max_i_neg(&mut self, channel: usize) -> (ElectricCurrent, ElectricCurrent) {
let max = ElectricCurrent::new::<ampere>(3.0); let max = ElectricCurrent::new::<ampere>(3.0);
let duty = self.get_pwm(channel, PwmPin::MaxINeg); let duty = self.get_pwm(channel, PwmPin::MaxINeg);
(duty * max, MAX_TEC_I) (duty * max, self.channel_state(channel).pwm_limits.max_i_neg)
} }
// Get current passing through TEC // Get current passing through TEC
@ -446,6 +449,7 @@ impl Channels {
let max = 4.0 * ElectricPotential::new::<volt>(3.3); let max = 4.0 * ElectricPotential::new::<volt>(3.3);
let duty = (max_v.min(MAX_TEC_V).max(ElectricPotential::zero()) / max).get::<ratio>(); let duty = (max_v.min(MAX_TEC_V).max(ElectricPotential::zero()) / max).get::<ratio>();
let duty = self.set_pwm(channel, PwmPin::MaxV, duty); let duty = self.set_pwm(channel, PwmPin::MaxV, duty);
self.channel_state(channel).pwm_limits.max_v = max_v;
(duty * max, max) (duty * max, max)
} }
@ -453,6 +457,7 @@ impl Channels {
let max = ElectricCurrent::new::<ampere>(3.0); let max = ElectricCurrent::new::<ampere>(3.0);
let duty = (max_i_pos.min(MAX_TEC_I).max(ElectricCurrent::zero()) / max).get::<ratio>(); let duty = (max_i_pos.min(MAX_TEC_I).max(ElectricCurrent::zero()) / max).get::<ratio>();
let duty = self.set_pwm(channel, PwmPin::MaxIPos, duty); let duty = self.set_pwm(channel, PwmPin::MaxIPos, duty);
self.channel_state(channel).pwm_limits.max_i_pos = max_i_pos;
(duty * max, max) (duty * max, max)
} }
@ -460,11 +465,12 @@ impl Channels {
let max = ElectricCurrent::new::<ampere>(3.0); let max = ElectricCurrent::new::<ampere>(3.0);
let duty = (max_i_neg.min(MAX_TEC_I).max(ElectricCurrent::zero()) / max).get::<ratio>(); let duty = (max_i_neg.min(MAX_TEC_I).max(ElectricCurrent::zero()) / max).get::<ratio>();
let duty = self.set_pwm(channel, PwmPin::MaxINeg, duty); let duty = self.set_pwm(channel, PwmPin::MaxINeg, duty);
self.channel_state(channel).pwm_limits.max_i_neg = max_i_neg;
(duty * max, max) (duty * max, max)
} }
fn report(&mut self, channel: usize) -> Report { fn report(&mut self, channel: usize) -> Report {
let i_set = self.get_i(channel); let i_set = self.channel_state(channel).i_set;
let i_tec = self.adc_read(channel, PinsAdcReadTarget::ITec, 16); let i_tec = self.adc_read(channel, PinsAdcReadTarget::ITec, 16);
let tec_i = self.get_tec_i(channel); let tec_i = self.get_tec_i(channel);
let dac_value = self.get_dac(channel); let dac_value = self.get_dac(channel);
@ -518,7 +524,7 @@ impl Channels {
PwmSummary { PwmSummary {
channel, channel,
center: CenterPointJson(self.channel_state(channel).center.clone()), center: CenterPointJson(self.channel_state(channel).center.clone()),
i_set: (self.get_i(channel), MAX_TEC_I).into(), i_set: self.get_i_set(channel).into(),
max_v: self.get_max_v(channel).into(), max_v: self.get_max_v(channel).into(),
max_i_pos: self.get_max_i_pos(channel).into(), max_i_pos: self.get_max_i_pos(channel).into(),
max_i_neg: self.get_max_i_neg(channel).into(), max_i_neg: self.get_max_i_neg(channel).into(),
@ -606,12 +612,12 @@ impl Serialize for CenterPointJson {
#[derive(Serialize)] #[derive(Serialize)]
pub struct PwmSummaryField<T: Serialize> { pub struct PwmSummaryField<T: Serialize> {
value: T, value: T,
max: T, user_value: T,
} }
impl<T: Serialize> From<(T, T)> for PwmSummaryField<T> { impl<T: Serialize> From<(T, T)> for PwmSummaryField<T> {
fn from((value, max): (T, T)) -> Self { fn from((value, user_value): (T, T)) -> Self {
PwmSummaryField { value, max } PwmSummaryField { value, user_value }
} }
} }

View File

@ -207,8 +207,8 @@ impl Handler {
} }
fn set_center_point(socket: &mut TcpSocket, channels: &mut Channels, channel: usize, center: CenterPoint) -> Result<Handler, Error> { fn set_center_point(socket: &mut TcpSocket, channels: &mut Channels, channel: usize, center: CenterPoint) -> Result<Handler, Error> {
let i_set = channels.get_i(channel);
let state = channels.channel_state(channel); let state = channels.channel_state(channel);
let i_set = state.i_set;
state.center = center; state.center = center;
if !state.pid_engaged { if !state.pid_engaged {
channels.set_i(channel, i_set); channels.set_i(channel, i_set);

View File

@ -1,15 +1,12 @@
use num_traits::Zero; use num_traits::Zero;
use serde::{Serialize, Deserialize}; use serde::{Serialize, Deserialize};
use uom::si::{ use uom::si::f64::ElectricCurrent;
electric_potential::volt,
electric_current::ampere,
f64::{ElectricCurrent, ElectricPotential},
};
use crate::{ use crate::{
ad7172::PostFilter, ad7172::PostFilter,
channels::Channels, channels::Channels,
command_parser::CenterPoint, command_parser::CenterPoint,
pid, pid,
pwm_limits::PwmLimits,
steinhart_hart, steinhart_hart,
}; };
@ -70,29 +67,3 @@ impl ChannelConfig {
let _ = channels.set_i(channel, self.i_set); let _ = channels.set_i(channel, self.i_set);
} }
} }
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
struct PwmLimits {
max_v: f64,
max_i_pos: f64,
max_i_neg: f64,
}
impl PwmLimits {
pub fn new(channels: &mut Channels, channel: usize) -> Self {
let (max_v, _) = channels.get_max_v(channel);
let (max_i_pos, _) = channels.get_max_i_pos(channel);
let (max_i_neg, _) = channels.get_max_i_neg(channel);
PwmLimits {
max_v: max_v.get::<volt>(),
max_i_pos: max_i_pos.get::<ampere>(),
max_i_neg: max_i_neg.get::<ampere>(),
}
}
pub fn apply(&self, channels: &mut Channels, channel: usize) {
channels.set_max_v(channel, ElectricPotential::new::<volt>(self.max_v));
channels.set_max_i_pos(channel, ElectricCurrent::new::<ampere>(self.max_i_pos));
channels.set_max_i_neg(channel, ElectricCurrent::new::<ampere>(self.max_i_neg));
}
}

View File

@ -41,6 +41,7 @@ mod command_parser;
use command_parser::Ipv4Config; use command_parser::Ipv4Config;
mod timer; mod timer;
mod pid; mod pid;
mod pwm_limits;
mod steinhart_hart; mod steinhart_hart;
mod channels; mod channels;
use channels::{CHANNELS, Channels}; use channels::{CHANNELS, Channels};

31
src/pwm_limits.rs Normal file
View File

@ -0,0 +1,31 @@
use serde::{Serialize, Deserialize};
use uom::si::f64::{
ElectricCurrent, ElectricPotential,
};
use crate::channels::Channels;
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct PwmLimits {
pub max_v: ElectricPotential,
pub max_i_pos: ElectricCurrent,
pub max_i_neg: ElectricCurrent,
}
impl PwmLimits {
pub fn new(channels: &mut Channels, channel: usize) -> Self {
let max_v = channels.get_max_v(channel).1;
let max_i_pos = channels.get_max_i_pos(channel).1;
let max_i_neg = channels.get_max_i_neg(channel).1;
PwmLimits {
max_v,
max_i_pos,
max_i_neg,
}
}
pub fn apply(&self, channels: &mut Channels, channel: usize) {
channels.set_max_v(channel, self.max_v);
channels.set_max_i_pos(channel, self.max_i_pos);
channels.set_max_i_neg(channel, self.max_i_neg);
}
}