- Modified some thermocouple functions to use f64 instead of f32

- Added thermistor
- Added resistive divider
This commit is contained in:
Zachary Sunforge
2024-07-07 18:57:59 -07:00
parent 403df6f5f4
commit 96ae59087e
7 changed files with 87 additions and 15 deletions

View File

@ -9,7 +9,7 @@ members = [
]
[workspace.package]
version = "0.3.3"
version = "0.3.4"
edition = "2021"
repository = "https://git.bfpower.io/BFPOWER/physical"
readme = "README.md"
@ -107,7 +107,9 @@ readme.workspace = true
license.workspace = true
[features]
thermocouple_k = []
resistive-divider = []
thermocouple-k = ["libm"]
thermistor = ["libm"]
lm35 = []
pid = []
stm32 = []
@ -115,7 +117,7 @@ stm32 = []
[dependencies]
uom = { workspace = true }
num-traits = { workspace = true }
libm = { workspace = true }
libm = { workspace = true, optional = true }
serde = { workspace = true, optional = true }
#---------------------------------------------------------------------------------------------------------------------

View File

@ -5,5 +5,7 @@ pub mod control;
pub mod error;
pub mod adc;
#[cfg(feature = "resistive-divider")]
pub mod resistive_divider;
pub use error::CriticalError;

31
src/resistive_divider.rs Normal file
View 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)
}

View File

@ -3,5 +3,8 @@ mod thermocouple;
#[cfg(feature = "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;

View 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)
}

View File

@ -1,2 +1,2 @@
#[cfg(feature = "thermocouple_k")]
#[cfg(feature = "thermocouple-k")]
pub mod type_k;

View File

@ -1,5 +1,7 @@
//! Note - Thermocouple conversion uses [f64] arithmetic internally.
use libm::pow;
use crate::error::InvalidValue;
use libm::powf;
use uom::si::electric_potential::millivolt;
use uom::si::quantities::{ElectricPotential, ThermodynamicTemperature};
use uom::si::thermodynamic_temperature::degree_celsius;
@ -7,7 +9,7 @@ use uom::si::thermodynamic_temperature::degree_celsius;
fn _convert(
voltage: ElectricPotential<f32>,
) -> Result<ThermodynamicTemperature<f32>, InvalidValue> {
let mv = voltage.get::<millivolt>();
let mv = voltage.get::<millivolt>() as f64;
let mv_pow2 = mv * mv;
let mv_pow3 = mv_pow2 * mv;
let mv_pow4 = mv_pow3 * mv;
@ -27,7 +29,7 @@ fn _convert(
+ -1.0450598E-2 * mv_pow7
+ -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 {
let mv_pow7 = mv_pow6 * mv;
let mv_pow8 = mv_pow7 * mv;
@ -43,7 +45,7 @@ fn _convert(
+ 1.057734E-6 * mv_pow8
+ -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 {
let celsius = 1.318058e2
+ 4.830222E+1 * mv
@ -53,7 +55,7 @@ fn _convert(
+ 8.802193E-6 * mv_pow5
+ -3.110810E-8 * mv_pow6;
Ok(ThermodynamicTemperature::new::<degree_celsius>(celsius))
Ok(ThermodynamicTemperature::new::<degree_celsius>(celsius as f32))
} else {
Err(InvalidValue)
}
@ -107,11 +109,10 @@ pub fn convert_polynomial(
_convert(voltage + voltage_correction)
}
//TODO: This is not working, check libm pow.
pub fn temp_to_voltage_poly(
temperature: ThermodynamicTemperature<f32>,
) -> 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_pow3 = cel_pow2 * celsius;
let cel_pow4 = cel_pow3 * celsius;
@ -135,11 +136,11 @@ pub fn temp_to_voltage_poly(
+ -0.198892668780E-19 * cel_pow9
+ -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 {
let base = celsius - 0.126968600000E+03;
let exp = -0.118343200000E-03 * (base * base);
let addition = powf(0.1185976, exp);
let addition = pow(0.1185976, exp);
let mv = -0.176004136860E-01
+ 0.389212049750E-01 * celsius
@ -153,7 +154,7 @@ pub fn temp_to_voltage_poly(
+ -0.121047212750E-25 * cel_pow9
+ addition;
Ok(ElectricPotential::new::<millivolt>(mv))
Ok(ElectricPotential::new::<millivolt>(mv as f32))
} else {
Err(InvalidValue)
}