From 5386d2a2bfcb79da7f52add0a1560fa71f8228c9 Mon Sep 17 00:00:00 2001 From: Zachary Sunforge Date: Thu, 6 Jul 2023 22:40:54 -0700 Subject: [PATCH] Thermocouple type K conversion --- Cargo.toml | 3 + src/transducer/conversion/mod.rs | 4 ++ .../conversion/thermocouples/mod.rs | 2 + .../conversion/thermocouples/type_k.rs | 66 +++++++++++++++++++ 4 files changed, 75 insertions(+) create mode 100644 src/transducer/conversion/thermocouples/mod.rs create mode 100644 src/transducer/conversion/thermocouples/type_k.rs diff --git a/Cargo.toml b/Cargo.toml index 513db1c..fd9fb6f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -126,6 +126,9 @@ repository.workspace = true readme.workspace = true license.workspace = true +[features] +thermocouple_k = [] + [dependencies] uom = { workspace = true } parity-scale-codec = { workspace = true } diff --git a/src/transducer/conversion/mod.rs b/src/transducer/conversion/mod.rs index e69de29..fe6f177 100644 --- a/src/transducer/conversion/mod.rs +++ b/src/transducer/conversion/mod.rs @@ -0,0 +1,4 @@ +mod thermocouples; + +#[cfg(feature = "thermocouple_k")] +pub use thermocouples::type_k as thermocouple_k; \ No newline at end of file diff --git a/src/transducer/conversion/thermocouples/mod.rs b/src/transducer/conversion/thermocouples/mod.rs new file mode 100644 index 0000000..9ce86f4 --- /dev/null +++ b/src/transducer/conversion/thermocouples/mod.rs @@ -0,0 +1,2 @@ +#[cfg(feature = "thermocouple_k")] +pub mod type_k; \ No newline at end of file diff --git a/src/transducer/conversion/thermocouples/type_k.rs b/src/transducer/conversion/thermocouples/type_k.rs new file mode 100644 index 0000000..e59b39e --- /dev/null +++ b/src/transducer/conversion/thermocouples/type_k.rs @@ -0,0 +1,66 @@ +use crate::transducer::InvalidValue; +use uom::si::electric_potential::millivolt; +use uom::si::f32; +use uom::si::thermodynamic_temperature::degree_celsius; + +/// Convert from a voltage produced by a type k thermocouple to a temperature. +/// +/// 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, + cold_junction: f32::ThermodynamicTemperature, +) -> Result { + //TODO: Add cold junction correction + let mv = voltage.get::(); + let mv_pow2 = mv * mv; + let mv_pow3 = mv_pow2 * mv; + let mv_pow4 = mv_pow3 * mv; + let mv_pow5 = mv_pow4 * mv; + let mv_pow6 = mv_pow5 * mv; + + if mv >= -5.891 && mv <= 0.0 { + let mv_pow7 = mv_pow6 * mv; + let mv_pow8 = mv_pow7 * mv; + + let celsius = 1.0 + + 2.5173462e1 * mv + + -1.1662878 * mv_pow2 + + -1.0833638 * mv_pow3 + + -8.9773540e-1 * mv_pow4 + + -3.7342377e-1 * mv_pow5 + + -8.6632643e-2 * mv_pow6 + + -1.0450598e-2 * mv_pow7 + + -5.1920577e-4 * mv_pow8; + + Ok(f32::ThermodynamicTemperature::new::(celsius)) + } else if mv > 0.0 && mv < 20.644 { + let mv_pow7 = mv_pow6 * mv; + let mv_pow8 = mv_pow7 * mv; + let mv_pow9 = mv_pow8 * mv; + + let celsius = 1.0 + + 2.508355e1 * mv + + 7.860106e-2 * mv_pow2 + + -2.503131e-1 * mv_pow3 + + 8.315270e-2 * mv_pow4 + + -1.228034e-2 * mv_pow5 + + 9.804036e-4 * mv_pow6 + + -4.413030e-5 * mv_pow7 + + 1.057734e-6 * mv_pow8 + + -1.052755e-8 * mv_pow9; + + Ok(f32::ThermodynamicTemperature::new::(celsius)) + } else if mv >= 20.644 && mv <= 54.886 { + let celsius = 1.318058e2 + + 4.830222e1 * mv + + -1.646031 * mv_pow2 + + 5.464731e-2 * mv_pow3 + + -9.650715e-4 * mv_pow4 + + 8.802193e-6 * mv_pow5 + + -3.110810e-8 * mv_pow6; + + Ok(f32::ThermodynamicTemperature::new::(celsius)) + } else { + Err(InvalidValue) + } +}