ESP32-S3-RGB-Matrix 使用教程

产品特性​

  • 采用 ESP32-S3-N32R16 芯片,搭载 Xtensa 32 位 LX7 双核处理器,主频高达 240MHz
  • 支持 2.4 GHz Wi-Fi 与 Bluetooth 5 (BLE) 双模通信
  • 内置 512KB SRAM、384KB ROM,叠封 32MB Flash 与 16MB PSRAM,满足多场景存储需求
  • 兼容微雪商店 Matrix-RGB 全系列尺寸,可流畅运行 LVGL 等图形界面程序
  • 板载 ES7210 回声消除芯片,提升语音处理效果
  • 板载 ES8311 低功耗音频编解码芯片,支持高质量音频输入输出
  • 配备双麦克风阵列,支持降噪与回声消除算法,适用于语音识别及唤醒等应用场景
  • 板载喇叭接口,支持音频播放输出,可直接连接喇叭使用
  • 集成 QMI8658 六轴惯性测量单元 (3 轴加速度计 + 3 轴陀螺仪),可实现姿态检测
  • 集成 SHTC3 温湿度传感器,可实现精准的温湿度检测
  • 板载 Micro SD 卡槽,支持图片、音频及各类文件数据存储,方便数据读写
  • 板载 PCF85063 RTC 实时时钟芯片,预留 SH1.0 电池接口,支持掉电持续计时
  • 预留 GPIO 扩展接口,便于外设扩展与功能定制,适配多样化开发需求
  • 双供电接口设计,最多支持 6 块 64 × 64 Matrix-RGB 屏幕稳定工作,支持级联扩展,满足大尺寸显示需求
  • 板载 USB Type-C 接口,支持供电、程序下载与调试,操作便捷
  • 板载 RST / BOOT 按钮,其中 BOOT 按钮支持自定义功能,提升开发灵活性

资源简介​


接口展示​


产品尺寸​


使用说明

为了让用户能够快速了解产品的各个功能,我们提供了一系列的测试例程,方便客户了解各个接口的使用,为了能够运行例程,需要准备的器件如下:

器件准备​

  • 1. ESP32-S3-RGB-Matrix ×1

  • 2. 任意型号的LED屏幕 x1 (如果有级联需求可以准备多个)

  • 3. VH4 2PIN 散头线(约 500mm) ×1 (如果有级联需求可以准备多个)

  • 4. 螺丝包 × 1

  • 5. 扁平线 16PIN 约 200mm × 1 (如果有级联需求可以准备多个)

  • 6. Micro SD卡 × 1

  • 7. 8Ω 5W 喇叭 × 1

  • 8. USB 线 Type-A 公口 → Type-C 公口 ×1

  • 9. PSU-27W-USB-C-EU-B x 1** USB Type-C接口充电器


注意事项​

  • 如需要级联多个屏幕,需要准备多个屏幕和多个扁平线,每个屏幕连接到一个扁平线端,如果供电不足可以准备双USB Type-C接口充电器供电。

  • TF 卡仅支持 MMC 通信方式。

    USB 下载注意事项(重要)

    开发板使用 USB 下载程序

若出现 无法识别端口 的情况,请进入 Boot 模式:

  1. 按住 BOOT 按键
  2. 连接 USB 至电脑
  3. 松开 BOOT 按键

下载完成后,按 RESET 按键运行程序。

编译前需在 menuconfig 中配置以下选项:​


  • Panel Height = 64

  • Panel Width = 64

  • 根据具体像素大小配置,配错会显示错位。

  • Scan Wiring Pattern = Standard

  • 扫描接线方式,选最常见标准模式。

  • Shift Driver IC = Generic

  • 驱动芯片按通用模式初始化,适合大多数普通面板。

  • Bit Depth = 8-bit

  • 颜色精度中等,效果和性能比较平衡。

  • Output Clock Speed = 20MHz

  • 数据输出速度,20MHz 通常稳定且够用。

  • Minimum Refresh Rate = 60Hz

  • 设置最低刷新率 60Hz,减少肉眼闪烁。

  • Default Brightness = 128

  • 默认亮度一半,亮度和功耗折中。

  • Display Rotation = 0°

  • 不旋转,按默认方向显示。

Arduino 开发

本章节包含以下部分,请按需阅读:

Arduino 入门教程​

初次接触 Arduino ESP32 开发,想要快速上手?我们为您准备了一套通用的 入门教程。

请注意:该教程使用 ESP32-S3-Zero 作为教学示例,所有硬件代码均基于其引脚布局。在动手实践前,建议您对照手中的开发板引脚图,确认引脚配置无误。

