Thermocouple type k conversion updates.
This commit is contained in:
@ -91,12 +91,7 @@ async fn main(spawner: Spawner) {
|
||||
|
||||
// Zero test
|
||||
let zero_voltage = f32::ElectricPotential::new::<millivolt>(0.0);
|
||||
let zero_temperature = thermocouple_k::convert(
|
||||
zero_voltage,
|
||||
reference_temp,
|
||||
thermocouple_k::r_junction_offset_lin,
|
||||
)
|
||||
.unwrap();
|
||||
let zero_temperature = thermocouple_k::convert_direct(zero_voltage, reference_temp).unwrap();
|
||||
let zero_celsius = zero_temperature.get::<degree_celsius>();
|
||||
info!("Zero test: {}", zero_celsius);
|
||||
|
||||
@ -108,9 +103,7 @@ async fn main(spawner: Spawner) {
|
||||
.unwrap()
|
||||
.to_voltage(AUTOCAL_CONF.ad_control.gain());
|
||||
let mv = voltage.get::<millivolt>();
|
||||
let temperature =
|
||||
thermocouple_k::convert(voltage, reference_temp, thermocouple_k::r_junction_offset_lin)
|
||||
.unwrap();
|
||||
let temperature = thermocouple_k::convert_direct(voltage, reference_temp).unwrap();
|
||||
let celsius = temperature.get::<degree_celsius>();
|
||||
info!("Temperature in degrees celsius: {}, millivolts: {}", celsius, mv);
|
||||
}
|
||||
|
@ -4,19 +4,10 @@ use uom::si::electric_potential::{millivolt, volt};
|
||||
use uom::si::f32;
|
||||
use uom::si::thermodynamic_temperature::degree_celsius;
|
||||
|
||||
/// Convert from a voltage produced by a type k thermocouple to a temperature using polynomial with
|
||||
/// NIST coefficients, this method has a maximum error of 0.06°C in addition to the underlying
|
||||
/// thermocouple inaccuracy.
|
||||
///
|
||||
/// This function uses the [NIST type K thermocouple linearisation polynomial](https://srdata.nist.gov/its90/type_k/kcoefficients_inverse.html).
|
||||
pub fn convert(
|
||||
fn _convert(
|
||||
voltage: f32::ElectricPotential,
|
||||
r_junction: f32::ThermodynamicTemperature,
|
||||
r_junction_offset: fn(
|
||||
r_junction: f32::ThermodynamicTemperature,
|
||||
) -> Result<f32::ElectricPotential, InvalidValue>,
|
||||
) -> Result<f32::ThermodynamicTemperature, InvalidValue> {
|
||||
let mv = voltage.get::<millivolt>() + r_junction_offset(r_junction)?.get::<millivolt>();
|
||||
let mv = voltage.get::<millivolt>();
|
||||
let mv_pow2 = mv * mv;
|
||||
let mv_pow3 = mv_pow2 * mv;
|
||||
let mv_pow4 = mv_pow3 * mv;
|
||||
@ -68,8 +59,56 @@ pub fn convert(
|
||||
}
|
||||
}
|
||||
|
||||
/// Convert from a voltage produced by a type k thermocouple to a temperature using polynomial and
|
||||
/// directly adding the reference junction temperature to the result for offset compensation.
|
||||
///
|
||||
/// Can be useful compared to [convert_seebeck] when the reference temperature or the temperature
|
||||
/// being read by the thermocouple is fairly close to 0.
|
||||
///
|
||||
/// This function uses the [NIST type K thermocouple linearisation polynomial](https://srdata.nist.gov/its90/type_k/kcoefficients_inverse.html).
|
||||
#[inline]
|
||||
pub fn convert_direct(
|
||||
voltage: f32::ElectricPotential,
|
||||
r_junction: f32::ThermodynamicTemperature,
|
||||
) -> Result<f32::ThermodynamicTemperature, InvalidValue> {
|
||||
let base_celsius = _convert(voltage)?.get::<degree_celsius>();
|
||||
let r_junction_celsius = r_junction.get::<degree_celsius>();
|
||||
|
||||
Ok(f32::ThermodynamicTemperature::new::<degree_celsius>(base_celsius + r_junction_celsius))
|
||||
}
|
||||
|
||||
/// Convert from a voltage produced by a type k thermocouple to a temperature using polynomial and
|
||||
/// using a constant seebeck coefficient to correct the input voltage for offset compensation.
|
||||
///
|
||||
/// Probably the right choice most of the time.
|
||||
///
|
||||
/// This function uses the [NIST type K thermocouple linearisation polynomial](https://srdata.nist.gov/its90/type_k/kcoefficients_inverse.html).
|
||||
#[inline]
|
||||
pub fn convert_seebeck(
|
||||
voltage: f32::ElectricPotential,
|
||||
r_junction: f32::ThermodynamicTemperature,
|
||||
) -> Result<f32::ThermodynamicTemperature, InvalidValue> {
|
||||
let voltage_correction = temp_to_voltage_seebeck(r_junction)?;
|
||||
_convert(voltage + voltage_correction)
|
||||
}
|
||||
|
||||
/// Convert from a voltage produced by a type k thermocouple to a temperature using polynomial and
|
||||
/// using a polynomial to correct the input voltage for offset compensation.
|
||||
///
|
||||
/// This is the most accurate method but uses the most processor cycles by a wide margin.
|
||||
///
|
||||
/// This function uses the [NIST type K thermocouple linearisation polynomial](https://srdata.nist.gov/its90/type_k/kcoefficients_inverse.html).
|
||||
#[inline]
|
||||
pub fn convert_polynomial(
|
||||
voltage: f32::ElectricPotential,
|
||||
r_junction: f32::ThermodynamicTemperature,
|
||||
) -> Result<f32::ThermodynamicTemperature, InvalidValue> {
|
||||
let voltage_correction = temp_to_voltage_poly(r_junction)?;
|
||||
_convert(voltage + voltage_correction)
|
||||
}
|
||||
|
||||
//TODO: This is not working, check libm pow.
|
||||
pub fn r_junction_offset_poly(
|
||||
pub fn temp_to_voltage_poly(
|
||||
temperature: f32::ThermodynamicTemperature,
|
||||
) -> Result<f32::ElectricPotential, InvalidValue> {
|
||||
let celsius = temperature.get::<degree_celsius>();
|
||||
@ -121,7 +160,7 @@ pub fn r_junction_offset_poly(
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn r_junction_offset_lin(
|
||||
pub fn temp_to_voltage_seebeck(
|
||||
temperature: f32::ThermodynamicTemperature,
|
||||
) -> Result<f32::ElectricPotential, InvalidValue> {
|
||||
let celsius = temperature.get::<degree_celsius>();
|
||||
|
Reference in New Issue
Block a user