Compare commits

..

No commits in common. "a84242fb1fa46b48641389ee2ffd7a40d00d2b03" and "b9902929a9b9edbb79662689f2e2a2406c30f58e" have entirely different histories.

5 changed files with 55 additions and 149 deletions

View File

@ -46,28 +46,26 @@ The scope of this setting is per TCP session.
### Commands ### Commands
| Syntax | Function | | Syntax | Function |
| --- | --- | | --- | --- |
| `report` | Show current input | | `report` | Show current input |
| `report mode` | Show current report mode | | `report mode` | Show current report mode |
| `report mode <off/on>` | Set report mode | | `report mode <off/on>` | Set report mode |
| `pwm` | Show current PWM settings | | `pwm` | Show current PWM settings |
| `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 *ampere* | | `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 |
| `center <0/1> <volts>` | Set the MAX1968 0A-centerpoint to *volts* | | `pid` | Show PID configuration |
| `center <0/1> vref` | Set the MAX1968 0A-centerpoint to measure from VREF | | `pid <0/1> target <value>` | Set the PID controller target |
| `pid` | Show PID configuration | | `pid <0/1> kp <value>` | Set proportional gain |
| `pid <0/1> target <value>` | Set the PID controller target | | `pid <0/1> ki <value>` | Set integral gain |
| `pid <0/1> kp <value>` | Set proportional gain | | `pid <0/1> kd <value>` | Set differential gain |
| `pid <0/1> ki <value>` | Set integral gain | | `pid <0/1> output_min <value>` | Set mininum output |
| `pid <0/1> kd <value>` | Set differential gain | | `pid <0/1> output_max <value>` | Set maximum output |
| `pid <0/1> output_min <value>` | Set mininum output | | `pid <0/1> integral_min <value>` | Set integral lower bound |
| `pid <0/1> output_max <value>` | Set maximum output | | `pid <0/1> integral_max <value>` | Set integral upper bound |
| `pid <0/1> integral_min <value>` | Set integral lower bound | | `s-h` | Show Steinhart-Hart equation parameters |
| `pid <0/1> integral_max <value>` | Set integral upper bound | | `s-h <0/1> <t/b/r0> <value>` | Set Steinhart-Hart parameter for a channel |
| `s-h` | Show Steinhart-Hart equation parameters | | `postfilter <0/1> rate <rate>` | Set postfilter output data rate |
| `s-h <0/1> <t/b/r0> <value>` | Set Steinhart-Hart parameter for a channel |
| `postfilter <0/1> rate <rate>` | Set postfilter output data rate |

View File