配置开发环境​

1. 安装和配置 Arduino IDE​

请参考 安装和配置 Arduino IDE 教程 下载安装 Arduino IDE 并添加 ESP32 支持。

板名称板安装要求版本号要求
esp32 by Espressif Systems“离线”安装/“在线”安装3.3.7

Arduino 设置:​


2. 运行示例​

Arduino 示例程序:ESP32-S3-RGB-Matrix 示例程序-GitHub Arduino 示例程序:ESP32-S3-RGB-Matrix 示例程序-Gitee

下面给出每个示例的目的、要点说明与运行效果(以便快速上手)。

示例程序基础例程说明
01_SimpleTestShapes简单形状绘画
02_PatternPlasma等离子特效
03_DoubleBuffer双缓冲测试,绘制动态图形
04_OtherShiftDriverPanel使用驱动芯片驱动屏幕
05_AnimatedGIFPanel_SD读取 SD 卡中的 GIF 图片并显示
06_BitmapIcons显示bmp 图片
07_Pixel_Mapping_Test展示HUB75基本控制逻辑

提示

注意:

  • 若驱动P4系列的屏幕,注意在代码中添加mxconfig.driver = HUB75_I2S_CFG::SHIFTREG;,否则会导致显示异常。

01_SimpleTestShapes​

【代码分析】

  • loop():按顺序执行文字绘制、纯色填充与清屏操作,用于快速验证面板的基础显示功能。
  • drawText(wheelval):根据 wheelval 绘制文字并改变颜色效果,用于检查字符渲染与颜色变化是否正常。
  • dma_display->fillScreen():依次将屏幕填充为黑、红、绿、蓝、白等纯色,便于观察整屏刷新与颜色显示效果。
  • delay(2000):每个显示步骤停留 2 秒,方便肉眼确认画面是否正确。
  • dma_display->clearScreen():在测试结束后清空画面,避免上一帧内容残留。

void loop() {

// animate by going through the colour wheel for the first two lines
drawText(wheelval);
wheelval +=1;
delay(2000);
dma_display->clearScreen();
dma_display->fillScreen(myBLACK);
delay(2000);
dma_display->fillScreen( myRED);
delay(2000);
dma_display->fillScreen(myGREEN);
delay(2000);
dma_display->fillScreen(myBLUE);
delay(2000);
dma_display->fillScreen(myWHITE);
delay(2000);
dma_display->clearScreen();

}

【运行效果】


02_PatternPlasma​

【代码分析】

  • loop():通过逐像素计算与调色板映射生成动态等离子特效。
  • for (int x ...) / for (int y ...):遍历整块面板的每个像素,逐点计算并绘制颜色。
  • sin8()、sin16()、cos16():结合坐标和 time_counter 生成动态变化的中间值 v,构造流动波纹效果。
  • ColorFromPalette(currentPalette, (v >> 8)):根据计算结果从当前调色板中取色。
  • dma_display->drawPixelRGB888():将计算出的 RGB 颜色写入当前像素。
  • time_counter、cycles、fps:分别用于驱动动画变化、统计循环次数和计算绘制帧率。
  • if (cycles >= 1024):重置计数器并随机切换调色板,实现不同色系自动轮换。
  • Serial.printf_P():每 5 秒输出一次 Effect fps,用于观察特效绘制速度。

void loop() {

for (int x = 0; x < PANE_WIDTH; x++) {
for (int y = 0; y < PANE_HEIGHT; y++) {
int16_t v = 128;
uint8_t wibble = sin8(time_counter);
v += sin16(x * wibble * 3 + time_counter);
v += cos16(y * (128 - wibble) + time_counter);
v += sin16(y * x * cos8(-time_counter) / 8);

currentColor = ColorFromPalette(currentPalette, (v >> 8)); //, brightness, currentBlendType);
dma_display->drawPixelRGB888(x, y, currentColor.r, currentColor.g, currentColor.b);
}
}

++time_counter;
++cycles;
++fps;

if (cycles >= 1024) {
time_counter = 0;
cycles = 0;
currentPalette = palettes[random(0,sizeof(palettes)/sizeof(palettes[0]))];
}

// print FPS rate every 5 seconds
// Note: this is NOT a matrix refresh rate, it's the number of data frames being drawn to the DMA buffer per second
if (fps_timer + 5000 < millis()){
Serial.printf_P(PSTR("Effect fps: %d\n"), fps/5);
fps_timer = millis();
fps = 0;
}
} // end loop


【运行效果】


03_DoubleBuffer​

