M5_CARDPUTER
Namespace: m5
Header: M5Cardputer.h
Global Instance: M5Cardputer
The main device class. Wraps M5Unified and adds keyboard support.
Public Members
Display / Lcd
320×240 TFT display. See Display (M5GFX) for the full drawing API.
Power
Battery level, charging status, sleep control. See below for detailed API.
Speaker
Tone generation and WAV playback. See Speaker for the full API.
Mic
I2S microphone recording. See Microphone for the full API.
BtnA
Physical button A. See below for detailed API.
Keyboard
Keyboard input handler. See Keyboard_Class for the full API.
In_I2C / Ex_I2C
I2C_Class &In_I2C = m5::In_I2C; // Internal I2C (on-board peripherals)
I2C_Class &Ex_I2C = m5::Ex_I2C; // External I2C (Port.A)
Device scanning and register read/write. See below for detailed API.
Methods
begin()
Initializes the device and M5Unified. Auto-detects board type and starts the keyboard reader if enableKeyboard is true.
| Parameter | Type | Default | Description |
|---|---|---|---|
enableKeyboard |
bool |
true |
Enable keyboard scanning |
begin(cfg)
Initializes with a custom M5Unified configuration. See Configuration for config options.
| Parameter | Type | Default | Description |
|---|---|---|---|
cfg |
m5::M5Unified::config_t |
— | Custom hardware config |
enableKeyboard |
bool |
true |
Enable keyboard scanning |
void setup() {
auto cfg = M5.config();
cfg.serial_baudrate = 115200;
cfg.internal_imu = false; // Cardputer has no IMU
cfg.internal_rtc = false; // Cardputer has no RTC
M5Cardputer.begin(cfg, true);
}
update()
Refreshes M5Unified state and scans the keyboard. Must be called on every loop() iteration.
void loop() {
M5Cardputer.update();
// Check keyboard
if (M5Cardputer.Keyboard.isChange()) { /* ... */ }
// Check button
if (M5Cardputer.BtnA.wasPressed()) { /* ... */ }
}
Button A API
wasPressed()
Returns true exactly once when the button transitions from released to pressed (rising edge).
void loop() {
M5Cardputer.update();
if (M5Cardputer.BtnA.wasPressed()) {
M5Cardputer.Display.println("Button pressed!");
}
}
wasReleased()
Returns true exactly once when the button transitions from pressed to released (falling edge).
isPressed()
Returns true continuously while the button is held down.
if (M5Cardputer.BtnA.isPressed()) {
// Triggered every frame while held
M5Cardputer.Speaker.tone(1000, 50);
}
isHolding()
Returns true when the button is in "hold" state (pressed longer than the hold threshold).
isReleased()
Returns true while the button is not pressed.
wasHold()
Returns true exactly once when the button press duration reaches the hold threshold (default 500ms).
if (M5Cardputer.BtnA.wasHold()) {
M5Cardputer.Display.println("Long press detected!");
// Show menu
}
wasChangePressed()
Returns true when the button state changed in either direction (pressed → released, or released → pressed).
if (M5Cardputer.BtnA.wasChangePressed()) {
// Toggle LED or mute/unmute
static bool muted = false;
muted = !muted;
if (muted) M5Cardputer.Speaker.setVolume(0);
else M5Cardputer.Speaker.setVolume(128);
}
wasReleasedAfterHold()
Returns true exactly once when the button is released after being held (long press released).
if (M5Cardputer.BtnA.wasReleasedAfterHold()) {
M5Cardputer.Display.println("Hold released — action confirmed.");
}
pressedFor(ms)
Returns true if the button has been continuously held for at least ms milliseconds.
// Shutdown after 3-second hold
if (M5Cardputer.BtnA.pressedFor(3000)) {
M5Cardputer.Display.println("Shutting down...");
M5Cardputer.Power.powerOff();
}
releasedFor(ms)
Returns true if the button has been released for at least ms milliseconds.
// Show idle notification after 5s of inactivity
if (M5Cardputer.BtnA.releasedFor(5000)) {
M5Cardputer.Display.drawString("Press any key to wake", 10, 10);
}
wasReleaseFor(ms)
Returns true exactly once when the button is released after having been held for at least ms.
if (M5Cardputer.BtnA.wasReleaseFor(1000)) {
M5Cardputer.Display.println("Held for at least 1 second.");
}
Click Detection
bool wasClicked(); // Quick press and release
bool wasSingleClicked(); // Single click confirmed
bool wasDoubleClicked(); // Double click confirmed
bool wasDecideClickCount(); // Multi-click count resolved
uint8_t getClickCount(); // Number of clicks counted
void loop() {
M5Cardputer.update();
if (M5Cardputer.BtnA.wasSingleClicked()) {
M5Cardputer.Display.println("Single click!");
}
if (M5Cardputer.BtnA.wasDoubleClicked()) {
M5Cardputer.Display.println("Double click!");
}
if (M5Cardputer.BtnA.wasDecideClickCount()) {
uint8_t count = M5Cardputer.BtnA.getClickCount();
M5Cardputer.Display.printf("%u clicks\n", count);
}
}
Button Configuration
void setDebounceThresh(uint32_t msec); // Default: 10ms
void setHoldThresh(uint32_t msec); // Default: 500ms
uint32_t getDebounceThresh();
uint32_t getHoldThresh();
void setup() {
M5Cardputer.begin();
// More responsive hold detection
M5Cardputer.BtnA.setHoldThresh(300);
// More stable debounce for noisy button
M5Cardputer.BtnA.setDebounceThresh(20);
}
Power API
getBatteryLevel()
Returns battery level as a percentage (0–100). Returns -1 if unable to read.
void loop() {
M5Cardputer.update();
int battery = M5Cardputer.Power.getBatteryLevel();
M5Cardputer.Display.setCursor(280, 0);
M5Cardputer.Display.printf("%d%%", battery);
}
getBatteryVoltage()
Returns battery voltage in millivolts.
int16_t voltage = M5Cardputer.Power.getBatteryVoltage();
M5Cardputer.Display.printf("Battery: %d mV\n", voltage);
getBatteryCurrent()
Returns battery current in mA (+ = charging, - = discharging).
int32_t current = M5Cardputer.Power.getBatteryCurrent();
if (current > 0) M5Cardputer.Display.println("Charging");
else M5Cardputer.Display.printf("Discharging: %d mA\n", current);
isCharging()
Returns charging status:
| Value | Meaning |
|---|---|
is_charging |
Battery is charging |
is_discharging |
Battery is discharging |
charge_unknown |
Cannot determine |
if (M5Cardputer.Power.isCharging() == is_charging) {
M5Cardputer.Display.drawString(" Charging", 250, 0);
}
Charge Control
void setBatteryCharge(bool enable); // Enable/disable charging
void setChargeCurrent(uint16_t max_mA); // Max charge current (mA)
void setChargeVoltage(uint16_t max_mV); // Max charge voltage (mV)
powerOff()
Turns off all power rails. The device will not respond until physically reset.
deepSleep(micro_seconds)
Enters ESP32 deep sleep. Wake after the specified time, or from touch/button.
// Deep sleep for 30 seconds
M5Cardputer.Power.deepSleep(30000000);
// Deep sleep until button press (0 = infinite)
M5Cardputer.Power.deepSleep(0, true);
lightSleep(micro_seconds)
Enters ESP32 light sleep. Faster wake-up than deep sleep, but uses more power.
timerSleep(seconds)
void timerSleep(int seconds);
void timerSleep(const rtc_time_t& time);
void timerSleep(const rtc_date_t& date, const rtc_time_t& time);
Schedules a timed sleep using the PMIC's RTC. Wakes at the specified time.
getVBUSVoltage()
Returns USB VBUS voltage in mV. Returns -1 if unsupported on this board.
int16_t vbus = M5Cardputer.Power.getVBUSVoltage();
if (vbus > 4000) {
M5Cardputer.Display.println("USB power connected");
}
setLed(brightness)
Controls the power LED (if present). 0 = off, 1–255 = on with brightness.
I2C API
Both In_I2C and Ex_I2C share the same I2C_Class API.
scanID() — Device Scan
void scanID(bool* result, uint32_t freq = 100000); // Scan all 7-bit addresses
bool scanID(uint8_t addr, uint32_t freq = 100000); // Check a single address
The first overload requires a bool[120] array. The second returns true if the address responds.
// Scan all devices on external Port.A
bool devices[120];
M5Cardputer.Ex_I2C.scanID(devices, 100000);
for (int i = 0; i < 120; i++) {
if (devices[i]) {
M5Cardputer.Display.printf("Device at 0x%02X\n", i);
}
}
// Check if OLED display is connected
if (M5Cardputer.Ex_I2C.scanID(0x3C)) {
M5Cardputer.Display.println("OLED found!");
}
writeRegister8() / readRegister8() — Single-Byte Register I/O
bool writeRegister8(uint8_t address, uint8_t reg, uint8_t data, uint32_t freq = 100000);
uint8_t readRegister8(uint8_t address, uint8_t reg, uint32_t freq = 100000);
Write one byte to or read one byte from a register on an I2C device.
// Write configuration
M5Cardputer.Ex_I2C.writeRegister8(0x68, 0x6B, 0x00, 400000); // Wake up MPU6050
// Read sensor data
uint8_t val = M5Cardputer.Ex_I2C.readRegister8(0x68, 0x75, 400000); // Read WHO_AM_I
M5Cardputer.Display.printf("WHO_AM_I: 0x%02X\n", val);
writeRegister() / readRegister() — Multi-Byte Register I/O
bool writeRegister(uint8_t address, uint8_t reg, const uint8_t* data, size_t length, uint32_t freq);
bool readRegister(uint8_t address, uint8_t reg, uint8_t* result, size_t length, uint32_t freq);
Write or read multiple bytes to/from an I2C device register.
// Read 6 bytes of accelerometer data from MPU6050 at 0x68
uint8_t accelData[6];
M5Cardputer.Ex_I2C.readRegister(0x68, 0x3B, accelData, 6, 400000);
int16_t ax = (accelData[0] << 8) | accelData[1];
int16_t ay = (accelData[2] << 8) | accelData[3];
int16_t az = (accelData[4] << 8) | accelData[5];
M5Cardputer.Display.printf("AX=%d AY=%d AZ=%d\n", ax, ay, az);
bitOn() / bitOff() — Bit Operations
bool bitOn(uint8_t address, uint8_t reg, uint8_t bits, uint32_t freq); // Set bits (OR)
bool bitOff(uint8_t address, uint8_t reg, uint8_t bits, uint32_t freq); // Clear bits (AND NOT)
Read-modify-write convenience: set or clear specific bits in a register.
// Set bit 3 of register 0x6B on device 0x68
M5Cardputer.Ex_I2C.bitOn(0x68, 0x6B, 0x08, 400000);
// Clear bit 3
M5Cardputer.Ex_I2C.bitOff(0x68, 0x6B, 0x08, 400000);