@ -13,7 +13,6 @@ use crate::{
ad7172, ad7172,
pid, pid,
steinhart_hart as sh, steinhart_hart as sh,
command_parser::CenterPoint,
}; };
const R_INNER: f64 = 2.0 * 5100.0; const R_INNER: f64 = 2.0 * 5100.0;
@ -25,8 +24,6 @@ pub struct ChannelState {
pub adc_time: Instant, pub adc_time: Instant,
/// VREF for the TEC (1.5V) /// VREF for the TEC (1.5V)
pub vref: ElectricPotential, pub vref: ElectricPotential,
/// i_set 0A center point
pub center: CenterPoint,
pub dac_value: ElectricPotential, pub dac_value: ElectricPotential,
pub pid_engaged: bool, pub pid_engaged: bool,
pub pid: pid::Controller, pub pid: pid::Controller,
@ -39,9 +36,8 @@ impl ChannelState {
adc_data: None, adc_data: None,
adc_calibration, adc_calibration,
adc_time: Instant::from_secs(0), adc_time: Instant::from_secs(0),
// updated later with Channels.read_vref() // can be initialized later with Channels.read_vref()
vref: ElectricPotential::new::<volt>(1.5), vref: ElectricPotential::new::<volt>(3.3 / 2.0),
center: CenterPoint::Vref,
dac_value: ElectricPotential::new::<volt>(0.0), dac_value: ElectricPotential::new::<volt>(0.0),
pid_engaged: false, pid_engaged: false,
pid: pid::Controller::new(pid::Parameters::default()), pid: pid::Controller::new(pid::Parameters::default()),

View File

@ -13,7 +13,7 @@ use crate::{
ad7172, ad7172,
channel::{Channel, Channel0, Channel1}, channel::{Channel, Channel0, Channel1},
channel_state::ChannelState, channel_state::ChannelState,
command_parser::{CenterPoint, PwmPin}, command_parser::PwmPin,
pins, pins,
}; };
@ -99,17 +99,11 @@ impl Channels {
} }
pub fn get_i(&mut self, channel: usize) -> (ElectricCurrent, ElectricCurrent) { pub fn get_i(&mut self, channel: usize) -> (ElectricCurrent, ElectricCurrent) {
let state = self.channel_state(channel); let vref = self.channel_state(channel).vref;
let center_point = match state.center {
CenterPoint::Vref =>
state.vref,
CenterPoint::Override(center_point) =>
ElectricPotential::new::<volt>(center_point),
};
let r_sense = ElectricalResistance::new::<ohm>(R_SENSE); let r_sense = ElectricalResistance::new::<ohm>(R_SENSE);
let (voltage, max) = self.get_dac(channel); let (voltage, max) = self.get_dac(channel);
let i_tec = (voltage - center_point) / (10.0 * r_sense); let i_tec = (voltage - vref) / (10.0 * r_sense);
let max = (max - center_point) / (10.0 * r_sense); let max = (max - vref) / (10.0 * r_sense);
(i_tec, max) (i_tec, max)
} }
@ -133,18 +127,12 @@ impl Channels {
} }
pub fn set_i(&mut self, channel: usize, i_tec: ElectricCurrent) -> (ElectricCurrent, ElectricCurrent) { pub fn set_i(&mut self, channel: usize, i_tec: ElectricCurrent) -> (ElectricCurrent, ElectricCurrent) {
let state = self.channel_state(channel); let vref = self.channel_state(channel).vref;
let center_point = match state.center {
CenterPoint::Vref =>
state.vref,
CenterPoint::Override(center_point) =>
ElectricPotential::new::<volt>(center_point),
};
let r_sense = ElectricalResistance::new::<ohm>(R_SENSE); let r_sense = ElectricalResistance::new::<ohm>(R_SENSE);
let voltage = i_tec * 10.0 * r_sense + center_point; let voltage = i_tec * 10.0 * r_sense + vref;
let (voltage, max) = self.set_dac(channel, voltage); let (voltage, max) = self.set_dac(channel, voltage);
let i_tec = (voltage - center_point) / (10.0 * r_sense); let i_tec = (voltage - vref) / (10.0 * r_sense);
let max = (max - center_point) / (10.0 * r_sense); let max = (max - vref) / (10.0 * r_sense);
(i_tec, max) (i_tec, max)
} }

View File

