Added LM35

This commit is contained in:
Zachary Sunforge
2023-07-18 19:52:50 -07:00
parent 45bc1707e9
commit 5e46116976
8 changed files with 64 additions and 19 deletions

View File

@ -128,6 +128,7 @@ license.workspace = true
[features] [features]
thermocouple_k = [] thermocouple_k = []
lm35 = []
[dependencies] [dependencies]
uom = { workspace = true } uom = { workspace = true }

View File

@ -9,7 +9,7 @@ license.workspace = true
[dependencies.physical] [dependencies.physical]
path = "../.." path = "../.."
features = ["thermocouple_k"] features = ["thermocouple_k", "lm35"]
[dependencies.physical-node] [dependencies.physical-node]
path = "../../node" path = "../../node"
features = ["embassy-sync"] features = ["embassy-sync"]

View File

@ -10,7 +10,7 @@ use {defmt_rtt as _, panic_probe as _};
use {embassy_executor as executor, embassy_stm32 as stm32}; use {embassy_executor as executor, embassy_stm32 as stm32};
use ads1256::standard::input::SingleEnded; use ads1256::standard::input::{Differential, SingleEnded};
use ads1256::{ use ads1256::{
AdControl, Ads1256, AutoCal, BitOrder, BlockingDelay, Buffer, ClockOut, Config, DState, AdControl, Ads1256, AutoCal, BitOrder, BlockingDelay, Buffer, ClockOut, Config, DState,
DataRate, DigitalIo, DigitalIoDirection, DigitalIoState, DioDirection, Gain, Multiplexer, DataRate, DigitalIo, DigitalIoDirection, DigitalIoState, DioDirection, Gain, Multiplexer,
@ -29,12 +29,12 @@ use uom::si::electric_potential::{millivolt, volt};
use uom::si::f32; use uom::si::f32;
use defmt::{debug, error, info, trace, unwrap}; 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; use uom::si::thermodynamic_temperature::degree_celsius;
const AUTOCAL_CONF: Config = Config { const AUTOCAL_CONF: Config = Config {
status: Status::setting(Buffer::Enabled, AutoCal::Enabled, BitOrder::MostSigFirst), 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), ad_control: AdControl::setting(Gain::X64, Sdcs::Off, ClockOut::Off),
data_rate: DataRate::Sps2_5, data_rate: DataRate::Sps2_5,
digital_io: DigitalIo::setting(DigitalIoState::default(), DigitalIoDirection::default()), 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.write_config(&mut spi, AUTOCAL_CONF).unwrap();
ads_1256.self_calibrate(&mut spi).await.unwrap(); ads_1256.self_calibrate(&mut spi).await.unwrap();
let reference_temp = f32::ThermodynamicTemperature::new::<degree_celsius>(26.0);
// Zero test
let zero_voltage = f32::ElectricPotential::new::<millivolt>(0.0);
let zero_temperature = thermocouple_k::convert_direct(zero_voltage, reference_temp).unwrap();
let zero_celsius = zero_temperature.get::<degree_celsius>();
info!("Zero test: {}", zero_celsius);
loop { 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::<degree_celsius>();
info!("Reference junction temperature in degrees celsius: {}", reference_celsius);
let gain = Gain::X64;
let voltage = ads_1256 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 .await
.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 = thermocouple_k::convert_direct(voltage, reference_temp).unwrap(); let temperature = thermocouple_k::convert_direct(voltage, reference).unwrap();
let celsius = temperature.get::<degree_celsius>(); let celsius = temperature.get::<degree_celsius>();
info!("Temperature in degrees celsius: {}, millivolts: {}", celsius, mv); info!("Thermocouple temperature in degrees celsius: {}, millivolts: {}", celsius, mv);
} }
} }

View File

@ -3,10 +3,9 @@ use crate::cell::CellView;
pub mod input; pub mod input;
pub mod output; pub mod output;
mod thermocouple; mod part;
#[cfg(feature = "thermocouple_k")] pub use part::*;
pub use thermocouple::type_k as thermocouple_k;
// Initialisation will always be async and won't complete until a state is available for all // Initialisation will always be async and won't complete until a state is available for all
// stateful transducers. // stateful transducers.

View File

@ -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<f32::ThermodynamicTemperature, InvalidValue> {
let volts = voltage.get::<volt>();
if volts >= MIN_VOLTS && volts <= MAX_VOLTS {
let celsius = volts * SCALE_FACTOR;
Ok(f32::ThermodynamicTemperature::new::<degree_celsius>(celsius))
} else {
Err(InvalidValue)
}
}

View File

@ -0,0 +1,7 @@
mod thermocouple;
#[cfg(feature = "lm35")]
pub mod lm35;
#[cfg(feature = "thermocouple_k")]
pub use thermocouple::type_k as thermocouple_k;