【代码分析】

  • loop():演示双缓冲动画的完整流程,包括切换缓冲区、后台绘制和更新运动状态。
  • display->flipDMABuffer():将后续绘图切换到未显示的后台缓冲区,用于减少动态图形闪烁。
  • delay(1000/display->calculated_refresh_rate):等待当前帧完成显示,避免过早翻转缓冲区导致撕裂或闪烁。
  • display->clearScreen():清空后台缓冲区,为新一帧绘制做准备。
  • delay(25):模拟耗时绘图过程,用于更直观地观察启用双缓冲后的平滑效果。
  • display->fillRect():绘制多个运动方块,形成动态测试画面。
  • velocityx / velocityy 判断逻辑:当方块碰到屏幕边界时反转运动方向,实现反弹效果。
  • Squares[i].xpos / Squares[i].ypos 更新:根据速度更新方块坐标,推动下一帧动画。

void loop()
{

// Flip all future drawPixel calls to write to the back buffer which is NOT being displayed.
display->flipDMABuffer();

// SUPER IMPORTANT: Wait at least long enough to ensure that a "frame" has been displayed on the LED Matrix Panel before the next flip!
delay(1000/display->calculated_refresh_rate);

// Now clear the back-buffer we are drawing to.
display->clearScreen();

// This is here to demonstrate flicker if double buffering is disabled. Emulates a long draw routine that would typically occur after a 'clearscreen'.
delay(25);


for (int i = 0; i < numSquares; i++)
{
// Draw rect and then calculate
display->fillRect(Squares[i].xpos, Squares[i].ypos, Squares[i].square_size, Squares[i].square_size, Squares[i].colour);

if (Squares[i].square_size + Squares[i].xpos >= display->width()) {
Squares[i].velocityx *= -1;
} else if (Squares[i].xpos <= 0) {
Squares[i].velocityx = abs (Squares[i].velocityx);
}

if (Squares[i].square_size + Squares[i].ypos >= display->height()) {
Squares[i].velocityy *= -1;
} else if (Squares[i].ypos <= 0) {
Squares[i].velocityy = abs (Squares[i].velocityy);
}

Squares[i].xpos += Squares[i].velocityx;
Squares[i].ypos += Squares[i].velocityy;
}
}

【运行效果】


04_OtherShiftDriverPanel​

【代码分析】

  • loop():持续生成整屏动态特效,用于验证带移位寄存器驱动芯片面板的显示兼容性。
  • for (int x ...) / for (int y ...):遍历整块屏幕,对每个像素分别计算颜色值。
  • sin8()、sin16()、cos16():结合坐标和 time_counter 生成连续变化的颜色索引。
  • ColorFromPalette(currentPalette, (v >> 8) + 127):根据中间值从调色板中映射出最终颜色。
  • dma_display->drawPixelRGB888():将 RGB 颜色逐点写入 DMA 显示缓冲区。
  • time_counter、cycles、fps:分别用于驱动动画变化、控制换色周期和统计绘制帧率。
  • if (cycles >= 1024):定期重置动画参数并随机切换调色板,便于观察不同色彩下的显示效果。
  • Serial.printf_P():周期输出 FPS 信息,用于评估当前图案绘制速度。
void loop(){
for (int x = 0; x < dma_display->width(); x++) {
for (int y = 0; y < dma_display->height(); y++) {
int16_t v = 0;
uint8_t wibble = sin8(time_counter);
v += sin16(x * wibble * 3 + time_counter);
v += cos16(y * (128 - wibble) + time_counter);
v += sin16(y * x * cos8(-time_counter) / 8);

currentColor = ColorFromPalette(currentPalette, (v >> 8) + 127); //, brightness, currentBlendType);
dma_display->drawPixelRGB888(x, y, currentColor.r, currentColor.g, currentColor.b);
}
}

++time_counter;
++cycles;
++fps;

if (cycles >= 1024) {
time_counter = 0;
cycles = 0;
currentPalette = palettes[random(0,sizeof(palettes)/sizeof(palettes[0]))];
}

// print FPS rate every 5 seconds
// Note: this is NOT a matrix refresh rate, it's the number of data frames being drawn to the DMA buffer per second
if (fps_timer + 5000 < millis()){
Serial.printf_P(PSTR("Effect fps: %d\n"), fps/5);
fps_timer = millis();
fps = 0;
}
}

【运行效果】


05_AnimatedGIFPanel_SD​