@ -122,12 +122,6 @@ pub enum PwmPin {
MaxV, MaxV,
} }
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum CenterPoint {
Vref,
Override(f64),
}
#[derive(Debug, Clone, PartialEq)] #[derive(Debug, Clone, PartialEq)]
pub enum Command { pub enum Command {
Quit, Quit,
@ -143,10 +137,6 @@ pub enum Command {
PwmPid { PwmPid {
channel: usize, channel: usize,
}, },
CenterPoint {
channel: usize,
center: CenterPoint,
},
/// PID parameter setting /// PID parameter setting
Pid { Pid {
channel: usize, channel: usize,
@ -300,25 +290,6 @@ fn pwm(input: &[u8]) -> IResult<&[u8], Result<Command, Error>> {
))(input) ))(input)
} }
fn center_point(input: &[u8]) -> IResult<&[u8], Result<Command, Error>> {
let (input, _) = tag("center")(input)?;
let (input, _) = whitespace(input)?;
let (input, channel) = channel(input)?;
let (input, _) = whitespace(input)?;
let (input, center) = alt((
value(Ok(CenterPoint::Vref), tag("vref")),
|input| {
let (input, value) = float(input)?;
Ok((input, value.map(CenterPoint::Override)))
}
))(input)?;
end(input)?;
Ok((input, center.map(|center| Command::CenterPoint {
channel,
center,
})))
}
/// `pid <0-1> <parameter> <value>` /// `pid <0-1> <parameter> <value>`
fn pid_parameter(input: &[u8]) -> IResult<&[u8], Result<Command, Error>> { fn pid_parameter(input: &[u8]) -> IResult<&[u8], Result<Command, Error>> {
let (input, channel) = channel(input)?; let (input, channel) = channel(input)?;
@ -407,7 +378,6 @@ fn command(input: &[u8]) -> IResult<&[u8], Result<Command, Error>> {
alt((value(Ok(Command::Quit), tag("quit")), alt((value(Ok(Command::Quit), tag("quit")),
map(report, Ok), map(report, Ok),
pwm, pwm,
center_point,
pid, pid,
steinhart_hart, steinhart_hart,
postfilter, postfilter,
@ -559,22 +529,4 @@ mod test {
rate: 21.0, rate: 21.0,
})); }));
} }
#[test]
fn parse_center_point() {
let command = Command::parse(b"center 0 1.5");
assert_eq!(command, Ok(Command::CenterPoint {
channel: 0,
center: CenterPoint::Override(1.5),
}));
}
#[test]
fn parse_center_point_vref() {
let command = Command::parse(b"center 1 vref");
assert_eq!(command, Ok(Command::CenterPoint {
channel: 1,
center: CenterPoint::Vref,
}));
}
} }

View File

