板载外设使用
本页面收集了 1.47'' IPS Display 上每个板载外设的独立功能级演示。每一节都是自包含的——你可以直接选择与你使用场景匹配的那一节,而无需阅读其他内容。
本页中的演示 GIF 为了缩短时长都经过了加速处理。
本页中的所有演示都需要按照快速上手中所述安装 esp32 Boards by Espressif (3.3.11),并按下文说明手动安装 Seeed_GFX2 库。
- Seeed_GFX2(手动安装) —— 此库在 Library Manager 中不可用,必须手动安装:
步骤 1. 点击上方按钮,将 Seeed_GFX2 v1.0.0 作为 ZIP 文件下载(固定到一个发布标签,以保证教程可复现)。或者,从 Seeed-Studio/Seeed_GFX2 克隆仓库。
步骤 2. 在 Arduino IDE 中,依次点击 Sketch > Include Library > Add .ZIP Library...,然后选择下载的 ZIP。IDE 会读取 library.properties 并自动将其安装到正确的 Seeed_GFX2 文件夹中——你无需重命名解压后的文件夹。(如果要改为手动安装,请先解压压缩包,将解压后的文件夹重命名为 Seeed_GFX2,再放入 Documents/Arduino/libraries/。)
步骤 3. 重启 Arduino IDE,使其检测到新库。
- Seeed_GFX2 是 Seeed Studio 基于分层
Board+Panel Config架构构建的图形库。每个演示都通过一次display.begin<Board_..., Config_...>()调用来初始化显示屏——Board 模板负责引脚映射(CS/DC/SCK/MOSI/RST/BL),而 Panel Config 预设了分辨率、颜色顺序(BGR)和方向。无需driver.h或手动引脚配置。 - 在这块板子上,演示使用
Board_XIAO_1inch47_Touch_Display<13, 12>(RST=13,BL=12)以及Config_Seeed_1inch47_Touch_JD9853A(172×320,BGR,无反色)。 - 触摸控制器(AXS5106L)由
Seeed_GFX2的 Touch 层(Touch_AXS5106L)处理——无需额外库。IMU 在示例中通过裸 I2C(Wire)读取。 - SD BMP Reader 和 SD Recorder 示例使用 ESP32 板包内置的
SD.h访问 SD 卡。
获取演示代码
本页中的每个演示都位于 Display-Gadgets 仓库的 code_GFX2/Function/ 目录下。每个演示是一个包含单个 .ino 草图的文件夹。务必下载完整文件夹,而不是从 GitHub 网页视图中复制 .ino 源码。
方案 A —— 将仓库下载为 ZIP(推荐):
- 打开 github.com/Seeed-Projects/Display-Gadgets,点击 Code > Download ZIP,然后在任意方便的位置解压压缩包。
- 进入
code_GFX2/Function/,打开每个演示中 Code location 行所示的文件夹。例如,本板子的 GraphicTest 演示位于code_GFX2/Function/147_ESP32/xiao_esp32s3_147_graphictest/。 - 双击
.ino文件,在 Arduino IDE 中将其打开。
方案 B —— 使用 git clone:
git clone https://github.com/Seeed-Projects/Display-Gadgets.git
然后从克隆得到的 code_GFX2/Function/... 文件夹中打开该演示的 .ino 文件。
屏幕显示 — GraphicTest
此演示在 1.47 英寸 JD9853A 面板上运行完整的图形基准测试,涵盖色条、直线、矩形、圆形、三角形、圆角矩形、文本以及像素渐变。可用来验证屏幕连线是否正确,以及所有绘图调用是否按预期工作。
代码位置: code_GFX2/Function/147_ESP32/xiao_esp32s3_147_graphictest/
工作原理
该草图通过 Seeed_GFX2 初始化 JD9853A 面板,然后依次运行十种图形基本图元,并通过 micros() 测量每一种的执行时间,将结果打印到串口监视器。
显示屏通过一次模板调用完成初始化:
display.begin<Board_XIAO_1inch47_Touch_Display<13, 12>,
Config_Seeed_1inch47_Touch_JD9853A>();
Board 模板负责引脚映射——CS=D2、DC=D3、SCK=D8、MOSI=D10——其 <RST, BL> 模板参数直接使用裸 GPIO 号,因此 <13, 12> 会将 RST 设为 GPIO13(D17),BL 设为 GPIO12(D18)。Panel Config 预设了 172×320 分辨率、BGR 颜色顺序以及无反色——无需 driver.h 或手动写 MADCTL。
运行演示
步骤 1. 在 Arduino IDE 中打开 xiao_esp32s3_147_graphictest.ino。
步骤 2. 选择 Tools > Board > esp32 > XIAO_ESP32S3_PLUS 以及正确的 Port。
步骤 3. 点击 Upload。
步骤 4. 打开 Tools > Serial Monitor(115200 波特率)。你应当能看到每个测试的计时输出:
=== XIAO ESP32-S3 Plus 1.47 graphic test ===
LCD width: 172
LCD height: 320
Color bars: 162.32 ms
Lines: 4562.40 ms
Fast lines: 240.45 ms
Rectangles: 189.31 ms
Filled rectangles: 644.85 ms
Circles: 667.74 ms
Triangles: 531.25 ms
Round rectangles: 236.16 ms
Text: 1899.09 ms
Pixel gradient: 7933.69 ms
Graphic test finished.
在屏幕上,你会看到每个测试图案显示约一秒钟,然后开始下一个。当所有测试完成后,会出现一个带蓝色圆角矩形边框的 “Finished” 屏幕。
预期结果

