channel_state: move adc_calibration into ChannelState

This commit is contained in:
Astro 2020-09-13 23:15:48 +02:00
parent bb26490153
commit b80fcc430b
4 changed files with 35 additions and 24 deletions

View File

@ -1,6 +1,7 @@
use stm32f4xx_hal::hal::digital::v2::OutputPin;
use crate::{
ad5680,
ad7172,
channel_state::ChannelState,
pins::{ChannelPins, ChannelPinSet},
};
@ -27,8 +28,8 @@ pub struct Channel<C: ChannelPins> {
}
impl<C: ChannelPins> Channel<C> {
pub fn new(mut pins: ChannelPinSet<C>) -> Self {
let state = ChannelState::default();
pub fn new(mut pins: ChannelPinSet<C>, adc_calibration: ad7172::ChannelCalibration) -> Self {
let state = ChannelState::new(adc_calibration);
let mut dac = ad5680::Dac::new(pins.dac_spi, pins.dac_sync);
let _ = dac.set(0);
// power up TEC

View File

@ -12,6 +12,7 @@ use crate::{
pub struct ChannelState {
pub adc_data: Option<u32>,
pub adc_calibration: ad7172::ChannelCalibration,
pub adc_time: Instant,
pub dac_value: ElectricPotential,
pub pid_engaged: bool,
@ -19,10 +20,11 @@ pub struct ChannelState {
pub sh: sh::Parameters,
}
impl Default for ChannelState {
fn default() -> Self {
impl ChannelState {
pub fn new(adc_calibration: ad7172::ChannelCalibration) -> Self {
ChannelState {
adc_data: None,
adc_calibration,
adc_time: Instant::from_secs(0),
dac_value: ElectricPotential::new::<volt>(0.0),
pid_engaged: false,
@ -30,17 +32,26 @@ impl Default for ChannelState {
sh: sh::Parameters::default(),
}
}
}
impl ChannelState {
/// Update PID state on ADC input, calculate new DAC output
pub fn update_pid(&mut self, now: Instant, adc_data: u32) -> f64 {
pub fn update(&mut self, now: Instant, adc_data: u32) {
self.adc_data = Some(adc_data);
self.adc_time = now;
}
/// Update PID state on ADC input, calculate new DAC output
pub fn update_pid(&mut self) -> f64 {
// Update PID controller
let input = (adc_data as f64) / (ad7172::MAX_VALUE as f64);
let temperature = self.sh.get_temperature(input);
self.pid.update(temperature)
self.pid.update(self.get_temperature().unwrap())
}
pub fn get_adc(&self) -> Option<ElectricPotential> {
let volts = self.adc_calibration.convert_data(self.adc_data?);
Some(ElectricPotential::new::<volt>(volts))
}
pub fn get_temperature(&self) -> Option<f64> {
let r = self.get_adc()?.get::<volt>();
let temperature = self.sh.get_temperature(r);
Some(temperature)
}
}

View File

@ -26,20 +26,23 @@ pub struct Channels {
impl Channels {
pub fn new(pins: pins::Pins) -> Self {
let channel0 = Channel::new(pins.channel0);
let channel1 = Channel::new(pins.channel1);
let pins_adc = pins.pins_adc;
let pwm = pins.pwm;
let mut adc = ad7172::Adc::new(pins.adc_spi, pins.adc_nss).unwrap();
// Feature not used
adc.set_sync_enable(false).unwrap();
// Setup channels and start ADC
adc.setup_channel(0, ad7172::Input::Ain0, ad7172::Input::Ain1).unwrap();
let adc_calibration0 = adc.get_calibration(0)
.expect("adc_calibration0");
adc.setup_channel(1, ad7172::Input::Ain2, ad7172::Input::Ain3).unwrap();
let adc_calibration1 = adc.get_calibration(1)
.expect("adc_calibration1");
adc.start_continuous_conversion().unwrap();
let mut channel0 = Channel::new(pins.channel0, adc_calibration0);
let mut channel1 = Channel::new(pins.channel1, adc_calibration1);
let pins_adc = pins.pins_adc;
let pwm = pins.pwm;
let mut channels = Channels { channel0, channel1, adc, pins_adc, pwm };
for channel in 0..CHANNELS {
channels.calibrate_dac_value(channel);

View File

@ -119,10 +119,6 @@ fn main() -> ! {
usb::State::setup(usb);
let mut channels = Channels::new(pins);
let adc_calibration = [
channels.adc.get_calibration(0).unwrap(),
channels.adc.get_calibration(1).unwrap(),
];
#[cfg(not(feature = "generate-hwaddr"))]
let hwaddr = EthernetAddress(NET_HWADDR);
@ -181,13 +177,13 @@ fn main() -> ! {
let state = channels.channel_state(channel);
let _ = writeln!(
socket, "channel {}: t={} adc_raw{}=0x{:06X} adc{}={:.3}V vref={} dac_feedback={} itec={} tec={} tec_u_meas={}",
socket, "channel {}: t={} adc{}={} vref={} dac_feedback={} itec={} tec={} tec_u_meas={} r={:03}",
channel,
state.adc_time, channel, adc_data,
channel, adc_calibration[channel].convert_data(adc_data),
vref.into_format_args(volt, Abbreviation), dac_feedback.into_format_args(volt, Abbreviation),
itec.into_format_args(volt, Abbreviation), tec_i.into_format_args(ampere, Abbreviation),
tec_u_meas.into_format_args(volt, Abbreviation),
(tec_u_meas / tec_i).into_format_args(ohm, Abbreviation),
);
} else {
let _ = writeln!(socket, "channel {}: no adc input", channel);
@ -398,9 +394,9 @@ fn main() -> ! {
let state = &mut channels.channel_state(usize::from(channel));
let adc_data = state.adc_data.unwrap_or(0);
let _ = writeln!(
socket, "t={} raw{}=0x{:06X} value={:.3}V",
socket, "t={} raw{}=0x{:06X} value={}",
state.adc_time, channel, adc_data,
adc_calibration[channel].convert_data(adc_data),
state.get_adc().unwrap().into_format_args(volt, Abbreviation),
).map(|_| {
session.mark_report_sent(channel);
});