M5Stack Cardputer
M5Stack-Cardputer
The M5Stack Cardputer (K132) and Cardputer ADV are card-sized computers based on the ESP32-S3 StampS3 module. They feature a 56-key QWERTY keyboard, a 1.14” 240x135 IPS display, a mono speaker, a microphone, a micro-SD card slot, an IR transmitter, a Grove port, and a WS2812 RGB LED.
The espp::M5StackCardputer component supports both variants with the same API - the board is detected at runtime - and provides a singleton hardware abstraction for initializing the display, keyboard (74HC138 GPIO matrix on the original, TCA8418 I2C controller on the ADV), audio (NS4168 amplifier on the original, ES8311 codec on the ADV), microphone, uSD card, RGB LED, battery measurement, and button subsystems.
Note
The speaker and the microphone share I2S pins, so they cannot be used at the same time; initializing one while the other is active will fail.
API Reference
Header File
Classes
-
class M5StackCardputer : public espp::BaseComponent
The M5StackCardputer class provides an interface to the M5Stack Cardputer (K132) and Cardputer ADV, ESP32-S3 (StampS3) based card-sized computers with a 56-key QWERTY keyboard. The variant is detected automatically at runtime (see variant()); both share the same 56-key layout and the same API.
The class provides access to the following features:
Display (1.14” 240x135 IPS TFT, ST7789V2)
Keyboard (original: 56-key matrix scanned through a 74HC138 demultiplexer; ADV: TCA8418 I2C keyboard controller)
Audio output (mono speaker; original: NS4168 I2S amplifier; ADV: ES8311 codec + NS4150B amplifier, initialized automatically)
Microphone (original: SPM1423 PDM; ADV: analog MEMS mic via the ES8311 codec)
micro-SD (uSD) card (SPI mode)
RGB LED (WS2812, on the StampS3 module)
Battery voltage measurement
G0 (BOOT) button
IR transmitter and Grove port pin definitions
Internal I2C bus accessor (ADV only; also hosts a BMI270 IMU at 0x68 which can be used with the espp bmi270 component)
The class is a singleton and can be accessed using the get() method.
Example
espp::M5StackCardputer &cardputer = espp::M5StackCardputer::get(); cardputer.set_log_level(espp::Logger::Verbosity::INFO); // initialize the LCD if (!cardputer.initialize_lcd()) { logger.error("Failed to initialize LCD!"); return; } // initialize the display, using a pixel buffer of 50 lines static constexpr size_t pixel_buffer_size = cardputer.lcd_width() * 50; if (!cardputer.initialize_display(pixel_buffer_size)) { logger.error("Failed to initialize display!"); return; } // initialize the RGB LED and the sound subsystem (the microphone shares a // pin with the speaker, so this example only uses the speaker) if (!cardputer.initialize_led()) { logger.error("Failed to initialize RGB LED!"); return; } if (!cardputer.initialize_sound()) { logger.error("Failed to initialize sound!"); return; } cardputer.volume(60.0f); // try to mount the uSD card (warn and continue if it's not inserted) if (!cardputer.initialize_sdcard({})) { logger.warn("Could not mount the uSD card; is one inserted?"); } // create the GUI (a small keyboard-driven text editor) static Gui gui({}); // print the controls (also available on-screen via the fn+1 help popup) logger.info("Controls:\n{}", Gui::HELP_TEXT); // whether the board has a working IMU; set after keyboard / variant // detection below, referenced by the keypress callback static bool have_imu = false; // the keyboard scanner delivers one event per key state change; use it to // drive the text editor, play key-click sounds, and show what's happening // in the status bar auto keypress_callback = [&](const espp::M5StackCardputer::KeyEvent &event) { if (!event.pressed) { return; } if (event.special == espp::M5StackCardputer::SpecialKey::F1) { // toggle the help popup bool shown = gui.toggle_help(); gui.set_status_text(shown ? "Help (fn+1 to close)" : "Ready"); play_beep(cardputer, 660.0f); } else if (event.special == espp::M5StackCardputer::SpecialKey::F2) { // toggle the IMU popup if (have_imu) { bool visible = gui.toggle_imu_visible(); gui.set_status_text(visible ? "IMU popup shown" : "IMU popup hidden"); } else { gui.set_status_text("No IMU on this board"); } play_beep(cardputer, 660.0f); } else if (event.special != espp::M5StackCardputer::SpecialKey::NONE) { gui.handle_special_key(event.special); gui.set_status_text(espp::M5StackCardputer::special_key_name(event.special)); play_beep(cardputer, 660.0f); } else if (event.value != 0) { gui.add_char(event.value); play_beep(cardputer, 880.0f); } else { // a modifier key by itself std::string status; if (event.modifiers.fn) status += "fn "; if (event.modifiers.shift) status += "shift "; if (event.modifiers.ctrl) status += "ctrl "; if (event.modifiers.opt) status += "opt "; if (event.modifiers.alt) status += "alt "; gui.set_status_text(status.empty() ? "Ready" : status); } }; // the keyboard scanner auto-detects the board variant: the original's // 74HC138 GPIO matrix or the ADV's TCA8418 I2C keyboard controller if (!cardputer.initialize_keyboard(keypress_callback)) { logger.error("Failed to initialize keyboard!"); return; } logger.info("Board variant: {}", espp::M5StackCardputer::variant_name(cardputer.variant())); // the ADV has a BMI270 IMU on the internal I2C bus; initialize it if we're // on one (warn and continue otherwise - the original has no IMU) if (cardputer.variant() == espp::M5StackCardputer::Variant::ADV) { have_imu = cardputer.initialize_imu(); if (have_imu) { // show the IMU popup by default (fn+2 toggles it) gui.toggle_imu_visible(); } else { logger.warn("Could not initialize the IMU!"); } } // the G0 (BOOT) button cycles the RGB LED color static std::atomic<int> led_hue{0}; auto button_callback = [&](const espp::Interrupt::Event &event) { if (event.active) { led_hue = (led_hue + 60) % 360; cardputer.led(espp::Hsv(static_cast<float>(led_hue), 1.0f, 0.2f)); play_beep(cardputer, 440.0f); } }; if (!cardputer.initialize_button(button_callback)) { logger.error("Failed to initialize button!"); return; } // set the initial LED color cardputer.led(espp::Hsv(static_cast<float>(led_hue), 1.0f, 0.2f)); // periodically update the status bar with the battery voltage / state of // charge, and (on the ADV) the IMU overlay with the latest accelerometer // and gyroscope readings static constexpr auto imu_period = 100ms; int loops_per_battery_update = std::chrono::seconds(5) / imu_period; int loop_count = 0; while (true) { if (have_imu && gui.imu_visible()) { auto imu = cardputer.imu(); std::error_code ec; if (imu->update(std::chrono::duration<float>(imu_period).count(), ec)) { auto accel = imu->get_accelerometer(); auto gyro = imu->get_gyroscope(); gui.set_imu_text(fmt::format("a {:+.1f} {:+.1f} {:+.1f}\ng {:+5.0f} {:+5.0f} {:+5.0f}", accel.x, accel.y, accel.z, gyro.x, gyro.y, gyro.z)); } } if ((loop_count % loops_per_battery_update) == 0) { gui.set_status_text(fmt::format("Battery: {:.2f} V ({:.0f}%)", cardputer.battery_voltage(), cardputer.battery_soc())); } loop_count++; std::this_thread::sleep_for(imu_period); }
Note
The speaker and the microphone share I2S pins (GPIO 43 word-select / PDM clock on the original; GPIO 41/43 bit-clock and word-select on the ADV), so they cannot be used at the same time. Initializing one while the other is active will fail.
Public Types
-
enum class SpecialKey : uint8_t
Special (non-printable) keys, produced by the Fn layer of the keyboard.
Values:
-
enumerator NONE
Not a special key.
-
enumerator ESC
Escape (fn + `)
-
enumerator F1
F1 (fn + 1)
-
enumerator F2
F2 (fn + 2)
-
enumerator F3
F3 (fn + 3)
-
enumerator F4
F4 (fn + 4)
-
enumerator F5
F5 (fn + 5)
-
enumerator F6
F6 (fn + 6)
-
enumerator F7
F7 (fn + 7)
-
enumerator F8
F8 (fn + 8)
-
enumerator F9
F9 (fn + 9)
-
enumerator F10
F10 (fn + 0)
-
enumerator F11
F11 (fn + -)
-
enumerator F12
F12 (fn + =)
-
enumerator DELETE
Delete (fn + backspace)
-
enumerator UP
Up arrow (fn + ;)
-
enumerator DOWN
Down arrow (fn + .)
-
enumerator LEFT
Left arrow (fn + ,)
-
enumerator RIGHT
Right arrow (fn + /)
-
enumerator NONE
-
enum class Variant : uint8_t
The hardware variant of the board.
Values:
-
enumerator ORIGINAL
Original Cardputer (K132): 74HC138 matrix keyboard, NS4168 I2S amplifier, SPM1423 PDM microphone
-
enumerator ADV
Cardputer ADV: TCA8418 I2C keyboard controller, ES8311 codec (speaker + microphone), BMI270 IMU on the internal I2C bus
-
enumerator ORIGINAL
-
using Pixel = lv_color16_t
Alias for the pixel type used by the display.
-
using button_callback_t = std::function<void(const espp::Interrupt::Event&)>
Alias for the button callback function.
-
using keypress_callback_t = std::function<void(const KeyEvent&)>
Alias for the keypress callback function. Called once for each key that changes state during a keyboard scan.
-
using microphone_callback_t = std::function<void(const uint8_t *data, size_t num_bytes)>
Alias for the microphone data callback. Called with 16-bit signed mono samples read from the PDM microphone.
Public Functions
-
espp::Interrupt &interrupts()
Get a reference to the interrupts
- Returns:
A reference to the interrupts
-
Variant variant()
Get the hardware variant of the board.
Note
The first call detects the variant by probing for the ADV’s TCA8418 keyboard controller on the internal I2C bus (GPIO 8/9); on the original those pins are then returned to plain GPIO for the 74HC138 matrix.
- Returns:
The hardware variant of the board
-
I2c *internal_i2c()
Get a pointer to the internal I2C bus (ADV only)
Note
On the ADV the internal bus hosts the TCA8418 keyboard controller (0x34), the ES8311 codec (0x18), and a BMI270 IMU (0x68)
- Returns:
A pointer to the internal I2C bus, or nullptr on the original Cardputer (which has no internal I2C bus)
- bool initialize_keyboard (const keypress_callback_t &callback=nullptr, std::chrono::milliseconds poll_interval=std::chrono::milliseconds(10), const espp::Task::BaseConfig &task_config={ .name="keyboard",.stack_size_bytes=CONFIG_M5STACK_CARDPUTER_KEYBOARD_TASK_STACK_SIZE,.priority=CONFIG_M5STACK_CARDPUTER_KEYBOARD_TASK_PRIORITY,.core_id=CONFIG_M5STACK_CARDPUTER_KEYBOARD_TASK_CORE_ID})
Initialize the keyboard
Note
The keyboard is a 4x14 matrix (a 74HC138-scanned GPIO matrix on the original, a TCA8418 I2C controller on the ADV); a scanner task owned by this class polls it at the given interval and calls the callback once per key state change.
Note
The callback runs in the scanner task’s context, so the task’s stack must be large enough for whatever the callback calls into (e.g. LVGL).
- Parameters:
callback – The callback function to call when a key changes state
poll_interval – The interval at which to scan the keyboard matrix
task_config – The configuration for the keyboard scanner task. The defaults come from the M5STACK_CARDPUTER_KEYBOARD_TASK_* Kconfig options.
- Returns:
true if the keyboard was successfully initialized, false otherwise
-
bool is_key_pressed(uint8_t row, uint8_t col) const
Get whether a key is currently pressed
- Parameters:
row – The row of the key in the matrix
col – The column of the key in the matrix
- Returns:
true if the key is currently pressed, false otherwise
-
Modifiers modifiers() const
Get the current state of the modifier keys
- Returns:
The current state of the modifier keys
-
std::array<uint16_t, KEYBOARD_ROWS> keyboard_state() const
Get the raw state of the keyboard matrix
- Returns:
One entry per row; in each entry bit N is set if the key in column N is currently pressed
-
bool initialize_button(const button_callback_t &callback = nullptr)
Initialize the G0 (BOOT) button
- Parameters:
callback – The callback function to call when the button changes state
- Returns:
true if the button was successfully initialized, false otherwise
-
bool button_state() const
Get the state of the G0 (BOOT) button
- Returns:
true if the button is pressed, false otherwise
-
bool initialize_lcd()
Initialize the LCD (low level display driver)
- Returns:
true if the LCD was successfully initialized, false otherwise
-
bool initialize_display(size_t pixel_buffer_size)
Initialize the display (lvgl display driver)
- Parameters:
pixel_buffer_size – The size of the pixel buffer
- Returns:
true if the display was successfully initialized, false otherwise
-
std::shared_ptr<Display<Pixel>> display() const
Get a shared pointer to the display
- Returns:
A shared pointer to the display
-
inline const std::shared_ptr<DisplayDriver> &display_driver() const
Get a shared pointer to the low-level display driver
- Returns:
A shared pointer to the display driver
-
void brightness(float brightness)
Set the brightness of the backlight
Note
This function will only work after initialize_lcd() has been called
- Parameters:
brightness – The brightness of the backlight as a percentage (0 - 100)
-
float brightness() const
Get the brightness of the backlight
Note
This function will only work after initialize_lcd() has been called
- Returns:
The brightness of the backlight as a percentage (0 - 100)
-
Pixel *vram0() const
Get the VRAM 0 pointer (DMA memory used by LVGL)
Note
This is the memory used by LVGL for rendering
Note
This is null unless initialize_display() has been called
- Returns:
The VRAM 0 pointer
-
Pixel *vram1() const
Get the VRAM 1 pointer (DMA memory used by LVGL)
Note
This is the memory used by LVGL for rendering
Note
This is null unless initialize_display() has been called
- Returns:
The VRAM 1 pointer
-
void write_lcd_frame(const uint16_t x, const uint16_t y, const uint16_t width, const uint16_t height, uint8_t *data)
Write a frame to the LCD
Note
This method queues the data to be written to the LCD, only blocking if there is an ongoing SPI transaction
- Parameters:
x – The x coordinate
y – The y coordinate
width – The width of the frame, in pixels
height – The height of the frame, in pixels
data – The data to write
-
void write_lcd_lines(int xs, int ys, int xe, int ye, const uint8_t *data, uint32_t user_data)
Write lines to the LCD
Note
This method queues the panel transfer asynchronously and may return before the write has completed.
- Parameters:
xs – The x start coordinate
ys – The y start coordinate
xe – The x end coordinate
ye – The y end coordinate
data – The data to write
user_data – User data to pass to the SPI transaction callback
- bool initialize_sound (uint32_t default_audio_rate=44100, const espp::Task::BaseConfig &task_config={ .name="audio",.stack_size_bytes=CONFIG_M5STACK_CARDPUTER_AUDIO_TASK_STACK_SIZE,.priority=CONFIG_M5STACK_CARDPUTER_AUDIO_TASK_PRIORITY,.core_id=CONFIG_M5STACK_CARDPUTER_AUDIO_TASK_CORE_ID})
Initialize the sound subsystem (mono speaker; NS4168 I2S amplifier on the original, ES8311 codec + NS4150B amplifier on the ADV)
Note
The speaker shares I2S pins with the microphone, so this will fail if the microphone has been initialized.
- Parameters:
default_audio_rate – The default sample rate for the audio, in Hz
task_config – The configuration for the audio task. The defaults come from the M5STACK_CARDPUTER_AUDIO_TASK_* Kconfig options.
- Returns:
true if the sound subsystem was successfully initialized, false otherwise
-
uint32_t audio_sample_rate() const
Get the audio sample rate
- Returns:
The audio sample rate, in Hz
-
void audio_sample_rate(uint32_t sample_rate)
Set the audio sample rate
- Parameters:
sample_rate – The audio sample rate, in Hz
-
size_t audio_buffer_size() const
Get the audio buffer size
- Returns:
The audio buffer size, in bytes
-
void mute(bool mute)
Mute or unmute the audio
- Parameters:
mute – true to mute the audio, false to unmute it
-
bool is_muted() const
Check if the audio is muted
- Returns:
true if the audio is muted, false otherwise
-
void volume(float volume)
Set the volume of the audio
Note
The NS4168 has no volume control, so the volume is applied in software when the samples are written to the I2S peripheral
- Parameters:
volume – The volume as a percentage (0 - 100)
-
float volume() const
Get the volume of the audio
- Returns:
The volume as a percentage (0 - 100)
-
void play_audio(const std::vector<uint8_t> &data)
Play the audio data
Note
This function is non-blocking and queues the data for the audio task to play
- Parameters:
data – The audio data to play (16-bit signed mono samples)
-
void play_audio(const uint8_t *data, uint32_t num_bytes)
Play the audio data
Note
This function is non-blocking and queues the data for the audio task to play
- Parameters:
data – The audio data to play (16-bit signed mono samples)
num_bytes – The number of bytes to play
- bool initialize_microphone (const microphone_callback_t &callback, uint32_t sample_rate=16000, const espp::Task::BaseConfig &task_config={ .name="microphone",.stack_size_bytes=CONFIG_M5STACK_CARDPUTER_MICROPHONE_TASK_STACK_SIZE,.priority=CONFIG_M5STACK_CARDPUTER_MICROPHONE_TASK_PRIORITY,.core_id=CONFIG_M5STACK_CARDPUTER_MICROPHONE_TASK_CORE_ID})
Initialize the microphone (SPM1423 PDM on the original, analog MEMS via the ES8311 codec on the ADV) and start delivering audio data to the provided callback
Note
The callback runs in the microphone task’s context, so the task’s stack must be large enough for whatever the callback does with the audio data.
Note
The microphone shares I2S pins with the speaker, so this will fail if the sound subsystem has been initialized.
- Parameters:
callback – The callback to call with recorded audio data (16-bit signed mono samples)
sample_rate – The sample rate for the microphone, in Hz
task_config – The configuration for the microphone task. The defaults come from the M5STACK_CARDPUTER_MICROPHONE_TASK_* Kconfig options.
- Returns:
true if the microphone was successfully initialized, false otherwise
-
uint32_t microphone_sample_rate() const
Get the microphone sample rate
- Returns:
The microphone sample rate, in Hz
-
bool initialize_sdcard(const SdCardConfig &config)
Initialize the uSD card (SPI mode)
- Parameters:
config – The configuration for the uSD card
- Returns:
True if the uSD card was initialized properly.
-
inline sdmmc_card_t *sdcard() const
Get the uSD card
Note
The uSD card is only available if it was successfully initialized and the mount point is valid
- Returns:
A pointer to the uSD card
-
bool initialize_led()
Initialize the RGB LED (WS2812 on the StampS3 module)
- Returns:
true if the LED was successfully initialized, false otherwise
-
bool led(const Hsv &hsv)
Set the color of the LED
- Parameters:
hsv – The color of the LED in HSV format
- Returns:
true if the color was successfully set, false otherwise
-
bool led(const Rgb &rgb)
Set the color of the LED
- Parameters:
rgb – The color of the LED in RGB format
- Returns:
true if the color was successfully set, false otherwise
-
float battery_voltage()
Get the battery voltage
Note
The battery voltage is measured through a 2:1 divider on GPIO 10
- Returns:
The battery voltage, in volts
-
float battery_soc()
Get the battery state of charge
Note
This is estimated from the battery voltage using a typical 1S lithium-ion discharge curve, so it is only an approximation - the voltage sags under load (e.g. with the backlight at full brightness or the speaker playing) which will lower the estimate.
- Returns:
The battery state of charge as a percentage (0 - 100)
- bool initialize_imu (const Imu::filter_fn &orientation_filter=nullptr, const Imu::ImuConfig &imu_config={ .accelerometer_range=Imu::AccelerometerRange::RANGE_4G,.accelerometer_odr=Imu::AccelerometerODR::ODR_100_HZ,.accelerometer_bandwidth=Imu::AccelerometerBandwidth::NORMAL_AVG4,.gyroscope_range=Imu::GyroscopeRange::RANGE_1000DPS,.gyroscope_odr=Imu::GyroscopeODR::ODR_100_HZ,.gyroscope_bandwidth=Imu::GyroscopeBandwidth::NORMAL_MODE,.gyroscope_performance_mode=Imu::GyroscopePerformanceMode::PERFORMANCE_OPTIMIZED})
Initialize the IMU (BMI270; Cardputer ADV only)
Note
The original Cardputer has no IMU, so this fails (with an error log) unless the board is a Cardputer ADV.
- Parameters:
orientation_filter – Optional filter function for orientation (e.g. a kalman or madgwick filter); called by Imu::update()
imu_config – The IMU configuration
- Returns:
true if the IMU was successfully initialized, false otherwise
-
inline std::shared_ptr<Imu> imu() const
Get a shared pointer to the IMU
- Returns:
A shared pointer to the IMU, or nullptr if it has not been (successfully) initialized
-
inline const std::string &get_name() const
Get the name of the component
Note
This is the tag of the logger
- Returns:
A const reference to the name of the component
-
inline void set_log_tag(const std::string_view &tag)
Set the tag for the logger
- Parameters:
tag – The tag to use for the logger
-
inline espp::Logger::Verbosity get_log_level() const
Get the log level for the logger
See also
See also
- Returns:
The verbosity level of the logger
-
inline void set_log_level(espp::Logger::Verbosity level)
Set the log level for the logger
See also
See also
- Parameters:
level – The verbosity level to use for the logger
-
inline void set_log_verbosity(espp::Logger::Verbosity level)
Set the log verbosity for the logger
See also
See also
See also
Note
This is a convenience method that calls set_log_level
- Parameters:
level – The verbosity level to use for the logger
-
inline espp::Logger::Verbosity get_log_verbosity() const
Get the log verbosity for the logger
See also
See also
See also
Note
This is a convenience method that calls get_log_level
- Returns:
The verbosity level of the logger
-
inline void set_log_rate_limit(std::chrono::duration<float> rate_limit)
Set the rate limit for the logger
See also
Note
Only calls to the logger that have _rate_limit suffix will be rate limited
- Parameters:
rate_limit – The rate limit to use for the logger
Public Static Functions
-
static inline M5StackCardputer &get()
Access the singleton instance of the M5StackCardputer class.
- Returns:
Reference to the singleton instance of the M5StackCardputer class
-
static inline const char *variant_name(Variant variant)
Get the name of a variant
- Parameters:
variant – The variant to get the name of
- Returns:
The name of the variant
-
static char key_value(uint8_t row, uint8_t col, const Modifiers &modifiers)
Get the character for a key, given a modifier state
- Parameters:
row – The row of the key in the matrix
col – The column of the key in the matrix
modifiers – The modifier state to apply
- Returns:
The character for the key (with the shift layer applied), or 0 if the key has no character
-
static SpecialKey special_key(uint8_t row, uint8_t col)
Get the special key (fn layer) for a key
- Parameters:
row – The row of the key in the matrix
col – The column of the key in the matrix
- Returns:
The special key for the key, or SpecialKey::NONE if it has none
-
static const char *special_key_name(SpecialKey key)
Get the name of a special key
- Parameters:
key – The special key to get the name of
- Returns:
The name of the special key
-
static inline constexpr size_t lcd_width()
Get the width of the LCD in pixels
- Returns:
The width of the LCD in pixels
-
static inline constexpr size_t lcd_height()
Get the height of the LCD in pixels
- Returns:
The height of the LCD in pixels
-
static inline constexpr auto get_lcd_dc_gpio()
Get the GPIO pin for the LCD data/command signal
- Returns:
The GPIO pin for the LCD data/command signal
-
static inline constexpr gpio_num_t ir_tx_gpio()
Get the GPIO pin for the IR transmitter
- Returns:
The GPIO pin for the IR transmitter
-
static inline constexpr gpio_num_t grove_scl_gpio()
Get the GPIO pin for the Grove port SCL / G1 signal
- Returns:
The GPIO pin for the Grove port SCL / G1 signal
-
static inline constexpr gpio_num_t grove_sda_gpio()
Get the GPIO pin for the Grove port SDA / G2 signal
- Returns:
The GPIO pin for the Grove port SDA / G2 signal
Public Static Attributes
-
static constexpr size_t KEYBOARD_ROWS = 4
Number of rows in the keyboard matrix.
-
static constexpr size_t KEYBOARD_COLS = 14
Number of columns in the keyboard matrix.
-
static constexpr size_t SPI_MAX_TRANSFER_BYTES = SPI_LL_DMA_MAX_BIT_LEN / 8
Maximum number of bytes that can be transferred in a single SPI transaction to the display. 32k on the ESP32-S3.
-
static constexpr char mount_point[] = "/sdcard"
Mount point for the uSD card.
-
struct KeyEvent
A single key state change reported by the keyboard scanner.
Public Members
-
uint8_t row
Row of the key in the matrix (0 = top / esc row)
-
uint8_t col
Column of the key in the matrix (0 = leftmost)
-
bool pressed
True if the key is now pressed, false if released.
-
char value
The character for the key, with the shift layer applied (0 if the key has no character, e.g. a modifier or an fn-layer special key). Backspace, tab, enter, and space are reported as ‘
’, ‘\t’, ‘
’, and ‘ ‘.
-
SpecialKey special
The special key (fn layer) if fn was held and the key has one, SpecialKey::NONE otherwise
-
uint8_t row
-
struct Modifiers
The state of the keyboard modifier keys.
-
struct SdCardConfig
Configuration for the uSD card.