Nareshkumar Rao 4 weeks ago
commit
4c164fcb4d
  1. 1
      .gitignore
  2. 4
      .vscode/settings.json
  3. 15
      .vscode/tasks.json
  4. 67
      Cargo.lock
  5. 12
      Cargo.toml
  6. 100
      src/dht11.rs
  7. 24
      src/main.rs

1
.gitignore

@ -0,0 +1 @@
/target

4
.vscode/settings.json

@ -0,0 +1,4 @@
{
"editor.formatOnSave": true,
"rust-analyzer.check.command": "clippy"
}

15
.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"
}
]
}

67
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",
]

12
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"

100
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<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,
})
}
}

24
src/main.rs

@ -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…
Cancel
Save