当草图运行完所有图案后,屏幕会显示 “Graphic Test / Finished” 信息。重置开发板即可再次运行测试。
触摸 — Touch Circle
此演示将 1.47 英寸触摸屏变成一个交互式绘图板。轻触屏幕任意位置,你的指尖处会出现一个白色圆圈。圆圈会保留在屏幕上,随着你不断点击而累积。点击屏幕底部的 CLEAR 条即可清除所有圆圈并重新开始。
代码位置: code_GFX2/Function/147_ESP32/xiao_esp32s3_147_touch_circle/
工作原理
该演示使用 AXS5106L 电容式触摸控制器(I2C 地址 0x63),通过 D4/D5 上的 I2C 连接。控制器报告显示屏像素范围内的绝对 (X, Y) 坐标。触摸由 Seeed_GFX2 的 Touch 层(Touch_AXS5106L)处理:
Touch_AXS5106L touch(-1, D7, Wire, 172, 320);
display.attachTouch(touch, display.panel().driver().bus());
// ...
display.getTouch(&x, &y);
| 引脚 | 功能 |
|---|---|
| D4 (SDA) | I2C 数据总线 — 与 IMU 共享 |
| D5 (SCL) | I2C 时钟总线 — 与 IMU 共享 |
| D7 | 触摸中断 (INT) |
| RST | 与 LCD 复位共享 (GPIO13 / D17) |
边沿触发绘制。 该示例使用边沿检测方式:它只在触摸的下降沿(手指按下瞬间)添加一个圆,而不是在手指按住期间持续添加。这样可以实现干净、明确的点按绘制行为,而不是在拖动时连续绘制轨迹。
X 轴镜像。 触摸面板的物理安装方向与 LCD 不同,因此原始 X 坐标必须镜像。display.getTouch() 已在内部应用了这种镜像并返回屏幕坐标,因此不需要手动进行 screenX = 172 - 1 - rawX 变换。
圆形缓冲区。 最多 120 个圆会存储在一个环形缓冲区中。当缓冲区已满时,最旧的圆会被移除,并重绘屏幕以保持显示干净。
CLEAR 区域。 屏幕底部 36 个像素被保留为 CLEAR 条。点击该区域会擦除所有圆并重置计数器,而不是绘制新圆。
安全绘制区域。 一圈暗灰色边框勾勒出圆形可以完全可见的区域。
运行演示
步骤 1. 在 Arduino IDE 中打开 xiao_esp32s3_147_touch_circle.ino。
步骤 2. 选择开发板和端口,然后点击 Upload。
步骤 3. 打开 Tools > Serial Monitor(115200 波特率)。你应当会看到:
=== XIAO ESP32-S3 Touch Circle Demo ===
LCD: 172x320
Touch: AXS5106L ready
Tap screen to draw white circles.
Tap CLEAR bar at bottom to erase.
步骤 4. 轻触屏幕——每次点击都会打印映射后的屏幕坐标,点击 CLEAR 条会打印擦除消息:
Touch: (76,163)
Touch: (64,226)
Touch: (32,80)
Touch: (118,100)
Touch: (37,311)
Clear zone tapped — erasing all circles.
Touch: (72,143)
Touch: (134,61)
Touch: (61,293)
Clear zone tapped — erasing all circles.
预期结果

