Initial node implementation #4
@ -91,12 +91,7 @@ async fn main(spawner: Spawner) {
|
|||||||
|
|
||||||
// Zero test
|
// Zero test
|
||||||
let zero_voltage = f32::ElectricPotential::new::<millivolt>(0.0);
|
let zero_voltage = f32::ElectricPotential::new::<millivolt>(0.0);
|
||||||
let zero_temperature = thermocouple_k::convert(
|
let zero_temperature = thermocouple_k::convert_direct(zero_voltage, reference_temp).unwrap();
|
||||||
zero_voltage,
|
|
||||||
reference_temp,
|
|
||||||
thermocouple_k::r_junction_offset_lin,
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
let zero_celsius = zero_temperature.get::<degree_celsius>();
|
let zero_celsius = zero_temperature.get::<degree_celsius>();
|
||||||
info!("Zero test: {}", zero_celsius);
|
info!("Zero test: {}", zero_celsius);
|
||||||
|
|
||||||
@ -108,9 +103,7 @@ async fn main(spawner: Spawner) {
|
|||||||
.unwrap()
|
.unwrap()
|
||||||
.to_voltage(AUTOCAL_CONF.ad_control.gain());
|
.to_voltage(AUTOCAL_CONF.ad_control.gain());
|
||||||
let mv = voltage.get::<millivolt>();
|
let mv = voltage.get::<millivolt>();
|
||||||
let temperature =
|
let temperature = thermocouple_k::convert_direct(voltage, reference_temp).unwrap();
|
||||||
thermocouple_k::convert(voltage, reference_temp, thermocouple_k::r_junction_offset_lin)
|
|
||||||
.unwrap();
|
|
||||||
let celsius = temperature.get::<degree_celsius>();
|
let celsius = temperature.get::<degree_celsius>();
|
||||||
info!("Temperature in degrees celsius: {}, millivolts: {}", celsius, mv);
|
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::f32;
|
||||||
use uom::si::thermodynamic_temperature::degree_celsius;
|
use uom::si::thermodynamic_temperature::degree_celsius;
|
||||||
|
|
||||||
/// Convert from a voltage produced by a type k thermocouple to a temperature using polynomial with
|
fn _convert(
|
||||||
/// 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(
|
|
||||||
voltage: f32::ElectricPotential,
|
voltage: f32::ElectricPotential,
|
||||||
r_junction: f32::ThermodynamicTemperature,
|
|
||||||
r_junction_offset: fn(
|
|
||||||
r_junction: f32::ThermodynamicTemperature,
|
|
||||||
) -> Result<f32::ElectricPotential, InvalidValue>,
|
|
||||||
) -> Result<f32::ThermodynamicTemperature, 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_pow2 = mv * mv;
|
||||||
let mv_pow3 = mv_pow2 * mv;
|
let mv_pow3 = mv_pow2 * mv;
|
||||||
let mv_pow4 = mv_pow3 * 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.
|
//TODO: This is not working, check libm pow.
|
||||||
pub fn r_junction_offset_poly(
|
pub fn temp_to_voltage_poly(
|
||||||
temperature: f32::ThermodynamicTemperature,
|
temperature: f32::ThermodynamicTemperature,
|
||||||
) -> Result<f32::ElectricPotential, InvalidValue> {
|
) -> Result<f32::ElectricPotential, InvalidValue> {
|
||||||
let celsius = temperature.get::<degree_celsius>();
|
let celsius = temperature.get::<degree_celsius>();
|
||||||
@ -121,7 +160,7 @@ pub fn r_junction_offset_poly(
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn r_junction_offset_lin(
|
pub fn temp_to_voltage_seebeck(
|
||||||
temperature: f32::ThermodynamicTemperature,
|
temperature: f32::ThermodynamicTemperature,
|
||||||
) -> Result<f32::ElectricPotential, InvalidValue> {
|
) -> Result<f32::ElectricPotential, InvalidValue> {
|
||||||
let celsius = temperature.get::<degree_celsius>();
|
let celsius = temperature.get::<degree_celsius>();
|
||||||
|
Reference in New Issue
Block a user