diff --git a/pod-operation/Cargo.lock b/pod-operation/Cargo.lock index 792e49c5..2fd5bab1 100644 --- a/pod-operation/Cargo.lock +++ b/pod-operation/Cargo.lock @@ -190,6 +190,32 @@ dependencies = [ "crypto-common", ] +[[package]] +name = "embedded-hal" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35949884794ad573cf46071e41c9b60efb0cb311e3ca01f7af807af1debc66ff" +dependencies = [ + "nb 0.1.3", + "void", +] + +[[package]] +name = "embedded-hal" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "361a90feb7004eca4019fb28352a9465666b24f840f5c3cddf0ff13920590b89" + +[[package]] +name = "embedded-hal-nb" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fba4268c14288c828995299e59b12babdbe170f6c6d73731af1b4648142e8605" +dependencies = [ + "embedded-hal 1.0.0", + "nb 1.1.0", +] + [[package]] name = "engineioxide" version = "0.7.2" @@ -416,6 +442,16 @@ dependencies = [ "unicode-normalization", ] +[[package]] +name = "ina219" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a93dcf42590b25525d79f7e497f3e8caf909ff8d53a2989b3c8d809980e647e" +dependencies = [ + "byteorder", + "embedded-hal 0.2.7", +] + [[package]] name = "itoa" version = "1.0.9" @@ -484,9 +520,24 @@ checksum = "3dce281c5e46beae905d4de1870d8b1509a9142b62eedf18b443b011ca8343d0" dependencies = [ "libc", "wasi", - "windows-sys", + "windows-sys 0.48.0", +] + +[[package]] +name = "nb" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "801d31da0513b6ec5214e9bf433a77966320625a37860f910be265be6e18d06f" +dependencies = [ + "nb 1.1.0", ] +[[package]] +name = "nb" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d5439c4ad607c3c23abf66de8c8bf57ba8adcd1f129e699851a6e43935d339d" + [[package]] name = "nu-ansi-term" version = "0.46.0" @@ -571,6 +622,7 @@ name = "pod-operation" version = "0.1.0" dependencies = [ "axum", + "ina219", "rppal", "serde", "serde_json", @@ -684,7 +736,13 @@ version = "0.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1dc171bbe325b04172e18d917c58c2cf1fb5adfd9ffabb1d6b3d62ba4c1c1331" dependencies = [ + "embedded-hal 0.2.7", + "embedded-hal 1.0.0", + "embedded-hal-nb", "libc", + "nb 0.1.3", + "spin_sleep", + "void", ] [[package]] @@ -810,7 +868,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9" dependencies = [ "libc", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -831,6 +889,15 @@ dependencies = [ "tower", ] +[[package]] +name = "spin_sleep" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "368a978649eaf70006b082e79c832bd72556ac1393eaf564d686e919dca2347f" +dependencies = [ + "windows-sys 0.52.0", +] + [[package]] name = "syn" version = "2.0.39" @@ -907,7 +974,7 @@ dependencies = [ "pin-project-lite", "socket2 0.5.5", "tokio-macros", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -1104,6 +1171,12 @@ version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +[[package]] +name = "void" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" + [[package]] name = "want" version = "0.3.1" @@ -1147,7 +1220,16 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" dependencies = [ - "windows-targets", + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.4", ] [[package]] @@ -1156,13 +1238,28 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", +] + +[[package]] +name = "windows-targets" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7dd37b7e5ab9018759f893a1952c9420d060016fc19a472b4bb20d1bdd694d1b" +dependencies = [ + "windows_aarch64_gnullvm 0.52.4", + "windows_aarch64_msvc 0.52.4", + "windows_i686_gnu 0.52.4", + "windows_i686_msvc 0.52.4", + "windows_x86_64_gnu 0.52.4", + "windows_x86_64_gnullvm 0.52.4", + "windows_x86_64_msvc 0.52.4", ] [[package]] @@ -1171,38 +1268,80 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bcf46cf4c365c6f2d1cc93ce535f2c8b244591df96ceee75d8e83deb70a9cac9" + [[package]] name = "windows_aarch64_msvc" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da9f259dd3bcf6990b55bffd094c4f7235817ba4ceebde8e6d11cd0c5633b675" + [[package]] name = "windows_i686_gnu" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" +[[package]] +name = "windows_i686_gnu" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b474d8268f99e0995f25b9f095bc7434632601028cf86590aea5c8a5cb7801d3" + [[package]] name = "windows_i686_msvc" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" +[[package]] +name = "windows_i686_msvc" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1515e9a29e5bed743cb4415a9ecf5dfca648ce85ee42e15873c3cd8610ff8e02" + [[package]] name = "windows_x86_64_gnu" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5eee091590e89cc02ad514ffe3ead9eb6b660aedca2183455434b93546371a03" + [[package]] name = "windows_x86_64_gnullvm" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77ca79f2451b49fa9e2af39f0747fe999fcda4f5e241b2898624dca97a1f2177" + [[package]] name = "windows_x86_64_msvc" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8" diff --git a/pod-operation/Cargo.toml b/pod-operation/Cargo.toml index 5d2be951..48a22a62 100644 --- a/pod-operation/Cargo.toml +++ b/pod-operation/Cargo.toml @@ -13,4 +13,5 @@ serde = { version = "1.0.192", features = ["derive"] } serde_json = "1.0.108" tracing = "0.1.40" tracing-subscriber = { version = "0.3.17", features = ["env-filter"] } -rppal = "0.17.1" +rppal = { version = "0.17.1", features = ["hal"] } +ina219 = "0.1.0" diff --git a/pod-operation/src/components/mod.rs b/pod-operation/src/components/mod.rs index 176dfe09..70272349 100644 --- a/pod-operation/src/components/mod.rs +++ b/pod-operation/src/components/mod.rs @@ -1 +1,2 @@ +pub mod pressure_transducer; pub mod signal_light; diff --git a/pod-operation/src/components/pressure_transducer.rs b/pod-operation/src/components/pressure_transducer.rs new file mode 100644 index 00000000..c3fa2c6c --- /dev/null +++ b/pod-operation/src/components/pressure_transducer.rs @@ -0,0 +1,57 @@ +use ina219::INA219; +use rppal::i2c::I2c; +use tracing::debug; + +pub struct PressureTransducer { + ina: INA219, +} + +// The calibration value is used to adjust the maximum current measurement +// and precision of measurements. +const INA219_CALIBRATION_VALUE: u16 = 0xffff; + +// Even with the calibration values, the readings from the INA219 are not in +// mA. A scaling factor is needed in order to convert the raw reading to mA and +// this is not provided in the INA219 library that we are using. Note that this +// value changes according to the calibration value. The exact formula can be +// found in the INA219 datasheet. +const INA219_SCALING_VALUE: f32 = 160.0; + +// The pressure transducer outputs a current between 4 mA and 20 mA with 0 PSI +// and 300 PSI respectively. Assuming a linear interpolation, a 1 mA increase +// results in a 18.75 PSI increase. +const REF_CURRENT_LOW: f32 = 4.0; +const REF_CURRENT_HIGH: f32 = 20.0; +const REF_PRESSURE_LOW: f32 = 0.0; +const REF_PRESSURE_HIGH: f32 = 300.0; + +const REF_CURRENT_SPAN: f32 = REF_CURRENT_HIGH - REF_CURRENT_LOW; +const REF_PRESSURE_SPAN: f32 = REF_PRESSURE_HIGH - REF_PRESSURE_LOW; + +impl PressureTransducer { + pub fn new(ina219_addr: u8) -> Self { + let device = I2c::new().unwrap(); + + let mut ina219 = INA219::new(device, ina219_addr); + debug!("Initialized I2C and INA219"); + + ina219.calibrate(INA219_CALIBRATION_VALUE).unwrap(); + debug!("Calibrating INA219"); + + PressureTransducer { ina: ina219 } + } + + // Read current from the INA219 and apply a scaling factor to translate + // the current reading to PSI. + pub fn read(&mut self) -> f32 { + let current = self.read_current(); + + REF_PRESSURE_LOW + REF_PRESSURE_SPAN * (current - REF_CURRENT_LOW) / REF_CURRENT_SPAN + } + + // Read from the INA219 and divide the reading by a scalar factor to + // convert the reading to mA. + fn read_current(&mut self) -> f32 { + f32::from(self.ina.current().unwrap()) / INA219_SCALING_VALUE + } +} diff --git a/pod-operation/src/demo.rs b/pod-operation/src/demo.rs index dc8532a8..64691485 100644 --- a/pod-operation/src/demo.rs +++ b/pod-operation/src/demo.rs @@ -1,5 +1,6 @@ use tracing::info; +use crate::components::pressure_transducer::PressureTransducer; use crate::components::signal_light::SignalLight; pub async fn blink(mut signal_light: SignalLight) { @@ -17,3 +18,12 @@ pub async fn blink(mut signal_light: SignalLight) { i += 1; } } + +pub async fn read_pressure_transducer(mut pressure_transducer: PressureTransducer) { + info!("Starting pressure transducer demo."); + + loop { + tokio::time::sleep(std::time::Duration::new(1, 0)).await; + println!("{:?}", pressure_transducer.read()); + } +} diff --git a/pod-operation/src/main.rs b/pod-operation/src/main.rs index 53163b1c..a525de8e 100644 --- a/pod-operation/src/main.rs +++ b/pod-operation/src/main.rs @@ -7,6 +7,7 @@ mod components; mod demo; mod handlers; +use crate::components::pressure_transducer::PressureTransducer; use crate::components::signal_light::SignalLight; #[tokio::main] @@ -23,6 +24,9 @@ async fn main() -> Result<(), Box> { let signal_light = SignalLight::new(); tokio::spawn(demo::blink(signal_light)); + let pressure_transducer = PressureTransducer::new(0x40); + tokio::spawn(demo::read_pressure_transducer(pressure_transducer)); + let app = axum::Router::new().layer(layer); info!("Starting server on port 5000");