每次点击都会在指尖位置留下一个白色圆圈。屏幕标题栏显示运行中的计数。点击 CLEAR 条后,屏幕会重置为空白,并重新绘制边框和标题栏。
SD 卡 — BMP 阅读器
该示例从 MicroSD 卡读取 24 位未压缩 .bmp 图像并在屏幕上显示。它包含内置的 SD 探测测试(写入/读取),并将完整诊断信息打印到串口监视器,非常适合用于验证 SD 卡访问和 BMP 解码。大于 172×320 的图像会被居中裁剪;较小的图像会在屏幕上居中显示。
代码位置: code_GFX2/Function/147_ESP32/xiao_esp32s3plus_147_sd_bmp_reader_diag_v0_8/
工作原理
LCD 和 SD 卡共享相同的物理 SPI 引脚(SCK = D8、MOSI = D10、MISO = D9),但使用独立的 SPI 主机:LCD 运行在 Seeed_GFX2 的 HSPI 主机上,而 SD 卡运行在默认的 ESP32 FSPI 主机上。SD 片选(D6)在空闲时保持为 HIGH,使卡片保持离开共享总线。该示例先读取 SD 卡,再初始化 LCD——它先挂载 SD、将 BMP 解码到 RAM 帧缓冲区、调用 SD.end(),然后才初始化显示屏。这样的顺序可以防止两个 SPI 主机在共享的 D8/D10 引脚上发生冲突。
该示例会以多个 SPI 频率挂载 SD 卡(4 MHz → 1 MHz → 400 kHz),然后运行一个快速写入/读取探测(/SDPROBE.TXT),以在解码任何图像前确认文件系统可访问。随后它会在 SD 根目录中查找 BMP 文件(优先文件名:/test.bmp、/TEST.BMP、/image.bmp、/IMAGE.BMP 等),按行将其解码为 RGB565 帧缓冲区,并在屏幕上绘制结果,同时在顶部显示“BMP OK”标题(显示解码时间),在屏幕底部边缘显示文件路径。
支持的 BMP 格式:
| 格式 | 位深 | 说明 |
|---|---|---|
| 未压缩 BMP (BI_RGB) | 24 位(也接受 16/32 位) | BGR888 转换为 RGB565 进行显示 |
大于 172×320 的图像会被居中裁剪;较小的图像会被居中显示。为获得最佳效果,请使用尺寸恰好为 172×320 像素、名为 /test.bmp 的 24 位未压缩 BMP。
运行演示
步骤 1. 将 MicroSD 卡格式化为 FAT32。
步骤 2. 将一个名为 test.bmp 的 24 位未压缩 BMP 图像(理想尺寸为 172×320 像素)复制到 SD 卡根目录。
步骤 3. 将 SD 卡插入显示板上的 MicroSD 插槽。
步骤 4. 在 Arduino IDE 中打开 xiao_esp32s3plus_147_sd_bmp_reader_diag_v0_8.ino,选择开发板和端口,然后点击 Upload。
步骤 5. 打开 Tools > Serial Monitor(115200 波特率)。你应当会看到:
=== XIAO ESP32-S3 Plus 1.47 SD BMP Reader Diagnostic v0.8 ===
[PIN] SD CS=D6 SCK=D8 MISO=D9 MOSI=D10
[IMG] Put /test.bmp in SD root
[SD] Trying 4000000 Hz...
[SD] OK card=15193 MB freq=4000000 Hz
[PROBE] write /SDPROBE.TXT
[PROBE] write OK
[PROBE] read /SDPROBE.TXT
[PROBE] read OK: XIAO ESP32-S3 SD probe OK
[IMG] open start /test.bmp
[IMG] open done /test.bmp
[IMG] file size=117814
[BMP] header OK path=/test.bmp size=122x320 bpp=24 row=368 offset=54
[IMG] BMP loaded /test.bmp
[DONE] BMP loaded path=/test.bmp readMs=7881 totalMs=8016
具体数值(card=15193 MB、file size=117814、readMs=7881 等)取决于你的 SD 卡和 BMP 文件——你的输出会有所不同。
随后屏幕会显示解码后的图像,顶部有绿色 “BMP OK” 标题(显示解码时间,单位毫秒),底部显示文件路径。
预期结果

图像会显示在屏幕上,顶部带有绿色 “BMP OK” 标题(显示解码时间),底部显示文件路径。如果未找到 BMP 文件,屏幕会显示 “No BMP loaded”,并附带说明,提示检查串口监视器并使用 /test.bmp。
麦克风与扬声器
演示 1:音量条
该示例将板载 PDM 麦克风变成一个大而灵敏的音量计。一个 10 段条形图填充在屏幕中央——低电平为绿色,中等电平为黄色,高电平为红色。条形图上方显示百分比,并会随电平变化颜色。
代码位置: code_GFX2/Function/147_ESP32/xiao_esp32s3_147_mic_canvas/
工作原理
板载 PDM(脉冲密度调制)数字麦克风 通过 ESP32-S3 的 I2S 外设在 PDM RX 模式下进行采样。在 ESP-IDF v5(Arduino core 3.3.11)上,这使用了新的驱动 API(driver/i2s_pdm.h):
| 引脚 | 信号 | 功能 |
|---|---|---|
| D0 | PDM_CLK | 输出到麦克风的 PDM 时钟 |
| D1 | MIC_DATA | 来自麦克风的 PDM 数据输入 |
I2S 外设被配置为16 kHz 单声道,带有 4 个 DMA 描述符,每个包含 256 帧。PDM CLK 驱动强度在初始化后被降低,以最小化电耦合。在主循环中通过 i2s_channel_read() 以 20 ms 超时时间读取采样数据。
信号处理:
- 峰值提取 — 扫描每个 256 采样点的缓冲区,找到绝对值最大的样本(峰值幅度)。
- 归一化 — 将原始峰值从下限 40 映射到上限 16,000,生成 0.0–1.0 的音量值。低于下限的值视为静音。
- 指数平滑 — 显示的音量是原始峰值的指数移动平均(α = 0.20),以防止抖动。当检测到静音时,显示值每帧按 ×0.94 衰减。
音量条绘制:
| 段位 | 颜色 | 音量范围 |
|---|---|---|
| 0–4(底部 5 格) | 绿色 | 0% – 50% |
| 5–8(中间 4 格) | 黄色 | 50% – 90% |
| 9(顶部) | 红色 | 90% – 100% |
该音量条使用差分渲染:仅重绘自上一帧以来状态发生变化的段位。未变化的段位保持不动,从而最小化 SPI 传输并防止闪烁。
运行示例
步骤 1. 在 Arduino IDE 中打开 xiao_esp32s3_147_mic_canvas.ino。
步骤 2. 选择开发板和端口,然后点击 Upload。
步骤 3. 打开 Tools > Serial Monitor(115200 波特率)。你应当看到:
=== Volume Bar (ESP32-S3) ===
[MIC] PDM RX ready (IDF v5)
[MIC] ready — speak or blow into the mic
步骤 4. 对着 PDM 麦克风(位于显示板左下角附近)说话或吹气。音量条会从绿色填充到黄色再到红色,上方的百分比会随之更新。
预期结果

