Skip to content

M5_CARDPUTER

Namespace: m5
Header: M5Cardputer.h
Global Instance: M5Cardputer

The main device class. Wraps M5Unified and adds keyboard support.


Public Members

Display / Lcd

M5GFX &Display = M5.Display;
M5GFX &Lcd     = Display;

320×240 TFT display. See Display (M5GFX) for the full drawing API.


Power

Power_Class &Power = M5.Power;

Battery level, charging status, sleep control. See below for detailed API.


Speaker

Speaker_Class &Speaker = M5.Speaker;

Tone generation and WAV playback. See Speaker for the full API.


Mic

Mic_Class &Mic = M5.Mic;

I2S microphone recording. See Microphone for the full API.


BtnA

Button_Class &BtnA = M5.getButton(0);

Physical button A. See below for detailed API.


Keyboard

Keyboard_Class Keyboard = Keyboard_Class();

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

void begin(bool enableKeyboard = true);

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
void setup() {
    M5Cardputer.begin();  // Default: keyboard enabled
}

begin(cfg)

void begin(m5::M5Unified::config_t cfg, bool enableKeyboard = true);

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

void update(void);

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

bool 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()

bool wasReleased();

Returns true exactly once when the button transitions from pressed to released (falling edge).

if (M5Cardputer.BtnA.wasReleased()) {
    M5Cardputer.Display.println("Button released.");
}

isPressed()

bool 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()

bool isHolding();

Returns true when the button is in "hold" state (pressed longer than the hold threshold).

if (M5Cardputer.BtnA.isHolding()) {
    M5Cardputer.Display.fillCircle(160, 120, 10, TFT_RED);
}

isReleased()

bool isReleased();

Returns true while the button is not pressed.

if (M5Cardputer.BtnA.isReleased()) {
    M5Cardputer.Display.drawString("Ready", 10, 10);
}

wasHold()

bool 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()

bool 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()

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

bool pressedFor(uint32_t 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)

bool releasedFor(uint32_t 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)

bool wasReleaseFor(uint32_t 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()

int32_t 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()

int16_t getBatteryVoltage();

Returns battery voltage in millivolts.

int16_t voltage = M5Cardputer.Power.getBatteryVoltage();
M5Cardputer.Display.printf("Battery: %d mV\n", voltage);

getBatteryCurrent()

int32_t 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()

is_charging_t 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)
// Limit charging current for heat management
M5Cardputer.Power.setChargeCurrent(500);   // 500mA max

powerOff()

void powerOff();

Turns off all power rails. The device will not respond until physically reset.

// Long press to power off
if (M5Cardputer.BtnA.pressedFor(3000)) {
    M5Cardputer.Power.powerOff();
}

deepSleep(micro_seconds)

void deepSleep(uint64_t micro_seconds = 0, bool touch_wakeup = true);

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)

void lightSleep(uint64_t micro_seconds = 0, bool touch_wakeup = true);

Enters ESP32 light sleep. Faster wake-up than deep sleep, but uses more power.

// Light sleep for 5 seconds, wake on button
M5Cardputer.Power.lightSleep(5000000, true);

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.

// Sleep for 60 seconds
M5Cardputer.Power.timerSleep(60);

getVBUSVoltage()

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

void setLed(uint8_t brightness = 255);

Controls the power LED (if present). 0 = off, 1–255 = on with brightness.

M5Cardputer.Power.setLed(128);  // Half 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);

I2C Bus Info

i2c_port_t getPort();   // I2C port number
int8_t getSDA();        // SDA pin
int8_t getSCL();        // SCL pin
bool isEnabled();       // Whether the bus is configured
void setup() {
    M5Cardputer.begin();

    M5Cardputer.Display.printf("Ex_I2C: SDA=%d SCL=%d\n",
        M5Cardputer.Ex_I2C.getSDA(),
        M5Cardputer.Ex_I2C.getSCL());

    if (M5Cardputer.Ex_I2C.isEnabled()) {
        M5Cardputer.Display.println("External I2C ready");
    }
}