commit 4c164fcb4d6e8d097c1612805ea1d042df70ec13 Author: Nareshkumar Rao Date: Sat Apr 20 23:43:17 2024 +0200 wip diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ea8c4bf --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/target diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..1570300 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,4 @@ +{ + "editor.formatOnSave": true, + "rust-analyzer.check.command": "clippy" +} \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 0000000..3b743c7 --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,15 @@ +{ + "version": "2.0.0", + "tasks": [ + { + "type": "process", + "command": "cross", + "args": ["build", "--target","arm-unknown-linux-gnueabihf"], + "problemMatcher": [ + "$rustc" + ], + "group": "build", + "label": "rust: cargo build" + } + ] +} \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..443fe9d --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,67 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "bitflags" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "cfg_aliases" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" + +[[package]] +name = "interrupts" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1ccb0bdc9cefc5772ebc23d9bd94aabf408ab6753735f1936ac6ed7e714c8c6" +dependencies = [ + "cfg-if", + "nix", +] + +[[package]] +name = "libc" +version = "0.2.153" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" + +[[package]] +name = "nix" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab2156c4fce2f8df6c499cc1c763e4394b7482525bf2a9701c9d79d215f519e4" +dependencies = [ + "bitflags", + "cfg-if", + "cfg_aliases", + "libc", +] + +[[package]] +name = "rpitest" +version = "0.1.0" +dependencies = [ + "interrupts", + "libc", + "rppal", +] + +[[package]] +name = "rppal" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1dc171bbe325b04172e18d917c58c2cf1fb5adfd9ffabb1d6b3d62ba4c1c1331" +dependencies = [ + "libc", +] diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..09f9697 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "rpitest" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +rppal = "0.17.1" +#rumqttc = "0.24.0" +interrupts = "0.1.5" +libc = "0.2.153" diff --git a/src/dht11.rs b/src/dht11.rs new file mode 100644 index 0000000..7d021ff --- /dev/null +++ b/src/dht11.rs @@ -0,0 +1,100 @@ +use std::{ + error::Error, + thread, + time::{Duration, Instant}, +}; + +use rppal::gpio::Gpio; + +pub struct Dht11Data { + pub temperature: f32, + pub humidity: f32, +} +pub struct Dht11Sensor { + pin: rppal::gpio::IoPin, +} +impl Dht11Sensor { + pub fn new(pin: u8) -> Result> { + let pin = Gpio::new()?.get(pin)?.into_io(rppal::gpio::Mode::Input); + Ok(Dht11Sensor { pin }) + } + + fn expect_pulse(&mut self, expected_level: bool) -> Result> { + let started = Instant::now(); + loop { + if self.pin.is_high() != expected_level { + break; + } + if started.elapsed() >= Duration::from_micros(1000) { + return Err(std::io::Error::new( + std::io::ErrorKind::InvalidData, + "Timeout while reading pulse", + ) + .into()); + } + + thread::sleep(Duration::from_micros(1)); + } + Ok(started.elapsed()) + } + + pub fn read(&mut self) -> Result> { + use rppal::gpio::{Bias, Mode}; + + let mut data = [0; 5]; + let mut cycles: [Duration; 80] = [Duration::from_micros(0); 80]; + + let guard = interrupts::disable(); + + self.pin.set_mode(Mode::Input); + self.pin.set_bias(Bias::PullUp); + thread::sleep(Duration::from_millis(1)); + + self.pin.set_mode(Mode::Output); + self.pin.set_low(); + thread::sleep(Duration::from_millis(20)); + + // Timing Critical Code + self.pin.set_mode(Mode::Input); + self.pin.set_bias(Bias::PullUp); + thread::sleep(Duration::from_micros(55)); + + self.expect_pulse(false)?; + self.expect_pulse(true)?; + for i in (0..80).step_by(2) { + cycles[i] = self.expect_pulse(false)?; + cycles[i + 1] = self.expect_pulse(true)?; + } + + for i in 0..40 { + let low_cycles = cycles[2 * i]; + let high_cycles = cycles[2 * i + 1]; + data[i / 8] <<= 1; + if high_cycles > low_cycles { + data[i / 8] |= 1; + } + } + + if data[4] != ((data[0] + data[1] + data[2] + data[3]) & 0xFF) { + return Err(std::io::Error::new( + std::io::ErrorKind::InvalidData, + "DHT Checksum Failure", + ) + .into()); + } + + let mut temperature = data[2] as f32; + if data[3] & 0x80 != 0 { + temperature = -1. - temperature; + } + temperature += ((data[3] & 0x0F) as f32) * 0.1; + + let mut humidity = data[0] as f32; + humidity += (data[1] as f32) * 0.1; + + Ok(Dht11Data { + temperature, + humidity, + }) + } +} diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..833e429 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,24 @@ +use std::{error::Error, thread, time::Duration}; + +use dht11::Dht11Sensor; + +mod dht11; + +fn main() -> Result<(), Box> { + unsafe { + libc::setpriority(libc::PRIO_PROCESS, 0, -20); + } + let mut sensor = Dht11Sensor::new(2)?; + loop { + match sensor.read() { + Ok(data) => println!( + "Humidity: {}; Temperature: {}", + data.humidity, data.temperature + ), + Err(msg) => println!("Error: {}", msg), + } + thread::sleep(Duration::from_millis(2000)); + } + + Ok(()) +}