【代码分析】

  • setup():完成 SD 卡、HUB75 面板和 GIF 解码器的初始化,为后续播放 GIF 动画做准备。
  • SD_MMC.setPins():配置 SD 卡使用的时钟、命令和数据引脚。
  • SD_MMC.begin("/sdcard", true):以 1-bit 模式挂载 SD 卡文件系统。
  • SD_MMC.cardType()、cardSize()、totalBytes()、usedBytes():读取卡类型、容量和空间占用信息,用于确认存储介质状态。
  • HUB75_I2S_CFG mxconfig(...):配置 HUB75 面板的宽度、高度和级联数量。
  • dma_display = new MatrixPanel_I2S_DMA(mxconfig):创建 DMA 显示对象。
  • dma_display->begin():启动 DMA 显示并分配显示缓冲区。
  • SD_MMC.open("/gifs"):打开 GIF 文件目录。
  • root.openNextFile():遍历 /gifs 目录中的文件。
  • GifFiles.push_back(filename):将找到的 GIF 文件路径保存到列表中,供后续循环播放使用。
  • gif.begin(LITTLE_ENDIAN_PIXELS):初始化 GIF 解码器,并设置像素字节序。
void setup()
{
Serial.begin(115200);

// **************************** Setup SD Card access via SD_MMC 1-bit ****************************
if (!SD_MMC.setPins(BSP_SD_CLK, BSP_SD_CMD, BSP_SD_D0)) {
Serial.println("SD_MMC setPins Failed");
return;
}

if(!SD_MMC.begin("/sdcard", true)){
Serial.println("Card Mount Failed");
return;
}
uint8_t cardType = SD_MMC.cardType();

if(cardType == CARD_NONE){
Serial.println("No SD card attached");
return;
}

Serial.print("SD Card Type: ");
if(cardType == CARD_MMC){
Serial.println("MMC");
} else if(cardType == CARD_SD){
Serial.println("SDSC");
} else if(cardType == CARD_SDHC){
Serial.println("SDHC");
} else {
Serial.println("UNKNOWN");
}

uint64_t cardSize = SD_MMC.cardSize() / (1024 * 1024);
Serial.printf("SD Card Size: %lluMB\n", cardSize);

//listDir(SD_MMC, "/", 1, false);

Serial.printf("Total space: %lluMB\n", SD_MMC.totalBytes() / (1024 * 1024));
Serial.printf("Used space: %lluMB\n", SD_MMC.usedBytes() / (1024 * 1024));



// **************************** Setup DMA Matrix ****************************
HUB75_I2S_CFG mxconfig(
PANEL_RES_X, // module width
PANEL_RES_Y, // module height
PANEL_CHAIN // Chain length
);

// Keep ESP32-S3 default HUB75 mapping to avoid Flash/PSRAM reserved pins.

//mxconfig.clkphase = false;
//mxconfig.driver = HUB75_I2S_CFG::FM6126A;

// Display Setup
dma_display = new MatrixPanel_I2S_DMA(mxconfig);

// Allocate memory and start DMA display
if( not dma_display->begin() )
Serial.println("****** !KABOOM! HUB75 memory allocation failed ***********");

dma_display->setBrightness8(128); //0-255
dma_display->clearScreen();


// **************************** Setup Sketch ****************************
Serial.println("Starting AnimatedGIFs Sketch");

// SD CARD STOPS WORKING WITH DMA DISPLAY ENABLED>...

File root = SD_MMC.open("/gifs");
if(!root){
Serial.println("Failed to open directory");
return;
}

File file = root.openNextFile();
while(file){
if(!file.isDirectory())
{
Serial.print(" FILE: ");
Serial.print(file.name());
Serial.print(" SIZE: ");
Serial.println(file.size());

std::string filename = "/gifs/" + std::string(file.name());
Serial.println(filename.c_str());

GifFiles.push_back( filename );
// Serial.println("Adding to gif list:" + String(filename));
totalFiles++;

}
file = root.openNextFile();
}

file.close();
Serial.printf("Found %d GIFs to play.", totalFiles);
//totalFiles = getGifInventory("/gifs");



// This is important - Set the right endianness.
gif.begin(LITTLE_ENDIAN_PIXELS);

}

【运行效果】


06_BitmapIcons​

【代码分析】

  • setup():完成显示初始化,并通过渐变方式绘制 WiFi 图标,验证位图资源与绘制接口是否正常。
  • dma_display->begin():启动 HUB75 面板显示。
  • dma_display->setBrightness8(90):设置面板亮度。
  • dma_display->fillScreen() / dma_display->clearScreen():初始化和切换阶段清空画面,避免残影干扰。
  • for (int r = 0; r < 255; r++):逐步增加红色分量,用于生成淡入动画。
  • drawXbm565(0,0,64,32, wifi_image1bit, ...):将 WiFi 的 XBM 位图绘制到屏幕上。
  • loop():循环切换不同图标,实现图标轮播显示。
  • drawXbm565(5,0, 32, 32, icon_bits[current_icon]):绘制当前索引对应的图标数据。
  • icon_name[current_icon]:通过串口输出当前显示的图标名称,便于调试。
  • current_icon = (current_icon + 1) % num_icons:循环更新图标索引,确保轮播不会越界。
