diff --git a/Cargo.toml b/Cargo.toml index 9064c91..87ff90b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -128,6 +128,7 @@ license.workspace = true [features] thermocouple_k = [] +lm35 = [] [dependencies] uom = { workspace = true } diff --git a/examples/ads1256/Cargo.toml b/examples/ads1256/Cargo.toml index 23fed7f..b75e37d 100644 --- a/examples/ads1256/Cargo.toml +++ b/examples/ads1256/Cargo.toml @@ -9,7 +9,7 @@ license.workspace = true [dependencies.physical] path = "../.." -features = ["thermocouple_k"] +features = ["thermocouple_k", "lm35"] [dependencies.physical-node] path = "../../node" features = ["embassy-sync"] diff --git a/examples/ads1256/src/bin/thermocouple.rs b/examples/ads1256/src/bin/thermocouple.rs index 250bcc0..7a32bc6 100644 --- a/examples/ads1256/src/bin/thermocouple.rs +++ b/examples/ads1256/src/bin/thermocouple.rs @@ -10,7 +10,7 @@ use {defmt_rtt as _, panic_probe as _}; use {embassy_executor as executor, embassy_stm32 as stm32}; -use ads1256::standard::input::SingleEnded; +use ads1256::standard::input::{Differential, SingleEnded}; use ads1256::{ AdControl, Ads1256, AutoCal, BitOrder, BlockingDelay, Buffer, ClockOut, Config, DState, DataRate, DigitalIo, DigitalIoDirection, DigitalIoState, DioDirection, Gain, Multiplexer, @@ -29,12 +29,12 @@ use uom::si::electric_potential::{millivolt, volt}; use uom::si::f32; use defmt::{debug, error, info, trace, unwrap}; -use physical::transducer::thermocouple_k; +use physical::transducer::{lm35, thermocouple_k}; use uom::si::thermodynamic_temperature::degree_celsius; const AUTOCAL_CONF: Config = Config { status: Status::setting(Buffer::Enabled, AutoCal::Enabled, BitOrder::MostSigFirst), - multiplexer: Multiplexer::setting(MuxInput::AIn0, MuxInput::Common), + multiplexer: Multiplexer::setting(MuxInput::AIn0, MuxInput::AIn1), ad_control: AdControl::setting(Gain::X64, Sdcs::Off, ClockOut::Off), data_rate: DataRate::Sps2_5, digital_io: DigitalIo::setting(DigitalIoState::default(), DigitalIoDirection::default()), @@ -87,24 +87,40 @@ async fn main(spawner: Spawner) { ads_1256.write_config(&mut spi, AUTOCAL_CONF).unwrap(); ads_1256.self_calibrate(&mut spi).await.unwrap(); - let reference_temp = f32::ThermodynamicTemperature::new::(26.0); - - // Zero test - let zero_voltage = f32::ElectricPotential::new::(0.0); - let zero_temperature = thermocouple_k::convert_direct(zero_voltage, reference_temp).unwrap(); - let zero_celsius = zero_temperature.get::(); - info!("Zero test: {}", zero_celsius); - loop { - Delay.delay_ms(1_000u16); + let gain = Gain::X2; + let reference = ads_1256 + .autocal_convert( + &mut spi, + Differential::AIn0.into(), + None, + Some(AUTOCAL_CONF.ad_control.with_gain(gain)), + None, + false, + ) + .await + .unwrap() + .to_voltage(gain); + let reference = lm35::convert(reference).unwrap(); + let reference_celsius = reference.get::(); + info!("Reference junction temperature in degrees celsius: {}", reference_celsius); + + let gain = Gain::X64; let voltage = ads_1256 - .read_data(&mut spi) + .autocal_convert( + &mut spi, + Differential::AIn1.into(), + None, + Some(AUTOCAL_CONF.ad_control.with_gain(gain)), + None, + false, + ) .await .unwrap() .to_voltage(AUTOCAL_CONF.ad_control.gain()); let mv = voltage.get::(); - let temperature = thermocouple_k::convert_direct(voltage, reference_temp).unwrap(); + let temperature = thermocouple_k::convert_direct(voltage, reference).unwrap(); let celsius = temperature.get::(); - info!("Temperature in degrees celsius: {}, millivolts: {}", celsius, mv); + info!("Thermocouple temperature in degrees celsius: {}, millivolts: {}", celsius, mv); } } diff --git a/src/transducer/mod.rs b/src/transducer/mod.rs index b0cdd72..d79c453 100644 --- a/src/transducer/mod.rs +++ b/src/transducer/mod.rs @@ -3,10 +3,9 @@ use crate::cell::CellView; pub mod input; pub mod output; -mod thermocouple; +mod part; -#[cfg(feature = "thermocouple_k")] -pub use thermocouple::type_k as thermocouple_k; +pub use part::*; // Initialisation will always be async and won't complete until a state is available for all // stateful transducers. diff --git a/src/transducer/part/lm35.rs b/src/transducer/part/lm35.rs new file mode 100644 index 0000000..0f492da --- /dev/null +++ b/src/transducer/part/lm35.rs @@ -0,0 +1,22 @@ +use crate::transducer::InvalidValue; +use uom::si::electric_potential::volt; +use uom::si::f32; +use uom::si::thermodynamic_temperature::degree_celsius; + +const MIN_VOLTS: f32 = -0.55; +const MAX_VOLTS: f32 = 1.50; +const SCALE_FACTOR: f32 = 100.0; + +#[inline] +pub fn convert( + voltage: f32::ElectricPotential, +) -> Result { + let volts = voltage.get::(); + + if volts >= MIN_VOLTS && volts <= MAX_VOLTS { + let celsius = volts * SCALE_FACTOR; + Ok(f32::ThermodynamicTemperature::new::(celsius)) + } else { + Err(InvalidValue) + } +} diff --git a/src/transducer/part/mod.rs b/src/transducer/part/mod.rs new file mode 100644 index 0000000..cd42413 --- /dev/null +++ b/src/transducer/part/mod.rs @@ -0,0 +1,7 @@ +mod thermocouple; + +#[cfg(feature = "lm35")] +pub mod lm35; + +#[cfg(feature = "thermocouple_k")] +pub use thermocouple::type_k as thermocouple_k; \ No newline at end of file diff --git a/src/transducer/thermocouple/mod.rs b/src/transducer/part/thermocouple/mod.rs similarity index 100% rename from src/transducer/thermocouple/mod.rs rename to src/transducer/part/thermocouple/mod.rs diff --git a/src/transducer/thermocouple/type_k.rs b/src/transducer/part/thermocouple/type_k.rs similarity index 100% rename from src/transducer/thermocouple/type_k.rs rename to src/transducer/part/thermocouple/type_k.rs