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
|
||||
pub const SPI_CLOCK: MegaHertz = MegaHertz(2);
|
||||
|
||||
pub const MAX_VALUE: u32 = 0xFF_FFFF;
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub enum AdcError<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 pid;
|
||||
mod steinhart_hart;
|
||||
use steinhart_hart as sh;
|
||||
|
||||
|
||||
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(),
|
||||
}
|
||||
}
|
||||
}
|
||||
mod channel_state;
|
||||
use channel_state::ChannelState;
|
||||
|
||||
|
||||
const HSE: MegaHertz = MegaHertz(8);
|
||||
|
@ -151,8 +129,20 @@ fn main() -> ! {
|
|||
let data = adc.read_data().unwrap();
|
||||
|
||||
let state = &mut channel_states[usize::from(channel)];
|
||||
state.adc_data = Some(data);
|
||||
state.adc_time = instant;
|
||||
state.update_adc(instant, data);
|
||||
|
||||
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()));
|
||||
});
|
||||
|
||||
|
|
Loading…
Reference in New Issue