void setup() {

// put your setup code here, to run once:
delay(1000); Serial.begin(115200); delay(200);


/************** DISPLAY **************/
Sprintln("...Starting Display");
dma_display = new MatrixPanel_I2S_DMA(mxconfig);
dma_display->begin();
dma_display->setBrightness8(90); //0-255
dma_display->clearScreen();

dma_display->fillScreen(dma_display->color444(0, 0, 0));

// Fade a Red Wifi Logo In
for (int r=0; r < 255; r++ )
{
drawXbm565(0,0,64,32, wifi_image1bit, dma_display->color565(r,0,0));
delay(10);
}

delay(2000);
dma_display->clearScreen();
}


void loop() {

// Loop through Weather Icons
Serial.print("Showing icon ");
Serial.println(icon_name[current_icon]);
drawXbm565(5,0, 32, 32, icon_bits[current_icon]);

current_icon = (current_icon +1 ) % num_icons;
delay(2000);
dma_display->clearScreen();

}

【运行效果】


07_Pixel_Mapping_Test​

【代码分析】

  • loop():按行列顺序逐点点亮像素,用于检查面板像素映射与软件配置是否一致。
  • for (int i ...) / for (int j ...):遍历 FourScanPanel 的全部像素坐标。
  • FourScanPanel->drawPixel(j, i, FourScanPanel->color565(255, 0, 0)):将当前像素点亮为红色,形成可观察的扫描轨迹。
  • delay(30):让扫描点以较慢速度移动,便于观察实际点亮顺序。
  • dma_display->clearScreen():整屏扫描完成后清空画面,开始下一轮测试。
  • delay(2000):在每轮扫描结束后停留 2 秒,方便确认映射结果是否正确。
void loop() {
for (int i = 0; i < FourScanPanel->height(); i++)
{
for (int j = 0; j < FourScanPanel->width(); j++)
{
FourScanPanel->drawPixel(j, i, FourScanPanel->color565(255, 0, 0));
delay(30);
}
}
delay(2000);
dma_display->clearScreen();
} // end loop

【运行效果】



ESP-IDF

本章节包含以下部分,请按需阅读:

ESP-IDF 入门教程​

初次接触 ESP32 ESP-IDF 开发,想要快速上手?我们为您准备了一套通用的 入门教程。

请注意:该教程使用 ESP32-S3-Zero 作为教学示例,所有硬件代码均基于其引脚布局。在动手实践前,建议您对照手中的开发板引脚图,确认引脚配置无误。

配置 ESP-IDF 开发环境​

备注

以下内容以 Windows 系统为例,使用 VS Code + ESP-IDF 扩展 的方式进行开发。Mac/Linux 用户请参考 官方说明。

版本选择

此部分图示以安装 ESP-IDF V5.2.2 为例示范,安装时请选用与您开发板示例匹配的 ESP-IDF 版本。

安装 ESP-IDF 开发环境​

  1. 前往 ESP-IDF Installation Manager 下载 ESP-IDF 安装管理器。这是乐鑫最新推出的跨平台安装工具,下文将演示如何使用其离线安装功能。

    在页面中点击 Offline Installer 标签,然后在筛选栏中选择 Windows 操作系统和你需要的 ESP-IDF 版本(图示仅为参考,请以实际为准)。


    确认选择无误后,点击下载按钮。浏览器将自动同时下载两个文件:一个是 ESP-IDF 离线整合包(.zst),另一个是 ESP-IDF 安装器(.exe)。


    请耐心等待两个文件下载完成。

  2. 下载完成后,双击运行 ESP-IDF 安装器(eim-gui-windows-x64.exe)。

    启动后,可在右上角将界面语言切换为中文。


    安装工具会自动检测同一目录下是否存在离线整合包。点击 从存档安装。


    接下来,选择安装路径。建议使用默认路径;若需自定义,请确保路径中不包含中文或空格。确认无误后,点击 开始安装。


  3. 当看到如下界面时,表示 ESP-IDF 已安装成功。


  4. 建议同时安装驱动程序。点击 完成安装,然后点击 安装驱动程序。


