Configure and monitor a 4x4 matrix keyboard with real-time key detection
This example demonstrates matrix keyboard configuration and monitoring using the PoKeys Core Library. Matrix keyboards allow scanning multiple keys using fewer pins by organizing them in a row/column grid.
use pokeys_lib::*;
use std::thread;
use std::time::Duration;
fn main() -> Result<()> {
println!("Matrix Keyboard Example");
// Connect to first available device
let mut device = connect_to_device(0)?;
println!("Connected to PoKeys device");
// Configure 4x4 matrix keyboard
let column_pins = [5, 6, 7, 8]; // Column pins 5-8
let row_pins = [1, 2, 3, 4]; // Row pins 1-4
device.configure_matrix_keyboard(4, 4, &column_pins, &row_pins)?;
println!("Matrix keyboard configured successfully!");
// Monitor for key presses
let mut previous_states = vec![vec![false; 4]; 4];
println!("Monitoring keyboard - press keys to see output...");
loop {
// Read current keyboard state
device.read_matrix_keyboard()?;
// Check each key position for changes
for row in 0..4 {
for col in 0..4 {
let current_state = device.matrix_keyboard.get_key_state(row, col);
// Detect state changes
if current_state != previous_states[row][col] {
if current_state {
println!("Key PRESSED at position ({}, {})", row, col);
} else {
println!("Key RELEASED at position ({}, {})", row, col);
}
previous_states[row][col] = current_state;
}
}
}
// Small delay to avoid overwhelming output
thread::sleep(Duration::from_millis(50));
}
} let mut device = connect_to_device(0)?;
Connects to the first available PoKeys device. The device object provides access to all matrix keyboard functions.
The mut keyword is required for modifying device state.
let column_pins = [5, 6, 7, 8]; // Column pins
let row_pins = [1, 2, 3, 4]; // Row pins
device.configure_matrix_keyboard(4, 4, &column_pins, &row_pins)?; Configures a 4x4 matrix keyboard by specifying which pins control rows and columns. Rows are outputs (driven by the device), columns are inputs (read by the device).
device.read_matrix_keyboard()?;
let current_state = device.matrix_keyboard.get_key_state(row, col);
Reads the current state of all keys in the matrix. Each key position (row, col) returns
true when pressed, false when released.
if current_state != previous_states[row][col] {
if current_state {
println!("Key PRESSED at position ({}, {})", row, col);
} else {
println!("Key RELEASED at position ({}, {})", row, col);
}
} Compares current key states with previous states to detect press and release events. Only prints when a key state actually changes to avoid spam.
The example uses Rust's ? operator for error handling.
Here's how to handle specific errors:
// More detailed error handling
match enumerate_usb_devices() {
Ok(count) if count == 0 => {
eprintln!("No devices found. Check connections.");
return Ok(());
},
Ok(count) => println!("Found {} devices", count),
Err(e) => {
eprintln!("Failed to enumerate devices: {}", e);
return Err(e.into());
}
}