Skip to content

M5Cardputer(ADV) Arduino 功能例程速查手册(综合本地实测版)

本手册基于 D:/M5AVD/CardputerAdv_资料 下的官方 API 文档(00~04)与已测 examples(display / button / buzzer / keyboard / inputText / mic / sdcard / ir_nec)整理,并综合 D:/M5AVD/M5Radio 项目实测写法。所有例程均可直接复制编译。 与网上通用教程的关键差异:颜色/对齐用 LovyanGFX 原生写法(GREEN/middle_center),playRaw 是 6 参数,clear() 是整屏清屏——以本机实测 examples 为准。

0. 开发环境 & 板型

Arduino IDE,板管理装M5Stack,开发板选M5Cardputer(库会自动识别 Cardputer / Cardputer-ADV 两种板型,键盘读取器自动切换:ADV 用 TCA8418 I2C 矩阵,旧版用 74HC138)。

库管理器装M5Cardputer(自带 M5Unified / M5GFX / IRremote)。WiFi/SD/SPI 是 ESP32 核心自带,无需另装。

屏幕 240×135,竖屏用时 setRotation(1) 旋转为横屏。

编译用默认 4MB 分区即可。

1. 统一框架(所有程序开头)

cpp
#include "M5Cardputer.h"
void setup() {
auto cfg = M5.config();
M5Cardputer.begin(cfg, true);   // true = 启用键盘;不用键盘写 M5Cardputer.begin(cfg)
M5Cardputer.Display.setRotation(1);  // 横屏
}
void loop() {
M5Cardputer.update();   // 必须每帧调用,刷新键盘/按钮/扬声器状态
}
```cpp

要点:
- M5Cardputer.Display 是一个 LovyanGFX 实例。
- 颜色常量:GREEN / BLACK / WHITE / RED / YELLOW / BLUE / CYAN / MAGENTA(LovyanGFX 原生,不要写 TFT_GREEN 这类 Adafruit 风格)。
- 文字对齐 datum:middle_center / top_center / top_left 等(不要写 MC_DATUM)。

## 2. 屏幕初始化

```cpp
#include "M5Cardputer.h"

void setup() {
  auto cfg = M5.config();
  M5Cardputer.begin(cfg);
  M5Cardputer.Display.setRotation(1);          // 横屏(1) / 竖屏(0)
  M5Cardputer.Display.fillScreen(BLACK);       // 清成黑底
  M5Cardputer.Display.setTextColor(GREEN);     // 前景色
  M5Cardputer.Display.setTextSize(1);          // 文字大小(浮点, 约0.5~2)
  M5Cardputer.Display.setTextDatum(middle_center);  // 对齐方式
}

void loop() { M5Cardputer.update(); }
```cpp

换字体(可选):

```cpp
M5Cardputer.Display.setTextFont(&fonts::Orbitron_Light_32);   // 内置字体之一
// 其它可用:fonts::FreeSerifBoldItalic18pt7b / fonts::FreeSansBoldOblique12pt7b
```cpp

## 3. 显示文字

三种写法:指定坐标、流式打印、居中对齐。

```cpp
#include "M5Cardputer.h"

void setup() {
  auto cfg = M5.config();
  M5Cardputer.begin(cfg);
  M5Cardputer.Display.fillScreen(BLACK);

  // 方式1:指定坐标 (x, y),原点在左上
  M5Cardputer.Display.setTextColor(WHITE);
  M5Cardputer.Display.setTextSize(1);
  M5Cardputer.Display.drawString("Hello Cardputer", 10, 10);

  // 方式3:居中对齐
  M5Cardputer.Display.setTextDatum(middle_center);
  M5Cardputer.Display.setTextColor(CYAN);
  M5Cardputer.Display.drawString("Center",
      M5Cardputer.Display.width() / 2, M5Cardputer.Display.height() / 2);
  M5Cardputer.Display.setTextDatum(top_left);   // 改回左上对齐
}

void loop() { M5Cardputer.update(); }
```cpp

滚动终端(M5Canvas,来自 inputText.ino):

```cpp
#include "M5Cardputer.h"
#include "M5GFX.h"

M5Canvas canvas(&M5Cardputer.Display);

void setup() {
  auto cfg = M5.config();
  M5Cardputer.begin(cfg, true);
  M5Cardputer.Display.setRotation(1);
  canvas.createSprite(M5Cardputer.Display.width() - 8,
                      M5Cardputer.Display.height() - 36);
  canvas.setTextScroll(true);
  canvas.println("log line 1");
  canvas.println("log line 2");
  canvas.pushSprite(4, 4);
}

void loop() { M5Cardputer.update(); }
```cpp

## 4. 显示图形

矩形、圆、线、三角形(来自 display.ino / 03 文档)。

```cpp
#include "M5Cardputer.h"

void setup() {
  auto cfg = M5.config();
  M5Cardputer.begin(cfg);
  M5Cardputer.Display.fillScreen(BLACK);

  M5Cardputer.Display.fillRect(10, 10, 80, 40, GREEN);      // 实心矩形 x,y,w,h,color
  M5Cardputer.Display.drawRect(100, 10, 80, 40, RED);       // 空心矩形
  M5Cardputer.Display.fillCircle(40, 90, 20, BLUE);         // 实心圆 cx,cy,r
  M5Cardputer.Display.drawCircle(100, 90, 20, YELLOW);      // 空心圆
  M5Cardputer.Display.drawLine(10, 120, 200, 120, WHITE);  // 线 x0,y0,x1,y1
  M5Cardputer.Display.drawTriangle(140, 70, 180, 120, 140, 120, MAGENTA); // 三角
  M5Cardputer.Display.drawRoundRect(200, 10, 30, 40, 8, CYAN); // 圆角矩形 x,y,w,h,radius
}

void loop() { M5Cardputer.update(); }
```cpp

随机彩色图形(display.ino 原版风格):

```cpp
uint16_t c = rand();
M5Cardputer.Display.fillCircle(rand() % M5Cardputer.Display.width(),
                               rand() % M5Cardputer.Display.height(), 20, c);
```cpp

## 5. 清屏 / 局部擦除

```cpp
M5Cardputer.Display.clear();                 // 整屏清屏(官方 examples 常用)
M5Cardputer.Display.fillScreen(BLACK);       // 等价:清成黑底

// 局部擦除:用背景色画实心矩形盖住旧内容(inputText.ino 用法)
M5Cardputer.Display.fillRect(0, M5Cardputer.Display.height() - 28,
                             M5Cardputer.Display.width(), 25, BLACK);
```cpp

动态刷新文字/图形时,先局部 fillRect 擦掉旧区域再画新的,避免叠字。

## 6. 按键输入(键盘)

来自 inputText.ino(真实准确)。启用键盘:M5Cardputer.begin(cfg, true)。每帧 M5Cardputer.update() 后检查 isChange() / isPressed()。

```cpp
#include "M5Cardputer.h"
#include "M5GFX.h"

String data = "> ";

void setup() {
  auto cfg = M5.config();
  M5Cardputer.begin(cfg, true);
  M5Cardputer.Display.setRotation(1);
  M5Cardputer.Display.setTextSize(0.5);
  M5Cardputer.Display.drawString(data, 4, M5Cardputer.Display.height() - 24);
}

void loop() {
  M5Cardputer.update();
  if (M5Cardputer.Keyboard.isChange()) {
    if (M5Cardputer.Keyboard.isPressed()) {
      Keyboard_Class::KeysState status = M5Cardputer.Keyboard.keysState();
      for (auto i : status.word) data += i;          // 追加本次按下的字符
      if (status.del) data.remove(data.length() - 1); // 退格键
      if (status.enter) { /* 回车:提交 data 做你的处理 */ data = "> "; } // 重置输入行
      // 重画输入行
      M5Cardputer.Display.fillRect(0, M5Cardputer.Display.height() - 28,
                                   M5Cardputer.Display.width(), 25, BLACK);
      M5Cardputer.Display.drawString(data, 4, M5Cardputer.Display.height() - 24);
    }
  }
}
```cpp

要点:
- status.word:本次按下的可打印字符数组(已处理 shift / caps)。
- 特殊键布尔:status.enter / status.del / status.space / status.backspace / status.tab / status.esc / status.up/down/left/right / status.f1..f12。
- 修饰键布尔:status.ctrl / status.shift / status.fn / status.alt / status.opt。
- 检测某个特定键(不依赖 word):M5Cardputer.Keyboard.isKeyPressed('m')(可用 'm' / 'a' / 数字 / ',' 等)。

## 7. 用户按钮 BtnA(G0)

来自 button.ino:

```cpp
#include "M5Cardputer.h"

void setup() {
  auto cfg = M5.config();
  M5Cardputer.begin(cfg);
  M5Cardputer.Display.setRotation(1);
}

void loop() {
  M5Cardputer.update();
  if (M5Cardputer.BtnA.wasPressed())  { M5Cardputer.Speaker.tone(8000, 20); /* 按下 */ }
  if (M5Cardputer.BtnA.wasReleased()) { /* 释放 */ }
  if (M5Cardputer.BtnA.wasClicked())  { /* 单击 */ }
  if (M5Cardputer.BtnA.wasHold())     { /* 长按 */ }
}
```cpp

注意:用 wasPressed() / wasReleased()(事件型,每按一次触发一次),不是 isPressed()。

## 8. 蜂鸣器 / 扬声器 tone

来自 buzzer.ino:

```cpp
#include "M5Cardputer.h"

void setup() {
  auto cfg = M5.config();
  M5Cardputer.begin(cfg);
}

void loop() {
  M5Cardputer.Speaker.tone(10000, 100);   // 频率Hz, 持续ms
  delay(1000);
  M5Cardputer.Speaker.tone(4000, 20);
  delay(1000);
}
```cpp

音量:M5Cardputer.Speaker.setVolume(0..255)。

停止当前音:M5Cardputer.Speaker.end()。

启用:M5Cardputer.Speaker.begin()。

## 9. 播放音频(playRaw)

来自 mic.ino(6 参数,实测可用):

```cpp
int16_t recData[1024];
size_t  recSize = sizeof(recData);
M5Cardputer.Speaker.begin();   // 播放前确保扬声器已启用
M5Cardputer.Speaker.playRaw(recData, recSize, 17000, false, 1, 0);  // data,len,sampleRate,stereo,repeat,channel
while (M5Cardputer.Speaker.isPlaying()) { delay(1); M5Cardputer.update(); }
```cpp

⚠麦克风与扬声器互斥:播放前 Mic.end() + Speaker.begin();录音前 Speaker.end() + Mic.begin()(见 mic.ino)。
⚠流式连续播放(如网络收音机)连续喂帧时,可用 7 参数重载 playRaw(data, len, sr, false, 1, channel, stop_current),stop_current=false 表示不清掉已排队音频。完整方案见另一篇《M5 网络收音机项目开发指南》(M5Radio 实测)。

## 10. 麦克风录音

来自 mic.ino 要点:

```cpp
M5Cardputer.Speaker.end();      // 先关扬声器(互斥)
M5Cardputer.Mic.begin();        // 启用麦克风

int16_t buf[240];
if (M5Cardputer.Mic.record(buf, 240, 17000)) {   // 录 240 样本 @17kHz
  // 处理 buf(int16 数组)
}

// 降噪调节
auto cfg = M5Cardputer.Mic.config();
cfg.noise_filter_level = (cfg.noise_filter_level + 8) & 255;
M5Cardputer.Mic.config(cfg);
```cpp

常用采样率 16 kHz / 17 kHz。完整实时波形示例见 examples/mic/mic.ino、examples/mic_wav_record/mic_wav_record.ino(存 WAV 到 SD 卡)。

## 11. microSD 卡

来自 sdcard.ino(真实管脚:CS=12, MOSI=14, SCK=40, MISO=39):

```cpp
#include <M5Cardputer.h>
#include <SPI.h>
#include <SD.h>

#define SD_CS   12
#define SD_SCK  40
#define SD_MISO 39
#define SD_MOSI 14

void setup() {
  M5Cardputer.begin();
  M5Cardputer.Display.setRotation(1);

  SPI.begin(SD_SCK, SD_MISO, SD_MOSI, SD_CS);
  if (!SD.begin(SD_CS, SPI, 25000000)) {
    M5Cardputer.Display.println("SD failed");
    while (1);
  }

  // 写文件
  File f = SD.open("/hello.txt", FILE_WRITE);
  if (f) { f.print("Hello "); f.close(); }

  // 读文件
  f = SD.open("/hello.txt");
  while (f.available()) Serial.write(f.read());
  f.close();
}

void loop() {}
```cpp

注意:TF 卡金属触点朝屏幕的反面插入。

## 12. 红外发送

来自 ir_nec.ino(IR_TX_PIN = 44):

```cpp
#define DISABLE_CODE_FOR_RECEIVER
#define SEND_PWM_BY_TIMER
#define IR_TX_PIN 44

#include "M5Cardputer.h"
#include <IRremote.hpp>

void setup() {
  auto cfg = M5.config();
  M5Cardputer.begin(cfg, true);
  IrSender.begin(DISABLE_LED_FEEDBACK);
  IrSender.setSendPin(IR_TX_PIN);
}