安装 Visual Studio Code 与 ESP-IDF 扩展​

  1. 下载并安装 Visual Studio Code。

  2. 安装时建议勾选 通过 Code 打开操作添加到 Windows 资源管理器文件上下文菜单,以便快速打开项目文件夹。

  3. 在 VS Code 中,点击侧边活动栏中的 扩展图标 扩展图标(或使用快捷键 Ctrl + Shift + X)打开 扩展 视图。

  4. 在搜索框中输入 ESP-IDF,找到 ESP-IDF 扩展并点击安装。


  5. 当 ESP-IDF 扩展版本 ≥ 2.0 时,扩展会自动检测并识别上述步骤中安装的 ESP-IDF 环境,无需手动配置。

示例程序​

IDF 示例程序:ESP32-S3-RGB-Matrix 示例程序-GitHub IDF 示例程序:ESP32-S3-RGB-Matrix 示例程序-Gitee

下面给出每个示例的目的、要点说明与运行效果(以便快速上手)。

示例程序基础例程说明
01_Matrix_RGBW简单测试 RGBW 灯颜色切换
02_Matrix_Font_5x7测试 5x7 字体显示
03_Matrix_QMI测试 QMI 功能显示
04_Matrix_RTC测试 RTC 时间显示
05_Matrix_SDCard测试 SD 卡挂载与容量读取
06_Matrix_SHTC3测试 SHTC3 温湿度传感器
07_Matrix_WiFi测试 WiFi 连接
08_Matrix_Audio测试音频播放

注意
  • 03_Matrix_QMI,06_Matrix_SHTC3,08_Matrix_Audio 这个三个示例是针对64x64像素大小的屏幕设计的,如果使用其他像素大小的屏幕,会出现文字显示重叠或错位。

01_Matrix_RGBW​


【代码分析】

  • rgbw_start():循环切换板载 RGBW 灯颜色,用于验证灯光驱动与日志输出是否正常。
  • sizeof(rgbw_colors) / sizeof(rgbw_colors[0]):计算预设颜色数组长度,供循环切换使用。
  • bsp_display_lock():加锁后操作显示界面,避免与其他显示任务冲突。
  • lv_obj_set_style_bg_color(screen, lv_color_hex(0x000000), 0):将当前屏幕背景设置为黑色,减少灯光测试时的界面干扰。
  • rgbw_set_color(rgbw_colors[color_index].hex_color):把当前颜色值输出到 RGBW 灯珠。
  • ESP_LOGI(TAG, "Current color: %s", ...):打印当前颜色名称,便于调试和观察切换顺序。
  • vTaskDelay(pdMS_TO_TICKS(2000)):每种颜色保持 2 秒,方便观察显示效果。
  • if (color_index >= num_colors):颜色索引到达末尾后回到起点,实现循环切换。
void rgbw_start(void) {
/* =======================
* 1. Basic Parameters
* ======================= */
int color_index = 0;
const int num_colors = sizeof(rgbw_colors) / sizeof(rgbw_colors[0]);

/* =======================
* 2. Init Screen
* ======================= */
bool locked = bsp_display_lock(1000);
if (locked) {
lv_obj_t *screen = lv_scr_act();
lv_obj_set_style_bg_color(screen, lv_color_hex(0x000000), 0);
bsp_display_unlock();
}
/* =======================
* 3. Loop Colors
* ======================= */
while (true) {
locked = bsp_display_lock(1000);
if (locked) {
rgbw_set_color(rgbw_colors[color_index].hex_color);
bsp_display_unlock();
}
ESP_LOGI(TAG, "Current color: %s", rgbw_colors[color_index].name);
vTaskDelay(pdMS_TO_TICKS(2000));
color_index++;
if (color_index >= num_colors) {
color_index = 0;
}
}
}

【运行效果】



02_Matrix_Font_5x7​


【代码分析】

  • font_5x7_start():启动 5x7 字体示例界面,并保持任务常驻运行。
  • ESP_LOGI(TAG, "Matrix Font 5x7 start"):输出启动日志,便于确认示例已经进入运行状态。
  • bsp_display_lock(0):进入 LVGL 显示上下文前先加锁,确保界面初始化过程安全。
  • font_5x7_ui_init():创建 5x7 字体示例所需的界面对象。
  • font_5x7_ui_apply():将字体、布局和默认文本等配置应用到界面上。
  • while (true):保持任务持续存在,避免示例初始化后立即退出。
  • vTaskDelay(pdMS_TO_TICKS(1000)):空闲等待,降低任务空转占用。
void font_5x7_start(void) {
/* =======================
* 1. Start Display
* ======================= */
ESP_LOGI(TAG, "Matrix Font 5x7 start");
/* =======================
* 2. Init UI (LVGL Locked)
* ======================= */
bool locked = bsp_display_lock(0);
if (locked) {
font_5x7_ui_init();
font_5x7_ui_apply();
bsp_display_unlock();
}

/* =======================
* 3. Idle Loop
* ======================= */
while (true) {
vTaskDelay(pdMS_TO_TICKS(1000));
}
}

