- Modified some thermocouple functions to use f64 instead of f32
- Added thermistor - Added resistive divider
This commit is contained in:
@ -9,7 +9,7 @@ members = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
[workspace.package]
|
[workspace.package]
|
||||||
version = "0.3.3"
|
version = "0.3.4"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
repository = "https://git.bfpower.io/BFPOWER/physical"
|
repository = "https://git.bfpower.io/BFPOWER/physical"
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
@ -107,7 +107,9 @@ readme.workspace = true
|
|||||||
license.workspace = true
|
license.workspace = true
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
thermocouple_k = []
|
resistive-divider = []
|
||||||
|
thermocouple-k = ["libm"]
|
||||||
|
thermistor = ["libm"]
|
||||||
lm35 = []
|
lm35 = []
|
||||||
pid = []
|
pid = []
|
||||||
stm32 = []
|
stm32 = []
|
||||||
@ -115,7 +117,7 @@ stm32 = []
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
uom = { workspace = true }
|
uom = { workspace = true }
|
||||||
num-traits = { workspace = true }
|
num-traits = { workspace = true }
|
||||||
libm = { workspace = true }
|
libm = { workspace = true, optional = true }
|
||||||
serde = { workspace = true, optional = true }
|
serde = { workspace = true, optional = true }
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------------------------------------------
|
||||||
|
@ -5,5 +5,7 @@ pub mod control;
|
|||||||
pub mod error;
|
pub mod error;
|
||||||
|
|
||||||
pub mod adc;
|
pub mod adc;
|
||||||
|
#[cfg(feature = "resistive-divider")]
|
||||||
|
pub mod resistive_divider;
|
||||||
|
|
||||||
pub use error::CriticalError;
|
pub use error::CriticalError;
|
||||||
|
31
src/resistive_divider.rs
Normal file
31
src/resistive_divider.rs
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
use uom::si::electric_potential::volt;
|
||||||
|
use uom::si::electrical_resistance::ohm;
|
||||||
|
use uom::si::quantities::{ElectricPotential, ElectricalResistance};
|
||||||
|
|
||||||
|
/// Given the resistance of the second resistor in a resistive voltage divider, calculate the resistance of the first resistor.
|
||||||
|
pub fn solve_r1(
|
||||||
|
voltage_src: ElectricPotential<f32>,
|
||||||
|
voltage_read: ElectricPotential<f32>,
|
||||||
|
r2: ElectricalResistance<f32>,
|
||||||
|
) -> ElectricalResistance<f32> {
|
||||||
|
let volts_src = voltage_src.get::<volt>();
|
||||||
|
let volts_read = voltage_read.get::<volt>();
|
||||||
|
let ohms2 = r2.get::<ohm>();
|
||||||
|
|
||||||
|
let ohms1 = ohms2 * (volts_src / volts_read - 1.0);
|
||||||
|
ElectricalResistance::new::<ohm>(ohms1)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Given the resistance of the first resistor in a resistive voltage divider, calculate the resistance of the second resistor.
|
||||||
|
pub fn solve_r2(
|
||||||
|
voltage_src: ElectricPotential<f32>,
|
||||||
|
voltage_read: ElectricPotential<f32>,
|
||||||
|
r1: ElectricalResistance<f32>,
|
||||||
|
) -> ElectricalResistance<f32> {
|
||||||
|
let volts_src = voltage_src.get::<volt>();
|
||||||
|
let volts_read = voltage_read.get::<volt>();
|
||||||
|
let ohms1 = r1.get::<ohm>();
|
||||||
|
|
||||||
|
let ohms2 = ohms1 * (1.0 / (volts_src / volts_read) - 1.0);
|
||||||
|
ElectricalResistance::new::<ohm>(ohms2)
|
||||||
|
}
|
@ -3,5 +3,8 @@ mod thermocouple;
|
|||||||
#[cfg(feature = "lm35")]
|
#[cfg(feature = "lm35")]
|
||||||
pub mod lm35;
|
pub mod lm35;
|
||||||
|
|
||||||
#[cfg(feature = "thermocouple_k")]
|
#[cfg(feature = "thermistor")]
|
||||||
|
pub mod thermistor;
|
||||||
|
|
||||||
|
#[cfg(feature = "thermocouple-k")]
|
||||||
pub use thermocouple::type_k as thermocouple_k;
|
pub use thermocouple::type_k as thermocouple_k;
|
33
src/transducer/part/thermistor.rs
Normal file
33
src/transducer/part/thermistor.rs
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
use libm::{log, logf};
|
||||||
|
use uom::si::electrical_resistance::ohm;
|
||||||
|
use uom::si::quantities::{ThermodynamicTemperature, ElectricalResistance};
|
||||||
|
use uom::si::thermodynamic_temperature::kelvin;
|
||||||
|
|
||||||
|
/// Convert thermistor resistance to a temperature using beta parameter equation
|
||||||
|
pub fn convert_beta(
|
||||||
|
resistance: ElectricalResistance<f32>,
|
||||||
|
beta: f32,
|
||||||
|
reference_temp: ThermodynamicTemperature<f32>,
|
||||||
|
reference_resist: ElectricalResistance<f32>,
|
||||||
|
) -> ThermodynamicTemperature<f32> {
|
||||||
|
let ohms = resistance.get::<ohm>();
|
||||||
|
let reference_kelvin = reference_temp.get::<kelvin>();
|
||||||
|
let reference_ohms = reference_resist.get::<ohm>();
|
||||||
|
|
||||||
|
let result_kelvin = 1.0 / ((1.0 / reference_kelvin) + (1.0 / beta) * logf(ohms / reference_ohms));
|
||||||
|
ThermodynamicTemperature::new::<kelvin>(result_kelvin)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Convert thermistor resistance to a temperature using Steinhart-Hart equation
|
||||||
|
pub fn convert_steinhart(
|
||||||
|
resistance: ElectricalResistance<f32>,
|
||||||
|
a: f64,
|
||||||
|
b: f64,
|
||||||
|
c: f64,
|
||||||
|
) -> ThermodynamicTemperature<f32> {
|
||||||
|
let ohms = resistance.get::<ohm>() as f64;
|
||||||
|
|
||||||
|
let log_omhs = log(ohms);
|
||||||
|
let kelvins = 1.0 / (a + b * log_omhs + c * log_omhs * log_omhs * log_omhs);
|
||||||
|
ThermodynamicTemperature::new::<kelvin>(kelvins as f32)
|
||||||
|
}
|
@ -1,2 +1,2 @@
|
|||||||
#[cfg(feature = "thermocouple_k")]
|
#[cfg(feature = "thermocouple-k")]
|
||||||
pub mod type_k;
|
pub mod type_k;
|
@ -1,5 +1,7 @@
|
|||||||
|
//! Note - Thermocouple conversion uses [f64] arithmetic internally.
|
||||||
|
|
||||||
|
use libm::pow;
|
||||||
use crate::error::InvalidValue;
|
use crate::error::InvalidValue;
|
||||||
use libm::powf;
|
|
||||||
use uom::si::electric_potential::millivolt;
|
use uom::si::electric_potential::millivolt;
|
||||||
use uom::si::quantities::{ElectricPotential, ThermodynamicTemperature};
|
use uom::si::quantities::{ElectricPotential, ThermodynamicTemperature};
|
||||||
use uom::si::thermodynamic_temperature::degree_celsius;
|
use uom::si::thermodynamic_temperature::degree_celsius;
|
||||||
@ -7,7 +9,7 @@ use uom::si::thermodynamic_temperature::degree_celsius;
|
|||||||
fn _convert(
|
fn _convert(
|
||||||
voltage: ElectricPotential<f32>,
|
voltage: ElectricPotential<f32>,
|
||||||
) -> Result<ThermodynamicTemperature<f32>, InvalidValue> {
|
) -> Result<ThermodynamicTemperature<f32>, InvalidValue> {
|
||||||
let mv = voltage.get::<millivolt>();
|
let mv = voltage.get::<millivolt>() as f64;
|
||||||
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;
|
||||||
@ -27,7 +29,7 @@ fn _convert(
|
|||||||
+ -1.0450598E-2 * mv_pow7
|
+ -1.0450598E-2 * mv_pow7
|
||||||
+ -5.1920577E-4 * mv_pow8;
|
+ -5.1920577E-4 * mv_pow8;
|
||||||
|
|
||||||
Ok(ThermodynamicTemperature::new::<degree_celsius>(celsius))
|
Ok(ThermodynamicTemperature::new::<degree_celsius>(celsius as f32))
|
||||||
} else if mv > 0.0 && mv < 20.644 {
|
} else if mv > 0.0 && mv < 20.644 {
|
||||||
let mv_pow7 = mv_pow6 * mv;
|
let mv_pow7 = mv_pow6 * mv;
|
||||||
let mv_pow8 = mv_pow7 * mv;
|
let mv_pow8 = mv_pow7 * mv;
|
||||||
@ -43,7 +45,7 @@ fn _convert(
|
|||||||
+ 1.057734E-6 * mv_pow8
|
+ 1.057734E-6 * mv_pow8
|
||||||
+ -1.052755E-8 * mv_pow9;
|
+ -1.052755E-8 * mv_pow9;
|
||||||
|
|
||||||
Ok(ThermodynamicTemperature::new::<degree_celsius>(celsius))
|
Ok(ThermodynamicTemperature::new::<degree_celsius>(celsius as f32))
|
||||||
} else if mv >= 20.644 && mv <= 54.886 {
|
} else if mv >= 20.644 && mv <= 54.886 {
|
||||||
let celsius = 1.318058e2
|
let celsius = 1.318058e2
|
||||||
+ 4.830222E+1 * mv
|
+ 4.830222E+1 * mv
|
||||||
@ -53,7 +55,7 @@ fn _convert(
|
|||||||
+ 8.802193E-6 * mv_pow5
|
+ 8.802193E-6 * mv_pow5
|
||||||
+ -3.110810E-8 * mv_pow6;
|
+ -3.110810E-8 * mv_pow6;
|
||||||
|
|
||||||
Ok(ThermodynamicTemperature::new::<degree_celsius>(celsius))
|
Ok(ThermodynamicTemperature::new::<degree_celsius>(celsius as f32))
|
||||||
} else {
|
} else {
|
||||||
Err(InvalidValue)
|
Err(InvalidValue)
|
||||||
}
|
}
|
||||||
@ -107,11 +109,10 @@ pub fn convert_polynomial(
|
|||||||
_convert(voltage + voltage_correction)
|
_convert(voltage + voltage_correction)
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: This is not working, check libm pow.
|
|
||||||
pub fn temp_to_voltage_poly(
|
pub fn temp_to_voltage_poly(
|
||||||
temperature: ThermodynamicTemperature<f32>,
|
temperature: ThermodynamicTemperature<f32>,
|
||||||
) -> Result<ElectricPotential<f32>, InvalidValue> {
|
) -> Result<ElectricPotential<f32>, InvalidValue> {
|
||||||
let celsius = temperature.get::<degree_celsius>();
|
let celsius = temperature.get::<degree_celsius>() as f64;
|
||||||
let cel_pow2 = celsius * celsius;
|
let cel_pow2 = celsius * celsius;
|
||||||
let cel_pow3 = cel_pow2 * celsius;
|
let cel_pow3 = cel_pow2 * celsius;
|
||||||
let cel_pow4 = cel_pow3 * celsius;
|
let cel_pow4 = cel_pow3 * celsius;
|
||||||
@ -135,11 +136,11 @@ pub fn temp_to_voltage_poly(
|
|||||||
+ -0.198892668780E-19 * cel_pow9
|
+ -0.198892668780E-19 * cel_pow9
|
||||||
+ -0.163226974860E-22 * cel_pow10;
|
+ -0.163226974860E-22 * cel_pow10;
|
||||||
|
|
||||||
Ok(ElectricPotential::new::<millivolt>(mv))
|
Ok(ElectricPotential::new::<millivolt>(mv as f32))
|
||||||
} else if celsius >= 0.0 && celsius <= 1372.0 {
|
} else if celsius >= 0.0 && celsius <= 1372.0 {
|
||||||
let base = celsius - 0.126968600000E+03;
|
let base = celsius - 0.126968600000E+03;
|
||||||
let exp = -0.118343200000E-03 * (base * base);
|
let exp = -0.118343200000E-03 * (base * base);
|
||||||
let addition = powf(0.1185976, exp);
|
let addition = pow(0.1185976, exp);
|
||||||
|
|
||||||
let mv = -0.176004136860E-01
|
let mv = -0.176004136860E-01
|
||||||
+ 0.389212049750E-01 * celsius
|
+ 0.389212049750E-01 * celsius
|
||||||
@ -153,7 +154,7 @@ pub fn temp_to_voltage_poly(
|
|||||||
+ -0.121047212750E-25 * cel_pow9
|
+ -0.121047212750E-25 * cel_pow9
|
||||||
+ addition;
|
+ addition;
|
||||||
|
|
||||||
Ok(ElectricPotential::new::<millivolt>(mv))
|
Ok(ElectricPotential::new::<millivolt>(mv as f32))
|
||||||
} else {
|
} else {
|
||||||
Err(InvalidValue)
|
Err(InvalidValue)
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user