Matrix
The keyboard matrix is the core hardware system responsible for scanning switches and detecting key presses. It serves as the bridge between the physical keyboard hardware and the firmware's key processing logic.
Matrix Types in RMK
RMK provides four built-in matrix implementations to match different hardware designs:
Normal Matrix
The standard approach. Keys are wired in a row-column grid, using diodes to prevent ghosting. RMK supports both col2row and row2col diode configurations to match your PCB design. You can set the diode direction in the matrix configuration.
Direct Pin Matrix
Each key connects directly to its own GPIO pin, eliminating the matrix grid and the need for diodes. All key states are read simultaneously without scanning. This method requires a high number of GPIO pins, so it's best for small keyboards and macropads. In the Rust API this is rmk::matrix::direct_pin::DirectPinMatrix; see the rp2040_direct_pin example.
Bidirectional Matrix
The bidirectional matrix design uses dynamically switchable GPIO pins that can change between input and output modes during the scan cycle. Because the bidirectional matrix is more complicated than the normal matrix, only the Rust API is provided at the moment.
74HC595 Shift Register Matrix
Columns are driven by one or more daisy-chained 74HC595 shift registers on an SPI bus (up to 32 columns), while rows stay on GPIO input pins. This saves MCU pins on wide keyboards. Only the Rust API is provided: rmk::matrix::hc595_matrix::Hc595Matrix takes an SpiDevice, the latch (RCLK) output pin, the row input pins and a debouncer, and derives the chain length from the COL const generic:
Async Matrix Feature
Async matrix is a power-saving feature that transforms how the matrix operates, dramatically reducing power consumption for wireless keyboards. This feature works out-of-the-box for nRF and RP2040. STM32 requires additional EXTI (external interrupt) configuration due to hardware limitations—see the Low Power documentation for details.
To enable it, add the async_matrix feature in Cargo.toml:
Configuration
For detailed matrix configuration options, pin assignments, and platform-specific setup, see the Matrix Configuration documentation.
Customization via Traits
RMK's matrix system is built on a trait-based architecture. Any matrix or debouncer that implements the corresponding trait can be seamlessly integrated into RMK, making both components highly extensible without touching core firmware code:
MatrixTrait: Defines the core scanning interface. Implement this trait to support external I/O expanders, non-standard electrical designs, or specialized scanning algorithms.
DebouncerTrait: Controls switch bounce filtering. RMK includes default and fast debouncing algorithms, and you can also implement custom debouncing logic optimized for your own use cases.
A matrix is an input device that publishes KeyboardEvents, so MatrixTrait builds on the InputDevice trait. The following is an example demonstrating how to use a customized matrix: