Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add shared state button example #160

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ Before running any examples that interface with external components, read throug

`gpio_status.rs` - Retrieves the mode and logic level for each of the pins on the 26-pin or 40-pin GPIO header, and displays the results in an ASCII table.

`gpio_shared_button_state.rs` - Shares a state with an input interrupt, stops the program until N event changes.

`i2c_ds3231.rs` - Sets and retrieves the time on a Maxim Integrated DS3231 RTC using I2C.

`pwm_blinkled.rs` - Blinks an LED using hardware PWM.
Expand Down
52 changes: 52 additions & 0 deletions examples/gpio_shared_button_state.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// gpio_shared_button_state.rs - Stops the program until a certain amount of event input changes via
// a non-global shared variable (that can be done using OnceCell for example), this requires a Mutex
// as it goes across threads and Arc to make sure we have the same entry everywhere.

use std::error::Error;
use std::sync::{Arc, Mutex};
use std::time::Duration;
use rppal::gpio::{Gpio, Event, Trigger};

const INPUT_PIN_GPIO: u8 = 27;
const STOP_AFTER_N_CHANGES: u8 = 5;

// The function we will run upon a Trigger
fn input_callback(event: Event, my_data: Arc<Mutex<u8>>) {
println!("Event: {:?}", event);
*my_data.lock().unwrap() += 1;
}

fn main() -> Result<(), Box<dyn Error>> {
// Initialize our data, in this case it's just a number.
let shared_state = Arc::new(Mutex::new(0));

// Configure the input pin.
let mut input_pin = Gpio::new()?.get(INPUT_PIN_GPIO)?.into_input_pulldown();

// We need to clone this as set_async_interrupt will move it and cant be used afterward if so
let shared_state_hold = shared_state.clone();
input_pin.set_async_interrupt(
Trigger::FallingEdge,
Some(Duration::from_millis(50)),
move |event| {
// Note: you can also add more parameters here!
input_callback(event, shared_state_hold.clone());
},
)?;

// We check constantly if we have reached our number of changes.
loop {
if *shared_state.lock().unwrap() >= STOP_AFTER_N_CHANGES {
// Reached it, exiting the program.
println!("Reached {STOP_AFTER_N_CHANGES} events, exiting...");
break;
}

// Suppose we do some work here that takes a second, the shorter the work takes, the quicker
// we will quit upon reaching our condition.
println!("Still waiting...");
std::thread::sleep(Duration::from_secs(1));
}

Ok(())
}
Loading