Beginner Digital I/O

Matrix Keyboard

Configure and monitor a 4x4 matrix keyboard with real-time key detection

Overview

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.

  • Matrix configuration - Setting up 4x4 keyboard layout
  • Pin assignment - Configuring row and column pins
  • Real-time monitoring - Detecting key press/release events
  • State tracking - Monitoring key state changes

Hardware Setup

Required Hardware

  • • PoKeys device (any model)
  • • LED with current-limiting resistor
  • • Breadboard and jumper wires
  • • USB cable for connection

Connections

  • • LED anode → Pin 1
  • • LED cathode → 220Ω resistor → GND
  • • PoKeys device → USB port

Complete Example

matrix_keyboard.rs
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));
    }
}

Code Explanation

1. Device Connection

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.

2. Matrix Configuration

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).

3. State Monitoring

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.

4. Change Detection

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.

Error Handling

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

Troubleshooting

Common Issues

No devices found

  • • Check USB cable connection
  • • Verify device has power (LED indicators)
  • • Install PoKeys USB drivers
  • • Try a different USB port

Connection failed

  • • Device may be in use by another application
  • • Try unplugging and reconnecting the device
  • • Check device permissions on Linux

LED doesn't blink

  • • Verify LED polarity (anode to pin, cathode to GND)
  • • Check resistor value (220Ω recommended)
  • • Ensure pin 1 is available on your device model

Next Steps