音量条会实时响应。在安静的房间里,音量条保持为空。从约 20 cm 远处以正常音量说话会点亮绿色段位。直接对着麦克风吹气会进入黄色或红色范围。
示例 2:SD 录音机
此示例将开发板变成一个简单的录音机。按下 USR1 录制 5 秒来自板载 PDM 麦克风的音频,将其以 WAV 文件保存到 MicroSD 卡,然后按下 USR2 通过外接的 MAX98357A I2S 功放和扬声器回放录音。
代码位置: code_GFX2/Function/147_ESP32/xiao_esp32s3_147_sd_record/
此示例使用 Seeed_GFX2 进行屏幕状态显示,并使用 esp32 开发板包中自带的 SD.h 进行文件访问。不需要 SdFat。
硬件连接
MicroSD 卡。 在烧录示例或上电之前,将 FAT32 格式化的 MicroSD 卡插入显示板上的卡槽。板载 PDM 麦克风无需任何外部接线。
扬声器输出。 将 MAX98357A I2S 功放模块连接到底部的 I2S 引出焊盘:
| I2S 焊盘 | XIAO 引脚 | GPIO | MAX98357A |
|---|---|---|---|
| I2S_SD | D11 | GPIO38 | DIN |
| I2S_SCK | D12 | GPIO39 | BCLK |
| I2S_WS | D13 | GPIO40 | LRC / WS |
| 3V3 | 3V3 | — | VIN |
| GND | GND | — | GND |
将扬声器连接到 MAX98357A 的 SPK+ 和 SPK- 端子。
工作原理
该示例依次运行四个阶段,按顺序使用四种不同的外设:
PDM 麦克风(录音)。 板载 PDM 麦克风通过 I2S 外设在 PDM RX 模式下,在 D0 (PDM_CLK) 和 D1 (MIC_DATA) 上以 16 kHz 单声道进行采样。为避免录音开头出现“咔嗒”声,前 300 ms 的采集数据会作为预热数据被丢弃。
RAM 缓冲区。 以 16 kHz、16 位单声道录制 5 秒音频需要 160,000 字节(5 s × 16,000 samples/s × 2 bytes)。采样数据先保存在 RAM 缓冲区中,然后再写入 SD 卡。
SD 卡(存储)。 录音被写入 MicroSD 卡上的 /REC_RAW.WAV 文件,使用的是 ESP32 开发板包自带的 SD.h。示例会以多个 SPI 频率挂载 SD 卡——依次尝试 8 MHz → 4 MHz → 1 MHz → 0.4 MHz——直到有一个成功。每次新的录音都会覆盖之前的文件。
此示例在启动时会删除 /REC_RAW.WAV。如果你想保留录音,请在重新启动开发板前将文件拷贝到电脑上。
I2S 回放。 回放时 I2S 外设工作在主机 / 发送模式,配置为 16 kHz、16 位、Philips 立体声。单声道采样会被复制到 I2S 的左右两个声道,从而无论 MAX98357A 选择哪个声道都能播放。
共享 LCD/SD 总线。 LCD 和 SD 卡共用 D8(SCK)、D9(MISO)和 D10(MOSI)引脚。该示例通过为它们分别分配不同的 SPI 主机来避免冲突:
- LCD 使用 Seeed_GFX2 的 HSPI 主机。
- SD 卡 使用 ESP32 的默认 FSPI 主机。
- 在对 SD 卡进行读写之前,示例会调用
display.end()以释放 LCD 对共享引脚的占用,然后在 SD 传输完成后重新初始化显示屏。
这种分离方式避免了 LCD 刷新与 SD 卡访问之间的 SPI 事务冲突。
运行示例
步骤 1. 将一张 FAT32 MicroSD 卡插入显示板上的卡槽。
步骤 2. 按上述说明将 MAX98357A 功放和扬声器连接到 I2S 引出焊盘。
步骤 3. 在 Arduino IDE 中打开 xiao_esp32s3_147_sd_record.ino。
步骤 4. 选择 Tools > Board > esp32 > XIAO_ESP32S3_PLUS(使用 esp32 开发板包 3.3.11)以及正确的 Port,然后点击 Upload。
步骤 5. 上传完成后,屏幕会显示 "SD Recorder"。
步骤 6. 按下 USR1,对着板载 PDM 麦克风说话 5 秒。
步骤 7. 等待屏幕显示 "Saved SD WAV" —— 录音已经写入 SD 卡。
步骤 8. 按下 USR2,通过扬声器回放刚刚录制的音频。
预期结果

