thermostat: cal gain error at TEC DAC output

This commit is contained in:
linuswck 2024-07-10 18:16:03 +08:00
parent db2f76771a
commit af95de0f16
2 changed files with 22 additions and 9 deletions

View File

@ -12,7 +12,7 @@ use stm32f4xx_hal::{adc::{config::{self, AdcConfig},
timer::pwm::PwmChannel}; timer::pwm::PwmChannel};
use uom::si::{electric_potential::millivolt, f32::ElectricPotential, ratio::ratio}; use uom::si::{electric_potential::millivolt, f32::ElectricPotential, ratio::ratio};
use crate::thermostat::ad5680; use crate::{device::sys_timer::sleep, thermostat::ad5680};
pub const PWM_FREQ_KHZ: KilohertzU32 = KilohertzU32::from_raw(20); pub const PWM_FREQ_KHZ: KilohertzU32 = KilohertzU32::from_raw(20);
@ -77,6 +77,7 @@ pub struct MAX1968 {
pub phy: MAX1968Phy<Channel0>, pub phy: MAX1968Phy<Channel0>,
pub pins_adc: Adc<ADC1>, pub pins_adc: Adc<ADC1>,
pub dma_adc: DMA_Transfer<Stream2<DMA2>, 1, Adc<ADC2>, PeripheralToMemory, &'static mut [u16; 16]>, pub dma_adc: DMA_Transfer<Stream2<DMA2>, 1, Adc<ADC2>, PeripheralToMemory, &'static mut [u16; 16]>,
pub dac_out_range: ElectricPotential,
prev_vtec_volt: ElectricPotential, prev_vtec_volt: ElectricPotential,
prev_itec_volt: ElectricPotential, prev_itec_volt: ElectricPotential,
} }
@ -115,7 +116,7 @@ static mut ADC2_FIRST_BUFFER: [u16; 16] = [0; 16];
static mut ADC2_LOCAL_BUFFER: [u16; 16] = [0; 16]; static mut ADC2_LOCAL_BUFFER: [u16; 16] = [0; 16];
impl MAX1968 { impl MAX1968 {
pub fn new(phy_ch0: MAX1968Phy<Channel0>, adc1: ADC1, adc2: ADC2, dma2: DMA2) -> Self { pub fn new(mut phy_ch0: MAX1968Phy<Channel0>, adc1: ADC1, adc2: ADC2, dma2: DMA2) -> Self {
let adc_config = AdcConfig::default() let adc_config = AdcConfig::default()
.clock(config::Clock::Pclk2_div_8) .clock(config::Clock::Pclk2_div_8)
.default_sample_time(config::SampleTime::Cycles_480); .default_sample_time(config::SampleTime::Cycles_480);
@ -221,11 +222,27 @@ impl MAX1968 {
); );
NVIC::unmask(interrupt::DMA2_STREAM2); NVIC::unmask(interrupt::DMA2_STREAM2);
} }
phy_ch0.dac.set(ad5680::MAX_VALUE).unwrap();
sleep(500);
let mut sample = 0;
for _ in 0..512 {
sample += pins_adc1.convert(
&phy_ch0.dac_feedback_pin,
stm32f4xx_hal::adc::config::SampleTime::Cycles_480,
) as u32;
}
let sample = sample / 512 as u32;
let mv = pins_adc1.sample_to_millivolts(sample as u16);
let dac_out_range = ElectricPotential::new::<millivolt>(mv as f32);
phy_ch0.dac.set(0).unwrap();
MAX1968 { MAX1968 {
phy: phy_ch0, phy: phy_ch0,
pins_adc: pins_adc1, pins_adc: pins_adc1,
dma_adc: dma_adc, dma_adc: dma_adc,
dac_out_range: dac_out_range,
prev_vtec_volt: ElectricPotential::new::<millivolt>(0.0), prev_vtec_volt: ElectricPotential::new::<millivolt>(0.0),
prev_itec_volt: ElectricPotential::new::<millivolt>(0.0), prev_itec_volt: ElectricPotential::new::<millivolt>(0.0),
} }

View File

@ -47,11 +47,6 @@ pub struct TecSettings {
} }
impl TecSettings { impl TecSettings {
pub const DAC_OUT_V_MAX: ElectricPotential = ElectricPotential {
dimension: PhantomData,
units: PhantomData,
value: 3.0,
};
pub const TEC_VSEC_BIAS_V: ElectricPotential = ElectricPotential { pub const TEC_VSEC_BIAS_V: ElectricPotential = ElectricPotential {
dimension: PhantomData, dimension: PhantomData,
units: PhantomData, units: PhantomData,
@ -237,7 +232,8 @@ impl Thermostat {
pub fn set_i(&mut self, i_tec: ElectricCurrent) -> ElectricCurrent { pub fn set_i(&mut self, i_tec: ElectricCurrent) -> ElectricCurrent {
let voltage = i_tec * 10.0 * R_SENSE + self.tec_settings.center_pt; let voltage = i_tec * 10.0 * R_SENSE + self.tec_settings.center_pt;
let voltage = self.max1968.set_dac(voltage, TecSettings::DAC_OUT_V_MAX); let voltage = self.max1968.set_dac(voltage, self.max1968.dac_out_range);
self.tec_settings.i_set = (voltage - self.tec_settings.center_pt) / (10.0 * R_SENSE); self.tec_settings.i_set = (voltage - self.tec_settings.center_pt) / (10.0 * R_SENSE);
self.tec_settings.i_set self.tec_settings.i_set
} }
@ -335,7 +331,7 @@ impl Thermostat {
best_error = error; best_error = error;
start_value = prev_value; start_value = prev_value;
let vref = (value as f32 / ad5680::MAX_VALUE as f32) * TecSettings::DAC_OUT_V_MAX; let vref = (value as f32 / ad5680::MAX_VALUE as f32) * self.max1968.dac_out_range;
self.set_center_pt(vref); self.set_center_pt(vref);
} }
prev_value = value; prev_value = value;