forked from M-Labs/thermostat
Compare commits
3 Commits
1741acfc3b
...
6b5c5340f8
Author | SHA1 | Date | |
---|---|---|---|
6b5c5340f8 | |||
37a8bde445 | |||
f02bf414b5 |
104
README.md
104
README.md
@ -94,42 +94,43 @@ The scope of this setting is per TCP session.
|
|||||||
Send commands as simple text string terminated by `\n`. Responses are
|
Send commands as simple text string terminated by `\n`. Responses are
|
||||||
formatted as line-delimited JSON.
|
formatted as line-delimited JSON.
|
||||||
|
|
||||||
| 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 <amp>` | Set maximum positive output current |
|
| `pwm <0/1> max_i_pos <amp>` | Set maximum positive output current |
|
||||||
| `pwm <0/1> max_i_neg <amp>` | Set maximum negative output current |
|
| `pwm <0/1> max_i_neg <amp>` | Set maximum negative output current |
|
||||||
| `pwm <0/1> max_v <volt>` | Set maximum output voltage |
|
| `pwm <0/1> max_v <volt>` | Set maximum output voltage |
|
||||||
| `pwm <0/1> i_set <amp>` | Disengage PID, set fixed output current |
|
| `pwm <0/1> i_set <amp>` | Disengage PID, set fixed output current |
|
||||||
| `pwm <0/1> pid` | Let output current to be controlled by the PID |
|
| `pwm <0/1> polarity_swapped <false/true>` | Swap output current polarity on channel |
|
||||||
| `center <0/1> <volt>` | Set the MAX1968 0A-centerpoint to the specified fixed voltage |
|
| `pwm <0/1> pid` | Let output current to be controlled by the PID |
|
||||||
| `center <0/1> vref` | Set the MAX1968 0A-centerpoint to measure from VREF |
|
| `center <0/1> <volt>` | Set the MAX1968 0A-centerpoint to the specified fixed voltage |
|
||||||
| `pid` | Show PID configuration |
|
| `center <0/1> vref` | Set the MAX1968 0A-centerpoint to measure from VREF |
|
||||||
| `pid <0/1> target <deg_celsius>` | Set the PID controller target temperature |
|
| `pid` | Show PID configuration |
|
||||||
| `pid <0/1> kp <value>` | Set proportional gain |
|
| `pid <0/1> target <deg_celsius>` | Set the PID controller target temperature |
|
||||||
| `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 <amp>` | Set mininum output |
|
| `pid <0/1> kd <value>` | Set differential gain |
|
||||||
| `pid <0/1> output_max <amp>` | Set maximum output |
|
| `pid <0/1> output_min <amp>` | Set mininum output |
|
||||||
| `s-h` | Show Steinhart-Hart equation parameters |
|
| `pid <0/1> output_max <amp>` | Set maximum output |
|
||||||
| `s-h <0/1> <t0/b/r0> <value>` | Set Steinhart-Hart parameter for a channel |
|
| `s-h` | Show Steinhart-Hart equation parameters |
|
||||||
| `postfilter` | Show postfilter settings |
|
| `s-h <0/1> <t0/b/r0> <value>` | Set Steinhart-Hart parameter for a channel |
|
||||||
| `postfilter <0/1> off` | Disable postfilter |
|
| `postfilter` | Show postfilter settings |
|
||||||
| `postfilter <0/1> rate <rate>` | Set postfilter output data rate |
|
| `postfilter <0/1> off` | Disable postfilter |
|
||||||
| `load [0/1]` | Restore configuration for channel all/0/1 from flash |
|
| `postfilter <0/1> rate <rate>` | Set postfilter output data rate |
|
||||||
| `save [0/1]` | Save configuration for channel all/0/1 to flash |
|
| `load [0/1]` | Restore configuration for channel all/0/1 from flash |
|
||||||
| `reset` | Reset the device |
|
| `save [0/1]` | Save configuration for channel all/0/1 to flash |
|
||||||
| `dfu` | Reset device and enters USB device firmware update (DFU) mode |
|
| `reset` | Reset the device |
|
||||||
| `ipv4 <X.X.X.X/L> [Y.Y.Y.Y]` | Configure IPv4 address, netmask length, and optional default gateway |
|
| `dfu` | Reset device and enters USB device firmware update (DFU) mode |
|
||||||
| `fan` | Show current fan settings and sensors' measurements |
|
| `ipv4 <X.X.X.X/L> [Y.Y.Y.Y]` | Configure IPv4 address, netmask length, and optional default gateway |
|
||||||
| `fan <value>` | Set fan power with values from 1 to 100 |
|
| `fan` | Show current fan settings and sensors' measurements |
|
||||||
| `fan auto` | Enable automatic fan speed control |
|
| `fan <value>` | Set fan power with values from 1 to 100 |
|
||||||
| `fcurve <a> <b> <c>` | Set fan controller curve coefficients (see *Fan control* section) |
|
| `fan auto` | Enable automatic fan speed control |
|
||||||
| `fcurve default` | Set fan controller curve coefficients to defaults (see *Fan control* section) |
|
| `fcurve <a> <b> <c>` | Set fan controller curve coefficients (see *Fan control* section) |
|
||||||
| `hwrev` | Show hardware revision, and settings related to it |
|
| `fcurve default` | Set fan controller curve coefficients to defaults (see *Fan control* section) |
|
||||||
|
| `hwrev` | Show hardware revision, and settings related to it |
|
||||||
|
|
||||||
|
|
||||||
## USB
|
## USB
|
||||||
@ -255,21 +256,22 @@ Use the bare `report` command to obtain a single report. Enable
|
|||||||
continuous reporting with `report mode on`. Reports are JSON objects
|
continuous reporting with `report mode on`. Reports are JSON objects
|
||||||
with the following keys.
|
with the following keys.
|
||||||
|
|
||||||
| Key | Unit | Description |
|
| Key | Unit | Description |
|
||||||
| --- | :---: | --- |
|
| --- | :---: | --- |
|
||||||
| `channel` | Integer | Channel `0`, or `1` |
|
| `channel` | Integer | Channel `0`, or `1` |
|
||||||
| `time` | Seconds | Temperature measurement time |
|
| `time` | Seconds | Temperature measurement time |
|
||||||
| `adc` | Volts | AD7172 input |
|
| `adc` | Volts | AD7172 input |
|
||||||
| `sens` | Ohms | Thermistor resistance derived from `adc` |
|
| `sens` | Ohms | Thermistor resistance derived from `adc` |
|
||||||
| `temperature` | Degrees Celsius | Steinhart-Hart conversion result derived from `sens` |
|
| `temperature` | Degrees Celsius | Steinhart-Hart conversion result derived from `sens` |
|
||||||
| `pid_engaged` | Boolean | `true` if in closed-loop mode |
|
| `pid_engaged` | Boolean | `true` if in closed-loop mode |
|
||||||
| `i_set` | Amperes | TEC output current |
|
| `current_swapped` | Boolean | `true` if TEC current direction is swapped relative to front panel |
|
||||||
| `dac_value` | Volts | AD5680 output derived from `i_set` |
|
| `i_set` | Amperes | TEC output current |
|
||||||
| `dac_feedback` | Volts | ADC measurement of the AD5680 output |
|
| `dac_value` | Volts | AD5680 output derived from `i_set` |
|
||||||
| `i_tec` | Volts | MAX1968 TEC current monitor |
|
| `dac_feedback` | Volts | ADC measurement of the AD5680 output |
|
||||||
| `tec_i` | Amperes | TEC output current feedback derived from `i_tec` |
|
| `i_tec` | Volts | MAX1968 TEC current monitor |
|
||||||
| `tec_u_meas` | Volts | Measurement of the voltage across the TEC |
|
| `tec_i` | Amperes | TEC output current feedback derived from `i_tec` |
|
||||||
| `pid_output` | Amperes | PID control output |
|
| `tec_u_meas` | Volts | Measurement of the voltage across the TEC |
|
||||||
|
| `pid_output` | Amperes | PID control output |
|
||||||
|
|
||||||
Note: With Thermostat v2 and below, the voltage and current readouts `i_tec` and `tec_i` are noisy without the hardware fix shown in [this PR][https://git.m-labs.hk/M-Labs/thermostat/pulls/105].
|
Note: With Thermostat v2 and below, the voltage and current readouts `i_tec` and `tec_i` are noisy without the hardware fix shown in [this PR][https://git.m-labs.hk/M-Labs/thermostat/pulls/105].
|
||||||
|
|
||||||
|
@ -35,6 +35,7 @@ pub struct ChannelState {
|
|||||||
pub pid_engaged: bool,
|
pub pid_engaged: bool,
|
||||||
pub pid: pid::Controller,
|
pub pid: pid::Controller,
|
||||||
pub sh: sh::Parameters,
|
pub sh: sh::Parameters,
|
||||||
|
pub polarity_swapped: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ChannelState {
|
impl ChannelState {
|
||||||
@ -51,6 +52,7 @@ impl ChannelState {
|
|||||||
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(),
|
||||||
|
polarity_swapped: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -158,6 +158,12 @@ impl Channels {
|
|||||||
|
|
||||||
pub fn set_i(&mut self, channel: usize, i_set: ElectricCurrent) -> ElectricCurrent {
|
pub fn set_i(&mut self, channel: usize, i_set: ElectricCurrent) -> ElectricCurrent {
|
||||||
let i_set = i_set.min(MAX_TEC_I).max(-MAX_TEC_I);
|
let i_set = i_set.min(MAX_TEC_I).max(-MAX_TEC_I);
|
||||||
|
self.channel_state(channel).i_set = i_set;
|
||||||
|
let negate = if self.channel_state(channel).polarity_swapped {
|
||||||
|
-1.0
|
||||||
|
} else {
|
||||||
|
1.0
|
||||||
|
};
|
||||||
let vref_meas = match channel.into() {
|
let vref_meas = match channel.into() {
|
||||||
0 => self.channel0.vref_meas,
|
0 => self.channel0.vref_meas,
|
||||||
1 => self.channel1.vref_meas,
|
1 => self.channel1.vref_meas,
|
||||||
@ -165,10 +171,9 @@ impl Channels {
|
|||||||
};
|
};
|
||||||
let center_point = vref_meas;
|
let center_point = vref_meas;
|
||||||
let r_sense = ElectricalResistance::new::<ohm>(R_SENSE);
|
let r_sense = ElectricalResistance::new::<ohm>(R_SENSE);
|
||||||
let voltage = i_set * 10.0 * r_sense + center_point;
|
let voltage = negate * i_set * 10.0 * r_sense + center_point;
|
||||||
let voltage = self.set_dac(channel, voltage);
|
let voltage = self.set_dac(channel, voltage);
|
||||||
let i_set = (voltage - center_point) / (10.0 * r_sense);
|
let i_set = negate * (voltage - center_point) / (10.0 * r_sense);
|
||||||
self.channel_state(channel).i_set = i_set;
|
|
||||||
i_set
|
i_set
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -386,18 +391,31 @@ impl Channels {
|
|||||||
}
|
}
|
||||||
|
|
||||||
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 duty = self.get_pwm(channel, PwmPin::MaxIPos);
|
let duty = if self.channel_state(channel).polarity_swapped {
|
||||||
|
self.get_pwm(channel, PwmPin::MaxINeg)
|
||||||
|
} else {
|
||||||
|
self.get_pwm(channel, PwmPin::MaxIPos)
|
||||||
|
};
|
||||||
(duty * MAX_TEC_I_DUTY_TO_CURRENT_RATE, MAX_TEC_I)
|
(duty * MAX_TEC_I_DUTY_TO_CURRENT_RATE, MAX_TEC_I)
|
||||||
}
|
}
|
||||||
|
|
||||||
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 duty = self.get_pwm(channel, PwmPin::MaxINeg);
|
let duty = if self.channel_state(channel).polarity_swapped {
|
||||||
|
self.get_pwm(channel, PwmPin::MaxIPos)
|
||||||
|
} else {
|
||||||
|
self.get_pwm(channel, PwmPin::MaxINeg)
|
||||||
|
};
|
||||||
(duty * MAX_TEC_I_DUTY_TO_CURRENT_RATE, MAX_TEC_I)
|
(duty * MAX_TEC_I_DUTY_TO_CURRENT_RATE, MAX_TEC_I)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get current passing through TEC
|
// Get current passing through TEC
|
||||||
pub fn get_tec_i(&mut self, channel: usize) -> ElectricCurrent {
|
pub fn get_tec_i(&mut self, channel: usize) -> ElectricCurrent {
|
||||||
(self.adc_read(channel, PinsAdcReadTarget::ITec, 16) - self.adc_read(channel, PinsAdcReadTarget::VREF, 16)) / ElectricalResistance::new::<ohm>(0.4)
|
let tec_i = (self.adc_read(channel, PinsAdcReadTarget::ITec, 16) - self.adc_read(channel, PinsAdcReadTarget::VREF, 16)) / ElectricalResistance::new::<ohm>(0.4);
|
||||||
|
if self.channel_state(channel).polarity_swapped {
|
||||||
|
-tec_i
|
||||||
|
} else {
|
||||||
|
tec_i
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get voltage across TEC
|
// Get voltage across TEC
|
||||||
@ -442,17 +460,38 @@ impl Channels {
|
|||||||
pub fn set_max_i_pos(&mut self, channel: usize, max_i_pos: ElectricCurrent) -> (ElectricCurrent, ElectricCurrent) {
|
pub fn set_max_i_pos(&mut self, channel: usize, max_i_pos: ElectricCurrent) -> (ElectricCurrent, ElectricCurrent) {
|
||||||
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_TEC_I_DUTY_TO_CURRENT_RATE).get::<ratio>();
|
let duty = (max_i_pos.min(MAX_TEC_I).max(ElectricCurrent::zero()) / MAX_TEC_I_DUTY_TO_CURRENT_RATE).get::<ratio>();
|
||||||
let duty = self.set_pwm(channel, PwmPin::MaxIPos, duty);
|
let duty = if self.channel_state(channel).polarity_swapped {
|
||||||
|
self.set_pwm(channel, PwmPin::MaxINeg, duty)
|
||||||
|
} else {
|
||||||
|
self.set_pwm(channel, PwmPin::MaxIPos, duty)
|
||||||
|
};
|
||||||
(duty * MAX_TEC_I_DUTY_TO_CURRENT_RATE, max)
|
(duty * MAX_TEC_I_DUTY_TO_CURRENT_RATE, max)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_max_i_neg(&mut self, channel: usize, max_i_neg: ElectricCurrent) -> (ElectricCurrent, ElectricCurrent) {
|
pub fn set_max_i_neg(&mut self, channel: usize, max_i_neg: ElectricCurrent) -> (ElectricCurrent, ElectricCurrent) {
|
||||||
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_TEC_I_DUTY_TO_CURRENT_RATE).get::<ratio>();
|
let duty = (max_i_neg.min(MAX_TEC_I).max(ElectricCurrent::zero()) / MAX_TEC_I_DUTY_TO_CURRENT_RATE).get::<ratio>();
|
||||||
let duty = self.set_pwm(channel, PwmPin::MaxINeg, duty);
|
let duty = if self.channel_state(channel).polarity_swapped {
|
||||||
|
self.set_pwm(channel, PwmPin::MaxIPos, duty)
|
||||||
|
} else {
|
||||||
|
self.set_pwm(channel, PwmPin::MaxINeg, duty)
|
||||||
|
};
|
||||||
(duty * MAX_TEC_I_DUTY_TO_CURRENT_RATE, max)
|
(duty * MAX_TEC_I_DUTY_TO_CURRENT_RATE, max)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn swap_polarity(&mut self, channel: usize, swapped: bool) {
|
||||||
|
if self.channel_state(channel).polarity_swapped != swapped {
|
||||||
|
let i_set = self.channel_state(channel).i_set;
|
||||||
|
let max_i_pos = self.get_max_i_pos(channel).0;
|
||||||
|
let max_i_neg = self.get_max_i_neg(channel).0;
|
||||||
|
|
||||||
|
self.channel_state(channel).polarity_swapped = swapped;
|
||||||
|
self.set_i(channel, i_set);
|
||||||
|
self.set_max_i_pos(channel, max_i_pos);
|
||||||
|
self.set_max_i_neg(channel, max_i_neg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
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.get_i(channel);
|
||||||
let i_tec = self.adc_read(channel, PinsAdcReadTarget::ITec, 16);
|
let i_tec = self.adc_read(channel, PinsAdcReadTarget::ITec, 16);
|
||||||
@ -469,6 +508,7 @@ impl Channels {
|
|||||||
temperature: state.get_temperature()
|
temperature: state.get_temperature()
|
||||||
.map(|temperature| temperature.get::<degree_celsius>()),
|
.map(|temperature| temperature.get::<degree_celsius>()),
|
||||||
pid_engaged: state.pid_engaged,
|
pid_engaged: state.pid_engaged,
|
||||||
|
current_swapped: state.polarity_swapped,
|
||||||
i_set,
|
i_set,
|
||||||
dac_value,
|
dac_value,
|
||||||
dac_feedback: self.adc_read(channel, PinsAdcReadTarget::DacVfb, 1),
|
dac_feedback: self.adc_read(channel, PinsAdcReadTarget::DacVfb, 1),
|
||||||
@ -567,6 +607,7 @@ pub struct Report {
|
|||||||
sens: Option<ElectricalResistance>,
|
sens: Option<ElectricalResistance>,
|
||||||
temperature: Option<f64>,
|
temperature: Option<f64>,
|
||||||
pid_engaged: bool,
|
pid_engaged: bool,
|
||||||
|
current_swapped: bool,
|
||||||
i_set: ElectricCurrent,
|
i_set: ElectricCurrent,
|
||||||
dac_value: ElectricPotential,
|
dac_value: ElectricPotential,
|
||||||
dac_feedback: ElectricPotential,
|
dac_feedback: ElectricPotential,
|
||||||
|
@ -181,6 +181,12 @@ impl Handler {
|
|||||||
Ok(Handler::Handled)
|
Ok(Handler::Handled)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn swap_polarity (socket: &mut TcpSocket, channels: &mut Channels, channel: usize, swapped: bool) -> Result<Handler, Error> {
|
||||||
|
channels.swap_polarity(channel, swapped);
|
||||||
|
send_line(socket, b"{}");
|
||||||
|
Ok(Handler::Handled)
|
||||||
|
}
|
||||||
|
|
||||||
fn set_pwm (socket: &mut TcpSocket, channels: &mut Channels, channel: usize, pin: PwmPin, value: f64) -> Result<Handler, Error> {
|
fn set_pwm (socket: &mut TcpSocket, channels: &mut Channels, channel: usize, pin: PwmPin, value: f64) -> Result<Handler, Error> {
|
||||||
match pin {
|
match pin {
|
||||||
PwmPin::ISet => {
|
PwmPin::ISet => {
|
||||||
@ -424,6 +430,7 @@ impl Handler {
|
|||||||
Command::Show(ShowCommand::PostFilter) => Handler::show_post_filter(socket, channels),
|
Command::Show(ShowCommand::PostFilter) => Handler::show_post_filter(socket, channels),
|
||||||
Command::Show(ShowCommand::Ipv4) => Handler::show_ipv4(socket, ipv4_config),
|
Command::Show(ShowCommand::Ipv4) => Handler::show_ipv4(socket, ipv4_config),
|
||||||
Command::PwmPid { channel } => Handler::engage_pid(socket, channels, channel),
|
Command::PwmPid { channel } => Handler::engage_pid(socket, channels, channel),
|
||||||
|
Command::PwmPolaritySwapped { channel, swapped } => Handler::swap_polarity(socket, channels, channel, swapped),
|
||||||
Command::Pwm { channel, pin, value } => Handler::set_pwm(socket, channels, channel, pin, value),
|
Command::Pwm { channel, pin, value } => Handler::set_pwm(socket, channels, channel, pin, value),
|
||||||
Command::CenterPoint { channel, center } => Handler::set_center_point(socket, channels, channel, center),
|
Command::CenterPoint { channel, center } => Handler::set_center_point(socket, channels, channel, center),
|
||||||
Command::Pid { channel, parameter, value } => Handler::set_pid(socket, channels, channel, parameter, value),
|
Command::Pid { channel, parameter, value } => Handler::set_pid(socket, channels, channel, parameter, value),
|
||||||
|
@ -159,6 +159,10 @@ pub enum Command {
|
|||||||
PwmPid {
|
PwmPid {
|
||||||
channel: usize,
|
channel: usize,
|
||||||
},
|
},
|
||||||
|
PwmPolaritySwapped {
|
||||||
|
channel: usize,
|
||||||
|
swapped: bool,
|
||||||
|
},
|
||||||
CenterPoint {
|
CenterPoint {
|
||||||
channel: usize,
|
channel: usize,
|
||||||
center: CenterPoint,
|
center: CenterPoint,
|
||||||
@ -239,6 +243,12 @@ fn off_on(input: &[u8]) -> IResult<&[u8], bool> {
|
|||||||
))(input)
|
))(input)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn boolean(input: &[u8]) -> IResult<&[u8], bool> {
|
||||||
|
alt((value(false, tag("false")),
|
||||||
|
value(true, tag("true"))
|
||||||
|
))(input)
|
||||||
|
}
|
||||||
|
|
||||||
fn channel(input: &[u8]) -> IResult<&[u8], usize> {
|
fn channel(input: &[u8]) -> IResult<&[u8], usize> {
|
||||||
map(one_of("01"), |c| (c as usize) - ('0' as usize))(input)
|
map(one_of("01"), |c| (c as usize) - ('0' as usize))(input)
|
||||||
}
|
}
|
||||||
@ -321,6 +331,16 @@ fn pwm_pid(input: &[u8]) -> IResult<&[u8], ()> {
|
|||||||
value((), tag("pid"))(input)
|
value((), tag("pid"))(input)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn pwm_polarity_swapped(input: &[u8]) -> IResult<&[u8], bool> {
|
||||||
|
preceded(
|
||||||
|
tag("polarity_swapped"),
|
||||||
|
preceded(
|
||||||
|
whitespace,
|
||||||
|
boolean,
|
||||||
|
)
|
||||||
|
)(input)
|
||||||
|
}
|
||||||
|
|
||||||
fn pwm(input: &[u8]) -> IResult<&[u8], Result<Command, Error>> {
|
fn pwm(input: &[u8]) -> IResult<&[u8], Result<Command, Error>> {
|
||||||
let (input, _) = tag("pwm")(input)?;
|
let (input, _) = tag("pwm")(input)?;
|
||||||
alt((
|
alt((
|
||||||
@ -333,6 +353,10 @@ fn pwm(input: &[u8]) -> IResult<&[u8], Result<Command, Error>> {
|
|||||||
let (input, ()) = pwm_pid(input)?;
|
let (input, ()) = pwm_pid(input)?;
|
||||||
Ok((input, Ok(Command::PwmPid { channel })))
|
Ok((input, Ok(Command::PwmPid { channel })))
|
||||||
},
|
},
|
||||||
|
|input| {
|
||||||
|
let (input, swapped) = pwm_polarity_swapped(input)?;
|
||||||
|
Ok((input, Ok(Command::PwmPolaritySwapped { channel, swapped })))
|
||||||
|
},
|
||||||
|input| {
|
|input| {
|
||||||
let (input, config) = pwm_setup(input)?;
|
let (input, config) = pwm_setup(input)?;
|
||||||
match config {
|
match config {
|
||||||
|
@ -20,6 +20,7 @@ pub struct ChannelConfig {
|
|||||||
pid_target: f32,
|
pid_target: f32,
|
||||||
pid_engaged: bool,
|
pid_engaged: bool,
|
||||||
i_set: ElectricCurrent,
|
i_set: ElectricCurrent,
|
||||||
|
polarity_swapped: bool,
|
||||||
sh: steinhart_hart::Parameters,
|
sh: steinhart_hart::Parameters,
|
||||||
pwm: PwmLimits,
|
pwm: PwmLimits,
|
||||||
/// uses variant `PostFilter::Invalid` instead of `None` to save space
|
/// uses variant `PostFilter::Invalid` instead of `None` to save space
|
||||||
@ -45,7 +46,8 @@ impl ChannelConfig {
|
|||||||
pid: state.pid.parameters.clone(),
|
pid: state.pid.parameters.clone(),
|
||||||
pid_target: state.pid.target as f32,
|
pid_target: state.pid.target as f32,
|
||||||
pid_engaged: state.pid_engaged,
|
pid_engaged: state.pid_engaged,
|
||||||
i_set: i_set,
|
i_set,
|
||||||
|
polarity_swapped: state.polarity_swapped,
|
||||||
sh: state.sh.clone(),
|
sh: state.sh.clone(),
|
||||||
pwm,
|
pwm,
|
||||||
adc_postfilter,
|
adc_postfilter,
|
||||||
@ -68,6 +70,7 @@ impl ChannelConfig {
|
|||||||
};
|
};
|
||||||
let _ = channels.adc.set_postfilter(channel as u8, adc_postfilter);
|
let _ = channels.adc.set_postfilter(channel as u8, adc_postfilter);
|
||||||
let _ = channels.set_i(channel, self.i_set);
|
let _ = channels.set_i(channel, self.i_set);
|
||||||
|
channels.swap_polarity(channel, self.polarity_swapped);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user