- 录音过程中,屏幕会显示录音进度。
- 录音结束后,屏幕会显示 "Saved SD WAV"。
- SD 卡上会生成一个
/REC_RAW.WAV文件。 - 按下 USR2 会通过扬声器回放你刚刚录制的音频。
IMU
1.47'' IPS Display 配备了板载 6 轴 IMU(LSM6DS3),通过 D4/D5 上的 I2C 连接。D14 上的运动中断线支持硬件唤醒和手势检测。
板载 IMU 为 LSM6DS3(已从电路板原理图确认,I2C 地址为 0x6A)。示例草图还会额外探测 QMI8658 兼容传感器作为防御性后备,但出厂的 1.47'' IPS Display 使用的是 LSM6DS3。
下面的两个示例都通过 I2C 读取板载 LSM6DS3。草图同样会探测 QMI8658 兼容传感器作为防御性后备,但抬腕唤醒配置针对的是 LSM6DS3 的寄存器。
示例 1:电子流沙
此示例将屏幕变成一个交互式流体模拟——金色沙粒会根据板载 6 轴 IMU 测得的重力方向流动和沉降。倾斜开发板,沙粒会实时改变流动方向。
代码位置: code_GFX2/Function/147_ESP32/xiao_esp32s3_147_electronic_quicksand/
工作原理
该仿真在 172×320 屏幕上叠加了一个 24×45 占用网格,其中每个单元为 7×7 像素。大约有 180 个粒子 被放置在网格中,每个粒子具有位置、速度以及金色渐变颜色。
IMU 通过 I2C(D4/D5)每 8 ms 读取一次。示例程序会在两个已知地址上探测 IMU——先是 QMI8658,然后是 LSM6DS3——并使用先响应的那个。原始加速度值经过低通滤波,用于推导重力向量。当你倾斜开发板时:
- 重力向量更新 —— 为避免抖动,加速度计数据通过指数移动平均进行平滑处理。
- 粒子速度 —— 每个粒子沿重力向量方向加速,并带有阻尼以及基于其在流体中深度的逐粒子流动性系数。
- 单元占用 —— 在流体中更深(相对于重力更接近“底部”)的粒子流动性更低,从而产生逼真的堆积效果。
- 差分渲染 —— 只重绘粒子进出过的单元,最大限度减少 SPI 传输并保持动画流畅。
靠近表面的粒子流动自如(流动性更高);埋得更深的粒子紧密堆积(流动性更低)——模拟真实沙子的行为。
运行演示
步骤 1. 在 Arduino IDE 中打开 xiao_esp32s3_147_electronic_quicksand.ino。
步骤 2. 选择开发板和端口,然后点击 Upload。
步骤 3. 上传完成后,屏幕底部会被金色粒子填满。将开发板向不同方向倾斜——沙子会像被重力拉动一样流动。
步骤 4. 打开 Tools > Serial Monitor(115200 波特率)以确认初始化:
=== Electronic Quicksand ESP32-S3 1.47 ===
[IMU] LSM6-compatible at 0x6A, WHO=0x6A
预期结果

