move to gpiocdev

This commit is contained in:
FliegendeWurst 2023-10-03 14:25:25 +02:00
parent c17424a686
commit 6aeaee2fc1
5 changed files with 1290 additions and 101 deletions

1301
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -11,7 +11,6 @@ embedded-graphics = "0.7.1"
linux-embedded-hal = "0.3.0"
embedded-hal = "0.2.5"
libc = "0.2.98"
gpio-cdev = "0.4"
rusqlite = "0.27.0"
time = { version = "0.3.9", features = ["parsing"] }
time-tz = "1.0.1"
@ -23,8 +22,16 @@ rppal = { version = "0.13.1", features = ["hal"] }
ssd1351 = { git = "https://github.com/FliegendeWurst/ssd1351-rust" }
display-interface-spi = "0.4.1"
ureq = { version = "2.4.0", default-features = false }
winit = { version = "0.28.7", optional = true }
softbuffer = { version = "0.3.1", optional = true }
rand_xoshiro = "0.6.0"
gpiocdev = "0.6.0"
#gpio-am2302-rs = { git = "https://github.com/FliegendeWurst/gpio-am2302-rs" }
[features]
pc = ["winit", "softbuffer"]
default = [ "pc" ]
[profile.release]
codegen-units = 1
debug = true

View File

@ -17,7 +17,6 @@ use embedded_graphics::{
Drawable,
};
use embedded_hal::digital::v2::OutputPin;
use gpio_cdev::{Chip, LineHandle, LineRequestFlags};
use image::{ImageBuffer, Rgb};
use linux_embedded_hal::I2cdev;
use rppal::{
@ -86,17 +85,3 @@ fn main() {
disp.reset(&mut rst, &mut Delay).unwrap();
disp.turn_off().unwrap();
}
struct LineHandleWrapper(LineHandle);
impl OutputPin for LineHandleWrapper {
type Error = gpio_cdev::Error;
fn set_low(&mut self) -> Result<(), Self::Error> {
self.0.set_value(0)
}
fn set_high(&mut self) -> Result<(), Self::Error> {
self.0.set_value(1)
}
}

View File

@ -1,6 +1,5 @@
use std::time::{Duration, SystemTime};
use gpio_cdev::Chip;
use rusqlite::{params, Connection};
fn main() {
@ -21,8 +20,6 @@ fn main() {
)
.unwrap();
let mut chip = Chip::new("/dev/gpiochip0").unwrap();
let line = chip.get_line(26).unwrap();
let mut attempts = 0;
let mut temps = vec![];
let mut rhs = vec![];
@ -30,7 +27,7 @@ fn main() {
.duration_since(SystemTime::UNIX_EPOCH)
.unwrap();
while temps.len() < 5 && attempts < 10 {
if let Ok((rh, temp)) = raspi_oled::am2302_reading(&line) {
if let Ok((rh, temp)) = raspi_oled::am2302_reading() {
// TODO: try out gpio_am2302_rs!
//if let Ok(reading) = gpio_am2302_rs::try_read(26) {
//let rh = reading.humidity as i64;
@ -49,7 +46,14 @@ fn main() {
rhs.sort();
let rh = rhs[rhs.len() / 2];
let temp = temps[temps.len() / 2];
println!("info: acquired {} readings (temps {:?}, rhs {:?}), using rh {} and temp {}", temps.len(), temps, rhs, rh, temp);
println!(
"info: acquired {} readings (temps {:?}, rhs {:?}), using rh {} and temp {}",
temps.len(),
temps,
rhs,
rh,
temp
);
database
.execute(
"INSERT INTO sensor_readings (time, humidity, celsius) VALUES (?1, ?2, ?3)",

View File

@ -8,7 +8,7 @@ use embedded_graphics::{
pixelcolor::Rgb565,
prelude::{OriginDimensions, RgbColor, Size},
};
use gpio_cdev::{EventType, Line, LineRequestFlags};
use gpiocdev::line::{Bias, EdgeDetection, EdgeKind, Value};
use image::{ImageBuffer, Rgb};
pub struct FrameOutput {
@ -55,24 +55,22 @@ impl OriginDimensions for FrameOutput {
}
}
fn read_events(line: &gpio_cdev::Line, timeout: std::time::Duration) -> Result<Vec<(u64, EventType)>, SensorError> {
let input = line.request(LineRequestFlags::INPUT, 0, "read-data")?;
fn read_events(timeout: std::time::Duration) -> Result<Vec<(u64, EdgeKind)>, SensorError> {
let input = gpiocdev::Request::builder()
.on_chip("/dev/gpiochip0")
.with_line(26)
.as_input()
.with_edge_detection(EdgeDetection::BothEdges)
.with_bias(Bias::PullDown)
.request()?;
let mut last_state = 1;
let start = time::Instant::now();
let mut events = Vec::with_capacity(81);
while start.elapsed() < timeout && events.len() < 81 {
let new_state = input.get_value()?;
if new_state != last_state {
let timestamp = start.elapsed();
let event_type = if last_state < new_state {
EventType::RisingEdge
} else {
EventType::FallingEdge
};
events.push((timestamp.as_micros() as u64, event_type));
last_state = new_state;
if input.wait_edge_event(timeout)? {
let event = input.read_edge_event()?;
events.push((start.elapsed().as_micros() as u64, event.kind));
}
}
if events.len() < 81 {
@ -82,15 +80,15 @@ fn read_events(line: &gpio_cdev::Line, timeout: std::time::Duration) -> Result<V
Ok(events)
}
fn events_to_data(events: Vec<(u64, EventType)>) -> Vec<u8> {
fn events_to_data(events: Vec<(u64, EdgeKind)>) -> Vec<u8> {
events[1..]
.windows(2)
.map(|pair| {
let prev = pair.get(0).unwrap();
let next = pair.get(1).unwrap();
match next.1 {
EventType::FallingEdge => Some(next.0 - prev.0),
EventType::RisingEdge => None,
EdgeKind::Falling => Some(next.0 - prev.0),
EdgeKind::Rising => None,
}
})
.filter(|&d| d.is_some())
@ -150,29 +148,33 @@ fn test_process_data() {
#[derive(Debug)]
pub enum SensorError {
Io(gpio_cdev::Error),
Io(gpiocdev::Error),
ChecksumMismatch,
HumidityTooHigh,
Timeout,
}
impl From<gpio_cdev::Error> for SensorError {
fn from(error: gpio_cdev::Error) -> Self {
impl From<gpiocdev::Error> for SensorError {
fn from(error: gpiocdev::Error) -> Self {
SensorError::Io(error)
}
}
pub fn am2302_reading(line: &Line) -> Result<(u16, u16), SensorError> {
let out = line.request(LineRequestFlags::OUTPUT, 1, "rust-am2302").unwrap();
out.set_value(1)?;
pub fn am2302_reading() -> Result<(u16, u16), SensorError> {
let mut out = gpiocdev::Request::builder()
.on_chip("/dev/gpiochip0")
.with_line(26)
.as_output(Value::Active)
.request()?;
out.set_value(26, Value::Active)?;
sleep(Duration::from_millis(500));
set_max_priority();
// set low for 20 ms
out.set_value(0)?;
out.set_value(26, Value::Inactive)?;
sleep(Duration::from_millis(3));
drop(out);
let events = read_events(&line, Duration::from_secs(1));
let events = read_events(Duration::from_secs(1));
println!("{:?} {:?}", events, events.as_ref().map(|x| x.len()));
set_normal_priority();
let events = events?;