Compare commits

..

3 Commits

Author SHA1 Message Date
45129be836 PwmLimits: Save user set value into flash
In place of the machine values derived from the PWM duty / center point
calculations
2024-08-15 17:08:35 +08:00
227a157e9e README: Document PWM value clamping 2024-08-15 17:08:35 +08:00
e34196267b PwmSummary: Show set value instead of max
Show in summary the set value, before all PWM duty calculations instead
of the maximum value.

Putting the maximum in PwmSummary has little use - the maximum never
changes throughout the runtime of the firmware and can be replaced by
documentation elsewhere.
2024-08-15 17:08:35 +08:00
3 changed files with 70 additions and 26 deletions

View File

@ -15,7 +15,7 @@ class Client:
pwm_report = self.get_pwm() pwm_report = self.get_pwm()
for pwm_channel in pwm_report: for pwm_channel in pwm_report:
for limit in ["max_i_neg", "max_i_pos", "max_v"]: for limit in ["max_i_neg", "max_i_pos", "max_v"]:
if pwm_channel[limit] == 0.0: if pwm_channel[limit]["value"] == 0.0:
logging.warning("`{}` limit is set to zero on channel {}".format(limit, pwm_channel["channel"])) logging.warning("`{}` limit is set to zero on channel {}".format(limit, pwm_channel["channel"]))
def _read_line(self): def _read_line(self):
@ -52,16 +52,16 @@ class Client:
Example:: Example::
[{'channel': 0, [{'channel': 0,
'center': 'vref', 'center': 'vref',
'i_set': -0.02002179650216762, 'i_set': {'max': 2.9802790335151985, 'value': -0.02002179650216762},
'max_i_neg': 2.0, 'max_i_neg': {'max': 3.0, 'value': 3.0},
'max_v': 3.988, 'max_v': {'max': 5.988, 'value': 5.988},
'max_i_pos': 2.0, 'max_i_pos': {'max': 3.0, 'value': 3.0}},
{'channel': 1, {'channel': 1,
'center': 'vref', 'center': 'vref',
'i_set': -0.02002179650216762, 'i_set': {'max': 2.9802790335151985, 'value': -0.02002179650216762},
'max_i_neg': 2.0, 'max_i_neg': {'max': 3.0, 'value': 3.0},
'max_v': 3.988, 'max_v': {'max': 5.988, 'value': 5.988},
'max_i_pos': 2.0} 'max_i_pos': {'max': 3.0, 'value': 3.0}}
] ]
""" """
return self._get_conf("pwm") return self._get_conf("pwm")

View File

@ -361,16 +361,48 @@ impl Channels {
} }
} }
pub fn get_max_v(&mut self, channel: usize) -> ElectricPotential { fn get_pwm(&self, channel: usize, pin: PwmPin) -> f64 {
ElectricPotential::new::<volt>(self.channel_state(channel).pwm_limits.max_v) fn get<P: hal::PwmPin<Duty=u16>>(pin: &P) -> f64 {
let duty = pin.get_duty();
let max = pin.get_max_duty();
duty as f64 / (max as f64)
}
match (channel, pin) {
(_, PwmPin::ISet) =>
panic!("i_set is no pwm pin"),
(0, PwmPin::MaxIPos) =>
get(&self.pwm.max_i_pos0),
(0, PwmPin::MaxINeg) =>
get(&self.pwm.max_i_neg0),
(0, PwmPin::MaxV) =>
get(&self.pwm.max_v0),
(1, PwmPin::MaxIPos) =>
get(&self.pwm.max_i_pos1),
(1, PwmPin::MaxINeg) =>
get(&self.pwm.max_i_neg1),
(1, PwmPin::MaxV) =>
get(&self.pwm.max_v1),
_ =>
unreachable!(),
}
} }
pub fn get_max_i_pos(&mut self, channel: usize) -> ElectricCurrent { pub fn get_max_v(&mut self, channel: usize) -> (ElectricPotential, ElectricPotential) {
ElectricCurrent::new::<ampere>(self.channel_state(channel).pwm_limits.max_i_pos) let max = 4.0 * ElectricPotential::new::<volt>(3.3);
let duty = self.get_pwm(channel, PwmPin::MaxV);
(duty * max, ElectricPotential::new::<volt>(self.channel_state(channel).pwm_limits.max_v))
} }
pub fn get_max_i_neg(&mut self, channel: usize) -> ElectricCurrent { pub fn get_max_i_pos(&mut self, channel: usize) -> (ElectricCurrent, ElectricCurrent) {
ElectricCurrent::new::<ampere>(self.channel_state(channel).pwm_limits.max_i_neg) let max = ElectricCurrent::new::<ampere>(3.0);
let duty = self.get_pwm(channel, PwmPin::MaxIPos);
(duty * max, ElectricCurrent::new::<ampere>(self.channel_state(channel).pwm_limits.max_i_pos))
}
pub fn get_max_i_neg(&mut self, channel: usize) -> (ElectricCurrent, ElectricCurrent) {
let max = ElectricCurrent::new::<ampere>(3.0);
let duty = self.get_pwm(channel, PwmPin::MaxINeg);
(duty * max, ElectricCurrent::new::<ampere>(self.channel_state(channel).pwm_limits.max_i_neg))
} }
// Get current passing through TEC // Get current passing through TEC
@ -492,10 +524,10 @@ 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), i_set: (self.get_i(channel), self.channel_state(channel).i_set).into(),
max_v: self.get_max_v(channel), max_v: self.get_max_v(channel).into(),
max_i_pos: self.get_max_i_pos(channel), max_i_pos: self.get_max_i_pos(channel).into(),
max_i_neg: self.get_max_i_neg(channel), max_i_neg: self.get_max_i_neg(channel).into(),
} }
} }
@ -577,14 +609,26 @@ impl Serialize for CenterPointJson {
} }
} }
#[derive(Serialize)]
pub struct PwmSummaryField<T: Serialize> {
value: T,
set_value: T,
}
impl<T: Serialize> From<(T, T)> for PwmSummaryField<T> {
fn from((value, set_value): (T, T)) -> Self {
PwmSummaryField { value, set_value }
}
}
#[derive(Serialize)] #[derive(Serialize)]
pub struct PwmSummary { pub struct PwmSummary {
channel: usize, channel: usize,
center: CenterPointJson, center: CenterPointJson,
i_set: ElectricCurrent, i_set: PwmSummaryField<ElectricCurrent>,
max_v: ElectricPotential, max_v: PwmSummaryField<ElectricPotential>,
max_i_pos: ElectricCurrent, max_i_pos: PwmSummaryField<ElectricCurrent>,
max_i_neg: ElectricCurrent, max_i_neg: PwmSummaryField<ElectricCurrent>,
} }
#[derive(Serialize)] #[derive(Serialize)]

View File

@ -80,9 +80,9 @@ pub struct PwmLimits {
impl PwmLimits { impl PwmLimits {
pub fn new(channels: &mut Channels, channel: usize) -> Self { pub fn new(channels: &mut Channels, channel: usize) -> Self {
let max_v = channels.get_max_v(channel); let (_, max_v) = channels.get_max_v(channel);
let max_i_pos = channels.get_max_i_pos(channel); let (_, max_i_pos) = channels.get_max_i_pos(channel);
let max_i_neg = channels.get_max_i_neg(channel); let (_, max_i_neg) = channels.get_max_i_neg(channel);
PwmLimits { PwmLimits {
max_v: max_v.get::<volt>(), max_v: max_v.get::<volt>(),
max_i_pos: max_i_pos.get::<ampere>(), max_i_pos: max_i_pos.get::<ampere>(),