calculate i_set current

This commit is contained in:
Astro 2020-09-16 22:22:48 +02:00
parent 8c80062da8
commit fc0ca8b581
3 changed files with 46 additions and 8 deletions

View File

@ -55,7 +55,7 @@ The scope of this setting is per TCP session.
| `pwm <0/1> max_i_pos <ratio>` | Set PWM duty cycle for **max_i_pos** to *ampere* | | `pwm <0/1> max_i_pos <ratio>` | Set PWM duty cycle for **max_i_pos** to *ampere* |
| `pwm <0/1> max_i_neg <ratio>` | Set PWM duty cycle for **max_i_neg** to *ampere* | | `pwm <0/1> max_i_neg <ratio>` | Set PWM duty cycle for **max_i_neg** to *ampere* |
| `pwm <0/1> max_v <ratio>` | Set PWM duty cycle for **max_v** to *volt* | | `pwm <0/1> max_v <ratio>` | Set PWM duty cycle for **max_v** to *volt* |
| `pwm <0/1> <volts>` | Disengage PID, set **i_set** DAC to *volts* | | `pwm <0/1> <volts>` | Disengage PID, set **i_set** DAC to *ampere* |
| `pwm <0/1> pid` | Set PWM to be controlled by PID | | `pwm <0/1> pid` | Set PWM to be controlled by PID |
| `pid` | Show PID configuration | | `pid` | Show PID configuration |
| `pid <0/1> target <value>` | Set the PID controller target | | `pid <0/1> target <value>` | Set the PID controller target |

View File

@ -1,9 +1,10 @@
use stm32f4xx_hal::hal; use stm32f4xx_hal::hal;
use smoltcp::time::Instant; use smoltcp::time::Instant;
use uom::si::{ use uom::si::{
f64::{ElectricCurrent, ElectricPotential}, f64::{ElectricCurrent, ElectricPotential, ElectricalResistance},
electric_potential::{millivolt, volt}, electric_potential::{millivolt, volt},
electric_current::ampere, electric_current::ampere,
electrical_resistance::ohm,
ratio::ratio, ratio::ratio,
}; };
use log::info; use log::info;
@ -17,6 +18,7 @@ use crate::{
}; };
pub const CHANNELS: usize = 2; pub const CHANNELS: usize = 2;
pub const R_SENSE: f64 = 0.05;
// TODO: -pub // TODO: -pub
pub struct Channels { pub struct Channels {
@ -91,7 +93,28 @@ impl Channels {
} }
/// i_set DAC /// i_set DAC
pub fn set_dac(&mut self, channel: usize, voltage: ElectricPotential) -> (ElectricPotential, ElectricPotential) { fn get_dac(&mut self, channel: usize) -> (ElectricPotential, ElectricPotential) {
let dac_factor = match channel.into() {
0 => self.channel0.dac_factor,
1 => self.channel1.dac_factor,
_ => unreachable!(),
};
let voltage = self.channel_state(channel).dac_value;
let max = ElectricPotential::new::<volt>(ad5680::MAX_VALUE as f64 / dac_factor);
(voltage, max)
}
pub fn get_i(&mut self, channel: usize) -> (ElectricCurrent, ElectricCurrent) {
let vref = self.channel_state(channel).vref;
let r_sense = ElectricalResistance::new::<ohm>(R_SENSE);
let (voltage, max) = self.get_dac(channel);
let i_tec = (voltage - vref) / (10.0 * r_sense);
let max = (max - vref) / (10.0 * r_sense);
(i_tec, max)
}
/// i_set DAC
fn set_dac(&mut self, channel: usize, voltage: ElectricPotential) -> (ElectricPotential, ElectricPotential) {
let dac_factor = match channel.into() { let dac_factor = match channel.into() {
0 => self.channel0.dac_factor, 0 => self.channel0.dac_factor,
1 => self.channel1.dac_factor, 1 => self.channel1.dac_factor,
@ -109,6 +132,16 @@ impl Channels {
(voltage, max) (voltage, max)
} }
pub fn set_i(&mut self, channel: usize, i_tec: ElectricCurrent) -> (ElectricCurrent, ElectricCurrent) {
let vref = self.channel_state(channel).vref;
let r_sense = ElectricalResistance::new::<ohm>(R_SENSE);
let voltage = i_tec * 10.0 * r_sense + vref;
let (voltage, max) = self.set_dac(channel, voltage);
let i_tec = (voltage - vref) / (10.0 * r_sense);
let max = (max - vref) / (10.0 * r_sense);
(i_tec, max)
}
pub fn read_dac_feedback(&mut self, channel: usize) -> ElectricPotential { pub fn read_dac_feedback(&mut self, channel: usize) -> ElectricPotential {
match channel { match channel {
0 => { 0 => {

View File

@ -229,7 +229,12 @@ fn main() -> ! {
channel, channel,
if state.pid_engaged { "engaged" } else { "disengaged" } if state.pid_engaged { "engaged" } else { "disengaged" }
); );
let _ = writeln!(socket, "- i_set={:.3}", state.dac_value.into_format_args(volt, Abbreviation)); let i_set = channels.get_i(channel);
let _ = writeln!(
socket, "- i_set={:.3} / {:.3}",
i_set.0.into_format_args(ampere, Abbreviation),
i_set.1.into_format_args(ampere, Abbreviation),
);
let max_v = channels.get_max_v(channel); let max_v = channels.get_max_v(channel);
let _ = writeln!( let _ = writeln!(
socket, "- max_v={:.3} / {:.3}", socket, "- max_v={:.3} / {:.3}",
@ -302,13 +307,13 @@ fn main() -> ! {
Command::Pwm { channel, pin: PwmPin::ISet, value } => { Command::Pwm { channel, pin: PwmPin::ISet, value } => {
channels.channel_state(channel).pid_engaged = false; channels.channel_state(channel).pid_engaged = false;
leds.g3.off(); leds.g3.off();
let voltage = ElectricPotential::new::<volt>(value); let current = ElectricCurrent::new::<ampere>(value);
let (voltage, max) = channels.set_dac(channel, voltage); let (current, max) = channels.set_i(channel, current);
let _ = writeln!( let _ = writeln!(
socket, "channel {}: i_set DAC output set to {:.3} / {:.3}", socket, "channel {}: i_set DAC output set to {:.3} / {:.3}",
channel, channel,
voltage.into_format_args(volt, Abbreviation), current.into_format_args(ampere, Abbreviation),
max.into_format_args(volt, Abbreviation), max.into_format_args(ampere, Abbreviation),
); );
} }
Command::Pwm { channel, pin, value } => { Command::Pwm { channel, pin, value } => {