void loop() {
  IrSender.sendNEC(0x1111, 0x34, 0);   // 地址, 命令, 重复次数
  delay(1000);
}
```cpp

需安装 IRremote 库(M5Cardputer 依赖自带)。

## 13. 搜索 WiFi / 连接 WiFi

M5 本地 examples 无专门 WiFi 例,以下基于 ESP32 原生 WiFi 库 +M5Radio 项目实测要点。
例程A 扫描附近热点:

```cpp
#include "M5Cardputer.h"
#include "WiFi.h"

void setup() {
  auto cfg = M5.config();
  M5Cardputer.begin(cfg);
  M5Cardputer.Display.setRotation(1);
  M5Cardputer.Display.setTextSize(0.5);

  // ⚠ 实测要点(来自 M5Radio):扫描前先断开并关闭 autoReconnect,否则偶发返回 0 条
  WiFi.disconnect(false);
  WiFi.setAutoReconnect(false);
  delay(150);
  int n = WiFi.scanNetworks(false, true);
  if (n <= 0) { delay(300); n = WiFi.scanNetworks(false, true); }  // 偶发0重试一次
  WiFi.setAutoReconnect(true);

  for (int i = 0; i < n; i++) {
    M5Cardputer.Display.print(i + 1); M5Cardputer.Display.print(": ");
    M5Cardputer.Display.print(WiFi.SSID(i));
    M5Cardputer.Display.print(" (");
    M5Cardputer.Display.print(WiFi.RSSI(i));
    M5Cardputer.Display.println("dBm)");
  }
}

void loop() { M5Cardputer.update(); }
```cpp

要点:WiFi.SSID(i) 名称、WiFi.RSSI(i) 信号强度(dBm,越接近 0 越强,-30 极好 / -80 很弱)、WiFi.encryptionType(i) 加密方式。
例程B 连接 WiFi:

```cpp
#include "WiFi.h"

const char* ssid     = "你的SSID";
const char* password = "你的密码";

void connectWiFi() {
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) { delay(500); }
  // 已连上,可开始网络操作
}
```cpp

## 14. 电源 / 电池

来自 03 文档:

float voltage = M5Cardputer.Power.getBatteryVoltage();  // 电池电压,如 4.1
// 百分比参考 M5Radio:按 3.0V~4.2V 线性换算

充电时把电源开关拨到 ON。

RGB LED 由 GPIO38 供电,使用前需 digitalWrite(LED_EN, HIGH) 点亮。

插入 3.5mm 耳机后,扬声器功放会被禁用。

## 15. 综合示例:键盘输入终端

改编自 inputText.ino,做一个最小终端:输入字符串,Enter 提交到串口,可接你自己的逻辑。

```cpp
#include "M5Cardputer.h"
#include "M5GFX.h"
String data = "> ";
void setup() {
auto cfg = M5.config();
M5Cardputer.begin(cfg, true);
Serial.begin(115200);
M5Cardputer.Display.setRotation(1);
M5Cardputer.Display.setTextSize(0.5);
M5Cardputer.Display.drawString(data, 4, M5Cardputer.Display.height() - 24);
}
void loop() {
M5Cardputer.update();
if (M5Cardputer.Keyboard.isChange()) {
if (M5Cardputer.Keyboard.isPressed()) {
  Keyboard_Class::KeysState status = M5Cardputer.Keyboard.keysState();
  for (auto i : status.word) data += i;
  if (status.del) data.remove(data.length() - 1);
  if (status.enter) {
    String cmd = data.substring(2);   // 去掉 "> "
    Serial.println(cmd);              // 提交你的处理
    data = "> ";
  }
  M5Cardputer.Display.fillRect(0, M5Cardputer.Display.height() - 28,
                               M5Cardputer.Display.width(), 25, BLACK);
  M5Cardputer.Display.drawString(data, 4, M5Cardputer.Display.height() - 24);
}
}
}
```cpp

## 附:本地材料索引(备查)

- API 文档:D:/M5AVD/CardputerAdv_资料/00_硬件规格与管脚表.md、01_Arduino IDE环境配置.md、02_依赖库说明.md、03_M5Cardputer核心API.md、04_示例代码汇总.md
- 已测例程:D:/M5AVD/CardputerAdv_资料/examples/(display / button / buzzer / keyboard/inputText / mic / sdcard / ir_nec / UI/REPL)
- 综合大案例(所有功能集成 + 网络收音机):D:/M5AVD/M5Radio(见另一篇《M5 网络收音机项目开发指南(M5Radio·已实测)》)