【运行效果】


03_Matrix_QMI​


【代码分析】

  • qmi_start():完成 QMI8658 传感器界面初始化、驱动启动和定时刷新配置。
  • qmi_ui_init():创建 QMI8658 数据显示界面。
  • middle_init_qmi8658():初始化 QMI8658 传感器驱动。
  • qmi_state.qmi_init_ret:保存传感器初始化结果,供界面层判断状态并显示提示。
  • example_ui_install_timer(100, qmi_data_update):安装 100 ms 周期定时器,定时刷新姿态或加速度数据。
  • qmi_data_update:在定时回调中更新传感器数据与界面显示。
  • while (true):保持任务常驻运行。
  • vTaskDelay(pdMS_TO_TICKS(1000)):空闲等待,减少任务资源占用。
void qmi_start(void) {
/* =======================
* 1. Start Display & UI
* ======================= */
bool locked = bsp_display_lock(0);
if (locked) {
qmi_ui_init();
bsp_display_unlock();
}

/* =======================
* 2. Start Sensor & Timer
* ======================= */
qmi_state.qmi_init_ret = middle_init_qmi8658();
locked = bsp_display_lock(0);
if (locked) {
example_ui_install_timer(100, qmi_data_update);
bsp_display_unlock();
}

/* =======================
* 3. Idle Loop
* ======================= */
while (true) {
vTaskDelay(pdMS_TO_TICKS(1000));
}
}

【运行效果】


04_Matrix_RTC​


【代码分析】

  • rtc_start():完成 RTC 界面初始化、设时、闹钟配置和实时刷新。
  • rtc_ui_init():创建时间显示相关的界面元素。
  • middle_rtc_init():初始化 RTC 驱动与底层硬件接口。
  • middle_rtc_set_time(rtc_state.rtc_time):将状态结构体中的初始时间写入 RTC 芯片。
  • middle_rtc_alarm(3):配置 RTC 闹钟测试条件,用于验证闹钟功能是否正常。
  • example_ui_install_timer(1, rtc_data_update):安装高频刷新定时器,使界面实时同步当前时间。
  • rtc_data_update:在回调中读取 RTC 数据并更新显示内容。
  • while (true):保持 RTC 示例任务持续运行。
void rtc_start(void) {
bool locked = bsp_display_lock(0);
if (locked) {
rtc_ui_init();
bsp_display_unlock();
}
middle_rtc_init();
middle_rtc_set_time(rtc_state.rtc_time);
middle_rtc_alarm(3);
locked = bsp_display_lock(0);
if (locked) {
example_ui_install_timer(1, rtc_data_update);
bsp_display_unlock();
}
while (true) {
vTaskDelay(pdMS_TO_TICKS(1000));
}
}

【运行效果】


05_Matrix_SDCard​


【代码分析】

  • sdcard_start():完成 SD 卡界面初始化、底层驱动启动和状态定时刷新。
  • sdcard_ui_init():创建用于显示挂载状态、容量和存储信息的界面组件。
  • middle_sdcard_init():执行 SD 卡底层初始化,通常包括总线配置、卡识别和文件系统挂载。
  • example_ui_install_timer(1000, sdcard_data_update):安装 1 秒周期定时器,定时刷新 SD 卡状态与容量信息。
  • sdcard_data_update:在回调中更新 SD 卡显示内容。
  • while (true):保持示例任务持续运行。
  • vTaskDelay(pdMS_TO_TICKS(1000)):空闲等待,减少任务占用。
void sdcard_start(void) {
/* =======================
* 1. Start Display & UI
* ======================= */
bool locked = bsp_display_lock(0);
if (locked) {
sdcard_ui_init();
bsp_display_unlock();
}

/* =======================
* 2. Init SD Card
* ======================= */
middle_sdcard_init();

/* =======================
* 3. Periodic Refresh
* ======================= */
locked = bsp_display_lock(0);
if (locked) {
example_ui_install_timer(1000, sdcard_data_update);
bsp_display_unlock();
}

/* =======================
* 4. Idle Loop
* ======================= */
while (true) {
vTaskDelay(pdMS_TO_TICKS(1000));
}
}

【运行效果】


06_Matrix_SHTC3​


