Initial node implementation #4
@ -7,6 +7,9 @@ repository.workspace = true
|
|||||||
readme.workspace = true
|
readme.workspace = true
|
||||||
license.workspace = true
|
license.workspace = true
|
||||||
|
|
||||||
|
[dependencies.physical]
|
||||||
|
path = "../.."
|
||||||
|
features = ["thermocouple_k"]
|
||||||
[dependencies.physical-node]
|
[dependencies.physical-node]
|
||||||
path = "../../node"
|
path = "../../node"
|
||||||
features = ["embassy-sync"]
|
features = ["embassy-sync"]
|
||||||
|
117
examples/ads1256/src/bin/thermocouple.rs
Normal file
117
examples/ads1256/src/bin/thermocouple.rs
Normal file
@ -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::<degree_celsius>(26.0);
|
||||||
|
|
||||||
|
// Zero test
|
||||||
|
let zero_voltage = f32::ElectricPotential::new::<millivolt>(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::<degree_celsius>();
|
||||||
|
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::<millivolt>();
|
||||||
|
let temperature =
|
||||||
|
thermocouple_k::convert(voltage, reference_temp, thermocouple_k::r_junction_offset_lin)
|
||||||
|
.unwrap();
|
||||||
|
let celsius = temperature.get::<degree_celsius>();
|
||||||
|
info!("Temperature in degrees celsius: {}, millivolts: {}", celsius, mv);
|
||||||
|
}
|
||||||
|
}
|
@ -1,4 +0,0 @@
|
|||||||
mod thermocouples;
|
|
||||||
|
|
||||||
#[cfg(feature = "thermocouple_k")]
|
|
||||||
pub use thermocouples::type_k as thermocouple_k;
|
|
@ -3,7 +3,10 @@ use crate::cell::CellView;
|
|||||||
|
|
||||||
pub mod input;
|
pub mod input;
|
||||||
pub mod output;
|
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
|
// Initialisation will always be async and won't complete until a state is available for all
|
||||||
// stateful transducers.
|
// stateful transducers.
|
||||||
|
@ -68,6 +68,7 @@ pub fn convert(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//TODO: This is not working, check libm pow.
|
||||||
pub fn r_junction_offset_poly(
|
pub fn r_junction_offset_poly(
|
||||||
temperature: f32::ThermodynamicTemperature,
|
temperature: f32::ThermodynamicTemperature,
|
||||||
) -> Result<f32::ElectricPotential, InvalidValue> {
|
) -> Result<f32::ElectricPotential, InvalidValue> {
|
Reference in New Issue
Block a user