Abgabe
This commit is contained in:
96
kawaii/kawaii-rs/dependencies/emergency-stop/src/lib.rs
Normal file
96
kawaii/kawaii-rs/dependencies/emergency-stop/src/lib.rs
Normal file
@@ -0,0 +1,96 @@
|
||||
extern crate kawaii;
|
||||
|
||||
use std::time::Duration;
|
||||
use std::thread;
|
||||
use std::thread::JoinHandle;
|
||||
use std::sync::Arc;
|
||||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
|
||||
use self::kawaii::gpio::{AsyncPort, Edge, Value};
|
||||
|
||||
#[cfg(feature = "measure")]
|
||||
use self::kawaii::Measure;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct EmergencyStop {
|
||||
thread: Option<JoinHandle<()>>,
|
||||
pub state: Arc<AtomicBool>,
|
||||
}
|
||||
|
||||
impl EmergencyStop {
|
||||
pub fn new(stop_port: u8) -> std::io::Result<Self> {
|
||||
let name = format!("EmergencyStop(port = {})", stop_port);
|
||||
let state = Arc::new(AtomicBool::new(false));
|
||||
let mut port = AsyncPort::new(stop_port, Edge::Both)?;
|
||||
|
||||
let state_clone = state.clone();
|
||||
let thread = thread::Builder::new()
|
||||
.name(name)
|
||||
.spawn(move || EmergencyStop::thread(&mut port, state_clone))?;
|
||||
|
||||
Ok(EmergencyStop {
|
||||
thread: Some(thread),
|
||||
state: state,
|
||||
})
|
||||
}
|
||||
|
||||
fn thread(port: &mut AsyncPort, state: Arc<AtomicBool>) {
|
||||
#[cfg(feature = "measure")]
|
||||
let mut measure = Measure::new(format!("EmergencyStop(port = {})", port.port.number));
|
||||
|
||||
// clear first value
|
||||
port.poll(Some(Duration::new(0, 0))).is_ok();
|
||||
|
||||
while !state.load(Ordering::Relaxed) {
|
||||
#[cfg(feature = "measure")]
|
||||
measure.start();
|
||||
|
||||
let timeout = Some(Duration::new(1, 0));
|
||||
|
||||
#[cfg(not(feature = "measure"))]
|
||||
let value = port.poll(timeout);
|
||||
|
||||
#[cfg(feature = "measure")]
|
||||
let value = port.poll_measure(timeout, &mut measure);
|
||||
|
||||
// continue on timeout
|
||||
match value {
|
||||
Ok(value) => {
|
||||
if let Some(value) = value {
|
||||
match value {
|
||||
Value::High => {
|
||||
#[cfg(debug_assertions)]
|
||||
println!("EmergencyStop! ({:?})", value);
|
||||
|
||||
state.store(true, Ordering::Relaxed);
|
||||
}
|
||||
_ => {
|
||||
#[cfg(debug_assertions)]
|
||||
println!("EmergencyStop ignored: ({:?})", value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
#[cfg(debug_assertions)]
|
||||
println!("EmergencyStop! ({:?})", e);
|
||||
|
||||
state.store(true, Ordering::Relaxed);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "measure")]
|
||||
measure.stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for EmergencyStop {
|
||||
fn drop(&mut self) {
|
||||
self.state.store(true, Ordering::Relaxed);
|
||||
|
||||
if let Some(thread) = self.thread.take() {
|
||||
thread.join().is_ok();
|
||||
}
|
||||
}
|
||||
}
|
||||
21
kawaii/kawaii-rs/dependencies/emergency-stop/src/main.rs
Normal file
21
kawaii/kawaii-rs/dependencies/emergency-stop/src/main.rs
Normal file
@@ -0,0 +1,21 @@
|
||||
extern crate emergency_stop;
|
||||
|
||||
use emergency_stop::EmergencyStop;
|
||||
|
||||
use std::time::Duration;
|
||||
use std::thread::sleep;
|
||||
use std::sync::atomic::Ordering;
|
||||
|
||||
static GPIO_PORT_STOP: u8 = 25;
|
||||
|
||||
fn main() {
|
||||
let emergency_stop = EmergencyStop::new(GPIO_PORT_STOP).expect("Create Emergency Stop failed");
|
||||
|
||||
println!("{:?}", emergency_stop);
|
||||
|
||||
while !emergency_stop.state.load(Ordering::Relaxed) {
|
||||
sleep(Duration::new(1, 0));
|
||||
}
|
||||
|
||||
println!("Stopped.");
|
||||
}
|
||||
Reference in New Issue
Block a user