【代码分析】

  • shtc3_start():完成 SHTC3 界面初始化、驱动启动和温湿度数据周期刷新。
  • shtc3_ui_init():创建温度、湿度和状态提示等界面元素。
  • middle_init_shtc3():初始化 SHTC3 传感器驱动。
  • shtc3_state.shtc3_init_ret:保存初始化结果,供界面层判断是否正常显示数据。
  • example_ui_install_timer(500, shtc3_data_update):安装 500 ms 周期定时器,定时更新传感器数据。
  • shtc3_data_update:在回调中读取温湿度信息并刷新界面。
  • while (true):保持示例任务持续运行。
  • vTaskDelay(pdMS_TO_TICKS(1000)):空闲等待,降低任务占用。
void shtc3_start(void) {
/* =======================
* 1. Start Display & UI
* ======================= */
bool locked = bsp_display_lock(0);
if (locked) {
shtc3_ui_init();
bsp_display_unlock();
}
/* =======================
* 2. Init Sensor & Timer
* ======================= */
shtc3_state.shtc3_init_ret = middle_init_shtc3();
locked = bsp_display_lock(0);
if (locked) {
example_ui_install_timer(500, shtc3_data_update);
bsp_display_unlock();
}

/* =======================
* 3. Idle Loop
* ======================= */
while (true){
vTaskDelay(pdMS_TO_TICKS(1000));
}
}

【运行效果】


07_Matrix_WiFi​


【代码分析】

  • wifi_start():完成 WiFi 界面初始化、STA 参数配置、驱动启动和状态刷新。
  • wifi_ui_init():创建网络状态显示界面。
  • middle_wifi_set_sta_config(WIFI_STA_SSID, WIFI_STA_PASS):设置目标热点的 SSID 和密码。
  • middle_wifi_init():启动 WiFi 驱动并发起连接流程。
  • wifi_state.wifi_init_ret:保存 WiFi 初始化结果,供界面显示连接状态。
  • example_ui_install_timer(1000, wifi_data_update):安装 1 秒周期定时器,定时刷新连接状态和网络信息。
  • wifi_data_update:在回调中更新 WiFi 连接状态、IP 地址等界面内容。
  • while (true):保持示例任务持续运行。
void wifi_start(void) {
/* =======================
* 1. Start Display & UI
* ======================= */
bool locked = bsp_display_lock(0);
if (locked) {
wifi_ui_init();
bsp_display_unlock();
}

/* =======================
* 2. Configure & Enable WiFi
* ======================= */
middle_wifi_set_sta_config(WIFI_STA_SSID, WIFI_STA_PASS);
wifi_state.wifi_init_ret = middle_wifi_init();

/* =======================
* 3. Periodic Refresh
* ======================= */
locked = bsp_display_lock(0);
if (locked) {
example_ui_install_timer(1000, wifi_data_update);
bsp_display_unlock();
}

/* =======================
* 4. Idle Loop
* ======================= */
while (true) {
vTaskDelay(pdMS_TO_TICKS(1000));
}
}

【运行效果】


08_Matrix_Audio​


【代码分析】

  • audio_start():完成音频界面初始化、音频任务创建和状态定时刷新。
  • audio_ui_init():创建音量、播放状态或频谱相关的界面元素。
  • audio_state.audio_out_vol = VOLUME:设置默认音频输出音量。
  • xTaskCreate(audio_task, "aud", 4096, NULL, tskIDLE_PRIORITY + 4, NULL):创建独立音频任务,在后台处理音频业务逻辑。
  • example_ui_install_timer(100, audio_data_update):安装 100 ms 周期定时器,定时同步音频状态到界面。
  • audio_data_update:在回调中更新播放状态、音量或其他音频信息。
  • while (true):保持示例任务持续运行。
  • vTaskDelay(pdMS_TO_TICKS(1000)):空闲等待,降低主任务占用。
void audio_start(void) {
/* =======================
* 1. Start Display & UI
* ======================= */
bool locked = bsp_display_lock(0);
if (locked) {
audio_ui_init();
bsp_display_unlock();
}
/* =======================
* 2. Start Audio Task
* ======================= */
audio_state.audio_out_vol = VOLUME;
xTaskCreate(audio_task, "aud", 4096, NULL, tskIDLE_PRIORITY + 4, NULL);
/* =======================
* 3. Periodic UI Refresh
* ======================= */
locked = bsp_display_lock(0);
if (locked) {
example_ui_install_timer(100, audio_data_update);
bsp_display_unlock();
}
/* =======================
* 4. Idle Loop
* ======================= */
while (true) {
vTaskDelay(pdMS_TO_TICKS(1000));
}
}

【运行效果】



相关资料

1. 硬件资料​

开发板设计文件

2. 技术手册​

3. 示例程序​

4. 软件工具​