From abde12a8badd95314773de6ec1d961d782f6a6d2 Mon Sep 17 00:00:00 2001 From: Zachary Sunforge Date: Fri, 14 Jul 2023 20:35:39 -0700 Subject: [PATCH] Thermocouple example --- examples/ads1256/Cargo.toml | 3 + examples/ads1256/src/bin/thermocouple.rs | 117 ++++++++++++++++++ src/transducer/conversion/mod.rs | 4 - src/transducer/mod.rs | 5 +- .../thermocouples => thermocouple}/mod.rs | 0 .../thermocouples => thermocouple}/type_k.rs | 1 + 6 files changed, 125 insertions(+), 5 deletions(-) create mode 100644 examples/ads1256/src/bin/thermocouple.rs delete mode 100644 src/transducer/conversion/mod.rs rename src/transducer/{conversion/thermocouples => thermocouple}/mod.rs (100%) rename src/transducer/{conversion/thermocouples => thermocouple}/type_k.rs (99%) diff --git a/examples/ads1256/Cargo.toml b/examples/ads1256/Cargo.toml index c847d66..23fed7f 100644 --- a/examples/ads1256/Cargo.toml +++ b/examples/ads1256/Cargo.toml @@ -7,6 +7,9 @@ repository.workspace = true readme.workspace = true license.workspace = true +[dependencies.physical] +path = "../.." +features = ["thermocouple_k"] [dependencies.physical-node] path = "../../node" features = ["embassy-sync"] diff --git a/examples/ads1256/src/bin/thermocouple.rs b/examples/ads1256/src/bin/thermocouple.rs new file mode 100644 index 0000000..4e0e8a3 --- /dev/null +++ b/examples/ads1256/src/bin/thermocouple.rs @@ -0,0 +1,117 @@ +#![no_std] +#![no_main] +#![feature(type_alias_impl_trait, async_fn_in_trait)] + +use core::cell::Cell; +use cortex_m::prelude::{ + _embedded_hal_blocking_delay_DelayMs, _embedded_hal_blocking_delay_DelayUs, +}; +use {defmt_rtt as _, panic_probe as _}; + +use {embassy_executor as executor, embassy_stm32 as stm32}; + +use ads1256::standard::input::SingleEnded; +use ads1256::{ + AdControl, Ads1256, AutoCal, BitOrder, BlockingDelay, Buffer, ClockOut, Config, DState, + DataRate, DigitalIo, DigitalIoDirection, DigitalIoState, DioDirection, Gain, Multiplexer, + MuxInput, OutputPin, Sdcs, SpiBus, Status, Wait, +}; +use embassy_time::{Delay, Duration, Timer}; +use executor::Spawner; +use stm32::dma::NoDma; +use stm32::exti::ExtiInput; +use stm32::gpio::{Input, Level, Output, Pull, Speed}; +use stm32::spi::Spi; +use stm32::time::Hertz; +use stm32::{pac, spi}; + +use uom::si::electric_potential::{millivolt, volt}; +use uom::si::f32; + +use defmt::{debug, error, info, trace, unwrap}; +use physical::transducer::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), + ad_control: AdControl::setting(Gain::X64, Sdcs::Off, ClockOut::Off), + data_rate: DataRate::Sps2_5, + digital_io: DigitalIo::setting(DigitalIoState::default(), DigitalIoDirection::default()), +}; + +struct Ads1256Delay; + +impl ads1256::BlockingDelay for Ads1256Delay { + #[inline] + fn t6_delay(&mut self) { + Delay.delay_us(1u32); + } + + fn t11_1_delay(&mut self) {} + + fn t11_2_delay(&mut self) {} +} + +#[embassy_executor::main] +async fn main(spawner: Spawner) { + unsafe { + pac::FLASH.acr().modify(|v| { + v.set_prften(true); + v.set_icen(true); + v.set_dcen(true); + }); + } + + let p = embassy_stm32::init(Default::default()); + + let mut spi_conf = spi::Config::default(); + spi_conf.mode = spi::MODE_1; + spi_conf.bit_order = spi::BitOrder::MsbFirst; + + let ads1256_data_ready = ExtiInput::new(Input::new(p.PF6, Pull::Up), p.EXTI6); + let select_ads1256 = Output::new(p.PF7, Level::High, Speed::VeryHigh); + + let mut spi = Spi::new( + p.SPI3, + p.PC10, + p.PC12, + p.PC11, + NoDma, + NoDma, + Hertz(ads1256::defaults::SPI_CLK_HZ), + spi_conf, + ); + + let mut ads_1256 = Ads1256::new(Ads1256Delay, select_ads1256, ads1256_data_ready); + 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( + zero_voltage, + reference_temp, + thermocouple_k::r_junction_offset_lin, + ) + .unwrap(); + let zero_celsius = zero_temperature.get::(); + info!("Zero test: {}", zero_celsius); + + loop { + Delay.delay_ms(1_000u16); + let voltage = ads_1256 + .read_data(&mut spi) + .await + .unwrap() + .to_voltage(AUTOCAL_CONF.ad_control.gain()); + let mv = voltage.get::(); + let temperature = + thermocouple_k::convert(voltage, reference_temp, thermocouple_k::r_junction_offset_lin) + .unwrap(); + let celsius = temperature.get::(); + info!("Temperature in degrees celsius: {}, millivolts: {}", celsius, mv); + } +} diff --git a/src/transducer/conversion/mod.rs b/src/transducer/conversion/mod.rs deleted file mode 100644 index fe6f177..0000000 --- a/src/transducer/conversion/mod.rs +++ /dev/null @@ -1,4 +0,0 @@ -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/mod.rs b/src/transducer/mod.rs index 6f907f7..b0cdd72 100644 --- a/src/transducer/mod.rs +++ b/src/transducer/mod.rs @@ -3,7 +3,10 @@ use crate::cell::CellView; pub mod input; pub mod output; -mod conversion; +mod thermocouple; + +#[cfg(feature = "thermocouple_k")] +pub use thermocouple::type_k as thermocouple_k; // Initialisation will always be async and won't complete until a state is available for all // stateful transducers. diff --git a/src/transducer/conversion/thermocouples/mod.rs b/src/transducer/thermocouple/mod.rs similarity index 100% rename from src/transducer/conversion/thermocouples/mod.rs rename to src/transducer/thermocouple/mod.rs diff --git a/src/transducer/conversion/thermocouples/type_k.rs b/src/transducer/thermocouple/type_k.rs similarity index 99% rename from src/transducer/conversion/thermocouples/type_k.rs rename to src/transducer/thermocouple/type_k.rs index 7356d1d..d95edac 100644 --- a/src/transducer/conversion/thermocouples/type_k.rs +++ b/src/transducer/thermocouple/type_k.rs @@ -68,6 +68,7 @@ pub fn convert( } } +//TODO: This is not working, check libm pow. pub fn r_junction_offset_poly( temperature: f32::ThermodynamicTemperature, ) -> Result {