forked from M-Labs/thermostat
reconnect the pid controller
This commit is contained in:
parent
fb81380955
commit
ba84295ec5
|
@ -7,7 +7,7 @@ use uom::si::{
|
||||||
},
|
},
|
||||||
electric_potential::volt,
|
electric_potential::volt,
|
||||||
electrical_resistance::ohm,
|
electrical_resistance::ohm,
|
||||||
temperature_interval::kelvin,
|
thermodynamic_temperature::degree_celsius,
|
||||||
};
|
};
|
||||||
use crate::{
|
use crate::{
|
||||||
ad7172,
|
ad7172,
|
||||||
|
@ -51,10 +51,11 @@ impl ChannelState {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Update PID state on ADC input, calculate new DAC output
|
/// Update PID state on ADC input, calculate new DAC output
|
||||||
pub fn update_pid(&mut self) {
|
pub fn update_pid(&mut self) -> Option<f64> {
|
||||||
// Update PID controller
|
let temperature = self.get_temperature()?
|
||||||
// self.pid.update(self.get_temperature().unwrap().get::<kelvin>())
|
.get::<degree_celsius>();
|
||||||
// TODO: add output field
|
let pid_output = self.pid.update(temperature);
|
||||||
|
Some(pid_output)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_adc(&self) -> Option<ElectricPotential> {
|
pub fn get_adc(&self) -> Option<ElectricPotential> {
|
||||||
|
|
|
@ -70,21 +70,16 @@ impl Channels {
|
||||||
self.adc.data_ready().unwrap().map(|channel| {
|
self.adc.data_ready().unwrap().map(|channel| {
|
||||||
let data = self.adc.read_data().unwrap();
|
let data = self.adc.read_data().unwrap();
|
||||||
|
|
||||||
let dac_value = {
|
|
||||||
let state = self.channel_state(channel);
|
let state = self.channel_state(channel);
|
||||||
state.update(instant, data);
|
|
||||||
let pid_output = state.update_pid();
|
|
||||||
|
|
||||||
if state.pid_engaged {
|
state.update(instant, data);
|
||||||
Some(pid_output)
|
match state.update_pid() {
|
||||||
} else {
|
Some(pid_output) if state.pid_engaged => {
|
||||||
None
|
log::info!("PID: {:.3} A", pid_output);
|
||||||
}
|
|
||||||
};
|
|
||||||
if let Some(dac_value) = dac_value {
|
|
||||||
// Forward PID output to i_set DAC
|
// Forward PID output to i_set DAC
|
||||||
// TODO:
|
self.set_i(channel.into(), ElectricCurrent::new::<ampere>(pid_output));
|
||||||
// self.set_dac(channel.into(), ElectricPotential::new::<volt>(dac_value));
|
}
|
||||||
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
channel
|
channel
|
||||||
|
|
|
@ -200,7 +200,7 @@ fn main() -> ! {
|
||||||
let state = channels.channel_state(channel);
|
let state = channels.channel_state(channel);
|
||||||
let _ = writeln!(socket, "PID settings for channel {}", channel);
|
let _ = writeln!(socket, "PID settings for channel {}", channel);
|
||||||
let pid = &state.pid;
|
let pid = &state.pid;
|
||||||
let _ = writeln!(socket, "- target={:.4}", pid.target);
|
let _ = writeln!(socket, "- target={:.4} °C", pid.target);
|
||||||
macro_rules! show_pid_parameter {
|
macro_rules! show_pid_parameter {
|
||||||
($p: tt) => {
|
($p: tt) => {
|
||||||
let _ = writeln!(
|
let _ = writeln!(
|
||||||
|
@ -217,7 +217,7 @@ fn main() -> ! {
|
||||||
show_pid_parameter!(output_min);
|
show_pid_parameter!(output_min);
|
||||||
show_pid_parameter!(output_max);
|
show_pid_parameter!(output_max);
|
||||||
if let Some(last_output) = pid.last_output {
|
if let Some(last_output) = pid.last_output {
|
||||||
let _ = writeln!(socket, "- last_output={:.4}", last_output);
|
let _ = writeln!(socket, "- last_output={:.3} A", last_output);
|
||||||
}
|
}
|
||||||
let _ = writeln!(socket, "");
|
let _ = writeln!(socket, "");
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,10 +44,13 @@ impl Controller {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update(&mut self, input: f64) -> f64 {
|
pub fn update(&mut self, input: f64) -> f64 {
|
||||||
|
// error
|
||||||
let error = self.target - input;
|
let error = self.target - input;
|
||||||
|
|
||||||
|
// partial
|
||||||
let p = self.parameters.kp * error;
|
let p = self.parameters.kp * error;
|
||||||
|
|
||||||
|
//integral
|
||||||
self.integral += error;
|
self.integral += error;
|
||||||
if self.integral < self.parameters.integral_min {
|
if self.integral < self.parameters.integral_min {
|
||||||
self.integral = self.parameters.integral_min;
|
self.integral = self.parameters.integral_min;
|
||||||
|
@ -57,12 +60,14 @@ impl Controller {
|
||||||
}
|
}
|
||||||
let i = self.parameters.ki * self.integral;
|
let i = self.parameters.ki * self.integral;
|
||||||
|
|
||||||
|
// derivative
|
||||||
let d = match self.last_input {
|
let d = match self.last_input {
|
||||||
None => 0.0,
|
None => 0.0,
|
||||||
Some(last_input) => self.parameters.kd * (last_input - input)
|
Some(last_input) => self.parameters.kd * (last_input - input)
|
||||||
};
|
};
|
||||||
self.last_input = Some(input);
|
self.last_input = Some(input);
|
||||||
|
|
||||||
|
// output
|
||||||
let mut output = p + i + d;
|
let mut output = p + i + d;
|
||||||
if output < self.parameters.output_min {
|
if output < self.parameters.output_min {
|
||||||
output = self.parameters.output_min;
|
output = self.parameters.output_min;
|
||||||
|
|
Loading…
Reference in New Issue