@ -55,7 +55,7 @@ use server::Server;
mod session; mod session;
use session::{Session, SessionOutput}; use session::{Session, SessionOutput};
mod command_parser; mod command_parser;
use command_parser::{CenterPoint, Command, ShowCommand, PwmPin}; use command_parser::{Command, ShowCommand, PwmPin};
mod timer; mod timer;
mod pid; mod pid;
mod steinhart_hart; mod steinhart_hart;
@ -221,32 +221,18 @@ fn main() -> ! {
} }
Command::Show(ShowCommand::Pwm) => { Command::Show(ShowCommand::Pwm) => {
for channel in 0..CHANNELS { for channel in 0..CHANNELS {
let i_set = channels.get_i(channel);
let state = channels.channel_state(channel); let state = channels.channel_state(channel);
let _ = writeln!( let _ = writeln!(
socket, "channel {}: PID={}", socket, "channel {}: PID={}",
channel, channel,
if state.pid_engaged { "engaged" } else { "disengaged" } if state.pid_engaged { "engaged" } else { "disengaged" }
); );
let _ = write!( let i_set = channels.get_i(channel);
socket, "- i_set={:.3} / {:.3} ", let _ = writeln!(
socket, "- i_set={:.3} / {:.3}",
i_set.0.into_format_args(ampere, Abbreviation), i_set.0.into_format_args(ampere, Abbreviation),
i_set.1.into_format_args(ampere, Abbreviation), i_set.1.into_format_args(ampere, Abbreviation),
); );
match state.center {
CenterPoint::Vref => {
let _ = writeln!(
socket, "center=vref vref={:.3}",
state.vref.into_format_args(volt, Abbreviation),
);
}
CenterPoint::Override(volts) => {
let _ = writeln!(
socket, "center={:.3} V",
volts,
);
}
}
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}",
@ -317,25 +303,28 @@ fn main() -> ! {
let _ = writeln!(socket, "channel {}: PID enabled to control PWM", channel let _ = writeln!(socket, "channel {}: PID enabled to control PWM", channel
); );
} }
Command::Pwm { channel, pin: PwmPin::ISet, value } => {
channels.channel_state(channel).pid_engaged = false;
leds.g3.off();
let current = ElectricCurrent::new::<ampere>(value);
let (current, max) = channels.set_i(channel, current);
let _ = writeln!(
socket, "channel {}: i_set DAC output set to {:.3} / {:.3}",
channel,
current.into_format_args(ampere, Abbreviation),
max.into_format_args(ampere, Abbreviation),
);
}
Command::Pwm { channel, pin, value } => { Command::Pwm { channel, pin, value } => {
match pin { match pin {
PwmPin::ISet => { PwmPin::ISet =>
channels.channel_state(channel).pid_engaged = false; // Handled above
leds.g3.off(); unreachable!(),
let current = ElectricCurrent::new::<ampere>(value);
let (current, max) = channels.set_i(channel, current);
let _ = writeln!(
socket, "channel {}: i_set DAC output set to {:.3} / {:.3}",
channel,
current.into_format_args(ampere, Abbreviation),
max.into_format_args(ampere, Abbreviation),
);
}
PwmPin::MaxV => { PwmPin::MaxV => {
let voltage = ElectricPotential::new::<volt>(value); let voltage = ElectricPotential::new::<volt>(value);
let (voltage, max) = channels.set_max_v(channel, voltage); let (voltage, max) = channels.set_max_v(channel, voltage);
let _ = writeln!( let _ = writeln!(
socket, "channel {}: max_v set to {:.3} / {:.3}", socket, "channel {:.3}: max_v set to {:.3} / {:.3}",
channel, channel,
voltage.into_format_args(volt, Abbreviation), voltage.into_format_args(volt, Abbreviation),
max.into_format_args(volt, Abbreviation), max.into_format_args(volt, Abbreviation),
@ -345,7 +334,7 @@ fn main() -> ! {
let current = ElectricCurrent::new::<ampere>(value); let current = ElectricCurrent::new::<ampere>(value);
let (current, max) = channels.set_max_i_pos(channel, current); let (current, max) = channels.set_max_i_pos(channel, current);
let _ = writeln!( let _ = writeln!(
socket, "channel {}: max_i_pos set to {:.3} / {:.3}", socket, "channel {:.3}: max_i_pos set to {:.3} / {:.3}",
channel, channel,
current.into_format_args(ampere, Abbreviation), current.into_format_args(ampere, Abbreviation),
max.into_format_args(ampere, Abbreviation), max.into_format_args(ampere, Abbreviation),
@ -355,7 +344,7 @@ fn main() -> ! {
let current = ElectricCurrent::new::<ampere>(value); let current = ElectricCurrent::new::<ampere>(value);
let (current, max) = channels.set_max_i_neg(channel, current); let (current, max) = channels.set_max_i_neg(channel, current);
let _ = writeln!( let _ = writeln!(
socket, "channel {}: max_i_neg set to {:.3} / {:.3}", socket, "channel {:.3}: max_i_neg set to {:.3} / {:.3}",
channel, channel,
current.into_format_args(ampere, Abbreviation), current.into_format_args(ampere, Abbreviation),
max.into_format_args(ampere, Abbreviation), max.into_format_args(ampere, Abbreviation),
@ -363,23 +352,6 @@ fn main() -> ! {
} }
} }
} }
Command::CenterPoint { channel, center } => {
let (i_tec, _) = channels.get_i(channel);
let state = channels.channel_state(channel);
state.center = center;
if !state.pid_engaged {
channels.set_i(channel, i_tec);
let _ = writeln!(
socket, "channel {}: center point updated, output readjusted for {:.3}",
channel, i_tec.into_format_args(ampere, Abbreviation),
);
} else {
let _ = writeln!(
socket, "channel {}: center point updated",
channel,
);
}
}
Command::Pid { channel, parameter, value } => { Command::Pid { channel, parameter, value } => {
let pid = &mut channels.channel_state(channel).pid; let pid = &mut channels.channel_state(channel).pid;
use command_parser::PidParameter::*; use command_parser::PidParameter::*;