当你倾斜开发板时,粒子会朝较低的一边流动。当显示屏保持水平放置时,演示会保留之前的重力方向。
演示 2:抬起唤醒
该演示实现了一个由 IMU 内置唤醒中断(连接到 D14)驱动的屏幕休眠/唤醒系统。屏幕会在 8 秒无操作后自动关闭(背光关闭 + ESP32 轻睡眠),当你拿起或移动设备时会立即唤醒。
代码位置: code_GFX2/Function/147_ESP32/xiao_esp32s3_147_wakeup/
工作原理
该演示使用 IMU 的嵌入式唤醒事件检测器——这是一项硬件特性,可在内部监测加速度计数据,当运动超过可配置阈值时拉高 INT1 引脚(在本板上连接到 D14)。这意味着 MCU 不需要持续轮询加速度计。
抬起唤醒演示将板载 LSM6DS3 配置为运动触发唤醒。
IMU 配置(LSM6DS3):
| 寄存器 | 数值 | 用途 |
|---|---|---|
CTRL1_XL | 0x40 | 加速度计 @ 104 Hz,±2g |
TAP_CFG | 0x80 | 启用嵌入式中断 |
WAKE_UP_THS | 0x05 | 唤醒阈值(中低灵敏度) |
WAKE_UP_DUR | 0x00 | 无持续时间滤波(响应快速的唤醒) |
MD1_CFG | 0x20 | 将唤醒信号路由到 INT1 |
休眠/唤醒流程:
- 活动状态 —— 屏幕点亮,背光 PWM 为 160。IMU 数据和电池电压分别每 250 ms / 1000 ms 刷新一次。倒计时计时器显示距离自动休眠剩余的秒数。
- 自动休眠 —— 在 8 秒无任何活动后,示例程序会关闭背光,显示“Sleeping... Pick up device to wake”消息,通过
esp_sleep_enable_gpio_wakeup()将 D14 配置为唤醒源,并进入 ESP32 轻睡眠。 - 唤醒 —— 当用户拿起开发板时,IMU 检测到运动并将 D14 拉高。ESP32 从轻睡眠中唤醒并重绘 UI。
手动测试按键:
| 按键 | 引脚 | 动作 |
|---|---|---|
| USR1 | D19 | 强制唤醒 |
| USR2 | D15 | 强制休眠 |
运行演示
步骤 1. 在 Arduino IDE 中打开 xiao_esp32s3_147_wakeup.ino,选择开发板和端口,然后点击 Upload。
步骤 2. 屏幕会显示一个包含电源状态、运动数据和倒计时计时器的仪表盘。让开发板静止放置 8 秒——它会自动进入休眠。
步骤 3. 拿起开发板或轻轻摇晃——屏幕会立即唤醒。
步骤 4. 打开 Tools > Serial Monitor(115200 波特率)以观察 IMU 检测和唤醒事件:
=== XIAO ESP32-S3 Plus 1.47 IMU Wake Demo ===
[IMU] LSM6-compatible at 0x6A, WHO=0x6A
[IMU] wake config OK
[WAKE] IMU_D14 count=1
[WAKE] IMU_D14 count=2
每次运动唤醒都会打印一行新的 [WAKE] IMU_D14 count=N,其中计数值会递增。休眠切换仅在屏幕上显示——当开发板进入休眠时不会打印串口信息。
预期结果

