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