Skip to content

Commit

Permalink
feat: add shared state button example
Browse files Browse the repository at this point in the history
  • Loading branch information
CosminPerRam committed Oct 7, 2024
1 parent a614532 commit d783f35
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 0 deletions.
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_pullup();

// 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(())
}

0 comments on commit d783f35

Please sign in to comment.