forked from M-Labs/thermostat
main: connect adc/sh/pid/dac, split out into mod channel_state
This commit is contained in:
parent
a94650e208
commit
c00c1bb081
|
@ -19,6 +19,8 @@ pub const SPI_MODE: spi::Mode = spi::Mode {
|
||||||
/// 2 MHz
|
/// 2 MHz
|
||||||
pub const SPI_CLOCK: MegaHertz = MegaHertz(2);
|
pub const SPI_CLOCK: MegaHertz = MegaHertz(2);
|
||||||
|
|
||||||
|
pub const MAX_VALUE: u32 = 0xFF_FFFF;
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
pub enum AdcError<SPI> {
|
pub enum AdcError<SPI> {
|
||||||
SPI(SPI),
|
SPI(SPI),
|
||||||
|
|
|
@ -0,0 +1,40 @@
|
||||||
|
use smoltcp::time::Instant;
|
||||||
|
use crate::{ad5680, ad7172, pid, steinhart_hart as sh};
|
||||||
|
|
||||||
|
|
||||||
|
pub struct ChannelState {
|
||||||
|
pub adc_data: Option<i32>,
|
||||||
|
pub adc_time: Instant,
|
||||||
|
pub dac_value: u32,
|
||||||
|
pub pid_enabled: bool,
|
||||||
|
pub pid: pid::Controller,
|
||||||
|
pub sh: sh::Parameters,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for ChannelState {
|
||||||
|
fn default() -> Self {
|
||||||
|
ChannelState {
|
||||||
|
adc_data: None,
|
||||||
|
adc_time: Instant::from_secs(0),
|
||||||
|
dac_value: 0,
|
||||||
|
pid_enabled: false,
|
||||||
|
pid: pid::Controller::new(pid::Parameters::default()),
|
||||||
|
sh: sh::Parameters::default(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ChannelState {
|
||||||
|
/// Update PID state on ADC input, calculate new DAC output
|
||||||
|
pub fn update_adc(&mut self, now: Instant, adc_data: i32) {
|
||||||
|
self.adc_data = Some(adc_data);
|
||||||
|
self.adc_time = now;
|
||||||
|
|
||||||
|
// Update PID controller
|
||||||
|
let input = (adc_data as f64) / (ad7172::MAX_VALUE as f64);
|
||||||
|
let temperature = self.sh.get_temperature(input);
|
||||||
|
let output = self.pid.update(temperature);
|
||||||
|
self.dac_value = (output * (ad5680::MAX_VALUE as f64)) as u32;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
42
src/main.rs
42
src/main.rs
|
@ -44,30 +44,8 @@ use command_parser::{Command, ShowCommand, PwmPin};
|
||||||
mod timer;
|
mod timer;
|
||||||
mod pid;
|
mod pid;
|
||||||
mod steinhart_hart;
|
mod steinhart_hart;
|
||||||
use steinhart_hart as sh;
|
mod channel_state;
|
||||||
|
use channel_state::ChannelState;
|
||||||
|
|
||||||
struct ChannelState {
|
|
||||||
adc_data: Option<i32>,
|
|
||||||
adc_time: Instant,
|
|
||||||
dac_value: u32,
|
|
||||||
pid_enabled: bool,
|
|
||||||
pid: pid::Controller,
|
|
||||||
sh: sh::Parameters,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Default for ChannelState {
|
|
||||||
fn default() -> Self {
|
|
||||||
ChannelState {
|
|
||||||
adc_data: None,
|
|
||||||
adc_time: Instant::from_secs(0),
|
|
||||||
dac_value: 0,
|
|
||||||
pid_enabled: false,
|
|
||||||
pid: pid::Controller::new(pid::Parameters::default()),
|
|
||||||
sh: sh::Parameters::default(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
const HSE: MegaHertz = MegaHertz(8);
|
const HSE: MegaHertz = MegaHertz(8);
|
||||||
|
@ -151,8 +129,20 @@ fn main() -> ! {
|
||||||
let data = adc.read_data().unwrap();
|
let data = adc.read_data().unwrap();
|
||||||
|
|
||||||
let state = &mut channel_states[usize::from(channel)];
|
let state = &mut channel_states[usize::from(channel)];
|
||||||
state.adc_data = Some(data);
|
state.update_adc(instant, data);
|
||||||
state.adc_time = instant;
|
|
||||||
|
if state.pid_enabled {
|
||||||
|
// Forward PID output to i_set DAC
|
||||||
|
match channel {
|
||||||
|
0 =>
|
||||||
|
dac0.set(state.dac_value).unwrap(),
|
||||||
|
1 =>
|
||||||
|
dac1.set(state.dac_value).unwrap(),
|
||||||
|
_ =>
|
||||||
|
unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
server.for_each(|_, session| session.set_report_pending(channel.into()));
|
server.for_each(|_, session| session.set_report_pending(channel.into()));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue