Nareshkumar Rao
8 months ago
commit
4c164fcb4d
7 changed files with 223 additions and 0 deletions
@ -0,0 +1 @@ |
|||
/target |
@ -0,0 +1,4 @@ |
|||
{ |
|||
"editor.formatOnSave": true, |
|||
"rust-analyzer.check.command": "clippy" |
|||
} |
@ -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" |
|||
} |
|||
] |
|||
} |
@ -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", |
|||
] |
@ -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" |
@ -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<Dht11Sensor, Box<dyn Error>> { |
|||
let pin = Gpio::new()?.get(pin)?.into_io(rppal::gpio::Mode::Input); |
|||
Ok(Dht11Sensor { pin }) |
|||
} |
|||
|
|||
fn expect_pulse(&mut self, expected_level: bool) -> Result<Duration, Box<dyn Error>> { |
|||
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<Dht11Data, Box<dyn Error>> { |
|||
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, |
|||
}) |
|||
} |
|||
} |
@ -0,0 +1,24 @@ |
|||
use std::{error::Error, thread, time::Duration}; |
|||
|
|||
use dht11::Dht11Sensor; |
|||
|
|||
mod dht11; |
|||
|
|||
fn main() -> Result<(), Box<dyn Error>> { |
|||
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(()) |
|||
} |
Loading…
Reference in new issue