diff --git a/src/ad7172/adc.rs b/src/ad7172/adc.rs index c7d6646..fcde70e 100644 --- a/src/ad7172/adc.rs +++ b/src/ad7172/adc.rs @@ -4,6 +4,10 @@ use stm32f4xx_hal::hal::{ blocking::spi::Transfer, digital::v2::OutputPin, }; +use uom::si::{ + f64::ElectricPotential, + electric_potential::volt, +}; use super::{ regs::{self, Register, RegisterData}, checksum::{ChecksumMode, Checksum}, @@ -272,7 +276,7 @@ pub struct ChannelCalibration { } impl ChannelCalibration { - pub fn convert_data(&self, data: u32) -> f64 { + pub fn convert_data(&self, data: u32) -> ElectricPotential { let data = if self.bipolar { (data as i32 - 0x80_0000) as f64 } else { @@ -282,7 +286,7 @@ impl ChannelCalibration { let data = data + (self.offset as i32 - 0x80_0000) as f64; let data = data / (2 << 23) as f64; - const V_REF: f64 = 3.0; - data * V_REF / 0.75 + const V_REF: f64 = 3.3; + ElectricPotential::new::(data * V_REF / 0.75) } } diff --git a/src/channel_state.rs b/src/channel_state.rs index 5563150..586aae0 100644 --- a/src/channel_state.rs +++ b/src/channel_state.rs @@ -15,11 +15,13 @@ use crate::{ steinhart_hart as sh, }; +const R_INNER: f64 = 2.0 * 5100.0; pub struct ChannelState { pub adc_data: Option, pub adc_calibration: ad7172::ChannelCalibration, pub adc_time: Instant, + pub vref: ElectricPotential, pub dac_value: ElectricPotential, pub pid_engaged: bool, pub pid: pid::Controller, @@ -32,6 +34,8 @@ impl ChannelState { adc_data: None, adc_calibration, adc_time: Instant::from_secs(0), + // can be initialized later with Channels.read_vref() + vref: ElectricPotential::new::(3.3 / 2.0), dac_value: ElectricPotential::new::(0.0), pid_engaged: false, pid: pid::Controller::new(pid::Parameters::default()), @@ -52,14 +56,19 @@ impl ChannelState { } pub fn get_adc(&self) -> Option { - let volts = self.adc_calibration.convert_data(self.adc_data?); - Some(ElectricPotential::new::(volts)) + Some(self.adc_calibration.convert_data(self.adc_data?)) + } + + /// Get `SENS[01]` input resistance + pub fn get_sens(&self) -> Option { + let r_inner = ElectricalResistance::new::(R_INNER); + let adc_input = self.get_adc()?; + let r = r_inner * adc_input / (self.vref - adc_input); + Some(r) } pub fn get_temperature(&self) -> Option { - let r = self.get_adc()?.get::(); - // TODO: - let r = ElectricalResistance::new::(r); + let r = self.get_sens()?; let temperature = self.sh.get_temperature(r); Some(temperature) } diff --git a/src/channels.rs b/src/channels.rs index c4b0512..9720c6b 100644 --- a/src/channels.rs +++ b/src/channels.rs @@ -45,6 +45,8 @@ impl Channels { let pwm = pins.pwm; let mut channels = Channels { channel0, channel1, adc, pins_adc, pwm }; for channel in 0..CHANNELS { + // FIXME: this reads 1.5 V instead of the expected 1.65 V. + // channels.channel_state(channel).vref = channels.read_vref(channel); channels.calibrate_dac_value(channel); } channels @@ -172,7 +174,7 @@ impl Channels { stm32f4xx_hal::adc::config::SampleTime::Cycles_480 ); let mv = self.pins_adc.sample_to_millivolts(sample); - ElectricPotential::new::(mv as f64 / 1000.0) + ElectricPotential::new::(mv as f64) } 1 => { let sample = self.pins_adc.convert( @@ -180,7 +182,7 @@ impl Channels { stm32f4xx_hal::adc::config::SampleTime::Cycles_480 ); let mv = self.pins_adc.sample_to_millivolts(sample); - ElectricPotential::new::(mv as f64 / 1000.0) + ElectricPotential::new::(mv as f64) } _ => unreachable!(), } diff --git a/src/main.rs b/src/main.rs index 383a4cb..ff421be 100644 --- a/src/main.rs +++ b/src/main.rs @@ -168,7 +168,7 @@ fn main() -> ! { } Command::Show(ShowCommand::Input) => { for channel in 0..CHANNELS { - if let Some(adc_data) = channels.channel_state(channel).adc_data { + if let Some(adc_input) = channels.channel_state(channel).get_adc() { let vref = channels.read_vref(channel); let dac_feedback = channels.read_dac_feedback(channel); @@ -179,9 +179,10 @@ fn main() -> ! { let state = channels.channel_state(channel); let _ = writeln!( - socket, "channel {}: t={} adc{}={} vref={} dac_feedback={} itec={} tec={} tec_u_meas={} r={:03}", - channel, - state.adc_time, channel, adc_data, + socket, "channel {}: t={} adc{}={} adc_r={} vref={} dac_feedback={} itec={} tec={} tec_u_meas={} r={:03}", + channel, state.adc_time, + channel, adc_input.into_format_args(volt, Abbreviation), + state.get_sens().unwrap().into_format_args(ohm, Abbreviation), 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), @@ -265,11 +266,12 @@ fn main() -> ! { let _ = writeln!(socket, "- t0={}", state.sh.t0.into_format_args(degree_celsius, Abbreviation)); let _ = writeln!(socket, "- b={}", state.sh.b); let _ = writeln!(socket, "- r0={}", state.sh.r0.into_format_args(ohm, Abbreviation)); - match (state.get_adc(), state.get_temperature()) { - (Some(adc), Some(temp)) => { + match (state.get_adc(), state.get_sens(), state.get_temperature()) { + (Some(adc), Some(sens), Some(temp)) => { let _ = writeln!( - socket, "- adc={} temp={:.3}K", + socket, "- adc={} r={} temp={:.3}K", adc.into_format_args(volt, Abbreviation), + sens.into_format_args(ohm, Abbreviation), temp.into_format_args(degree_celsius, Abbreviation), ); }