在唤醒状态下,屏幕会显示实时加速度计和陀螺仪数据。静止 8 秒后,屏幕熄灭,ESP32-S3 进入轻睡眠。拿起设备后,屏幕会在不到一秒的时间内恢复显示,同时唤醒计数器递增。
用户按键
1.47 英寸 IPS 显示屏上有 两个物理按键 连接到 XIAO ESP32-S3 Plus:
| 按键 | 引脚 | 逻辑 | 丝印标识 |
|---|---|---|---|
| BTN_A | D19 | 低电平有效(按下 = LOW) | USR1 |
| BTN_B | D15 | 低电平有效(按下 = LOW) | USR2 |
读取按键
两个按键都使用 XIAO 的内部上拉电阻。一个简单的轮询读取加去抖逻辑如下所示:
const int BTN_A = D19;
const int BTN_B = D15;
void setup() {
pinMode(BTN_A, INPUT_PULLUP);
pinMode(BTN_B, INPUT_PULLUP);
Serial.begin(115200);
}
void loop() {
if (digitalRead(BTN_A) == LOW) {
Serial.println("BTN_A pressed");
delay(200); // simple debounce
}
if (digitalRead(BTN_B) == LOW) {
Serial.println("BTN_B pressed");
delay(200);
}
}
使用中断进行去抖
为了实现响应迅速且已去抖的按键处理,你可以使用 GPIO 中断配合一个短暂的稳定延时:
volatile bool btnAFlag = false;
volatile bool btnBFlag = false;
void btnAIsr() { btnAFlag = true; }
void btnBIsr() { btnBFlag = true; }
void setup() {
pinMode(D19, INPUT_PULLUP);
pinMode(D15, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(D19), btnAIsr, FALLING);
attachInterrupt(digitalPinToInterrupt(D15), btnBIsr, FALLING);
}
void loop() {
if (btnAFlag) {
btnAFlag = false;
delay(30); // debounce settling time
if (digitalRead(D19) == LOW) {
// handle BTN_A press
}
}
if (btnBFlag) {
btnBFlag = false;
delay(30);
if (digitalRead(D15) == LOW) {
// handle BTN_B press
}
}
}
出厂仪表盘中的默认行为
在预烧录的出厂固件中,按键映射如下(你可以在自己的代码中覆盖这些行为):
| 按键 | 动作 |
|---|---|
| BTN_A (D19) | 短按:循环切换屏幕亮度 100% → 75% → 50% → 25% → 0% → 100% |
| BTN_B (D15) | 短按:切换屏幕关闭 / 恢复到上次亮度 |
按键引出焊盘(在板上标记为 U1 和 U2)分别与 D19 和 D15 相连,如果需要,你可以连接外部按键。
电池电压检测
该演示在 D16 上读取板载电池分压,并在 1.47 英寸 IPS 显示屏上以黄色实时显示两项读数:原始 D16 分压电压和计算得到的电池电压。它只显示电压读数;不会估算电池电量百分比,也不会报告充电状态。
代码位置: code_GFX2/Function/147_ESP32/xiao_esp32s3_147_battery_status/
工作原理
电池电路:
ESP32-S3 Plus 通过连接到 D16 的板载分压电路读取 LiPo 电池电压:
| Signal | ESP32-S3 Pin | Function |
|---|---|---|
BAT_ADC | D16 | 模拟输入,用于读取分压后的电池电压。内部连接到一个分压电路(316K / 160K)。请勿在外部使用此引脚。 |
分压比: R14 = 316 kΩ,R15 = 160 kΩ → 分压比 = (316 + 160) / 160 ≈ 2.975
读取过程:
示例程序使用 Board_XIAO_1inch47_Touch_Display<13, 12> 和 Config_Seeed_1inch47_Touch_JD9853A(172×320,BGR,无反色)初始化显示屏,然后以 12 位分辨率、11 dB 衰减,使用 analogReadMilliVolts() 对 D16 进行 12 次采样(间隔 700 µs)。它将这些采样值平均为分压后的原始电压,再乘以分压比得到电池电压(Calc = D16 × 2.975),并将这两个值以两行居中的黄色文本显示。只有当任一数值发生显著变化时(D16 ≥ 0.02 V 或 Calc ≥ 0.05 V),屏幕才会刷新。
没有充电状态信号连接到任何 ESP32-S3 GPIO。本示例仅显示电压读数;它不会检测电池是否存在或充电状态,也不会估算电池电量百分比。
运行示例
步骤 1. 在 Arduino IDE 中打开 xiao_esp32s3_147_battery_status.ino。
步骤 2. 选择 Tools > Board > esp32 > XIAO_ESP32S3_PLUS 和正确的 Port。
步骤 3. 点击 Upload。
步骤 4. 观察屏幕——它会显示两行黄色文本:原始 D16 分压电压和计算得到的电池电压。连接或断开 LiPo 电池(或 USB-C 线缆),即可观察数值的变化。
预期结果
![]() 电压读数(D16 + Calc) | ![]() 电池连接器(背面) |
屏幕顶部一行显示原始 D16 分压电压,底部一行显示计算得到的电池电压(Calc)。当连接 LiPo 电池时,Calc 近似等于电池端电压。在仅使用 USB 供电时也可能出现读数,因此仅凭 Calc 无法确认是否连接了电池。
该示例还会每秒向串口监视器打印一行诊断信息,例如:
D16 1.39V | Calc 4.14V
资源
- 🗃️[PCB 设计文件] XIAO 1.47'' IPS Display (ESP32-S3) KiCad Project
- 📄[原理图] XIAO 1.47'' IPS Display (ESP32-S3) Schematic
- 📦[3D 模型] XIAO 1.47'' IPS Display (STEP)
- 📄[数据手册] 1.47 Inch Display Datasheet
- 💾[出厂固件] XIAO 1.47'' IPS Display (ESP32-S3) Factory Firmware
- [示例] XIAO Display Board 示例代码 — 所有 Function 示例位于
code_GFX2/Function/147_ESP32/目录中
技术支持与产品讨论
感谢您选择我们的产品!我们将为您提供多种支持,以确保您在使用我们产品时拥有尽可能顺畅的体验。我们提供多种沟通渠道,以满足不同的偏好和需求。

