Arduino 开发
本章节包含以下部分,请按需阅读:
Arduino 入门教程
初次接触 Arduino ESP32 开发,想要快速上手?我们为您准备了一套通用的 入门教程。
- 第0节 认识 ESP32
- 第1节 安装和配置 Arduino IDE
- 第2节 Arduino 基础知识
- 第3节 数字输出/输入
- 第4节 模拟输入
- 第5节 脉冲宽度调制 (PWM)
- 第6节 串行通信 (UART)
- 第7节 I2C 通信
- 第8节 SPI 通信
- 第9节 Wi-Fi 基础用法
- 第10节 网页服务器
- 第11节 蓝牙 (Bluetooth)
- 第12节 LVGL 图形界面开发
- 第13节 综合项目
请注意:该教程使用 ESP32-S3-Zero 作为教学示例,所有硬件代码均基于其引脚布局。在动手实践前,建议您对照手中的开发板引脚图,确认引脚配置无误。
配置开发环境
1. 安装和配置 Arduino IDE
请参考 安装和配置 Arduino IDE 教程 下载安装 Arduino IDE 并添加 ESP32 支持。
2. 安装库
- 在安装 Arduino 库时,通常有两种方式可供选择:在线安装 和 离线安装。若库安装要求离线安装,则必须使用提供的库文件。
- 对于大多数库,用户可以通过 Arduino 软件的在线库管理器轻松搜索并安装。然而,一些开源库或自定义库未被同步到 Arduino 库管理器中,因此无法通过在线搜索获取。在这种情况下,用户只能通过离线方式手动安装这些库。
- 可从 此链接 的
Arduino目录中,下载 ESP32-C6-Touch-AMOLED-1.8 开发板的示例程序包。包内的Arduino\libraries目录已包含本教程所需的全部库文件。
| 库或文件名称 | 说明 | 版本 | 安装方式 |
|---|---|---|---|
| GFX Library for Arduino | ST7789 显示驱动图形库 | v1.6.4 | 通过库管理器或手动安装 |
| SensorLib | PCF85063、QMI8658 传感器驱动库 | v0.3.3 | 通过库管理器或手动安装 |
| XPowersLib | AXP2101 驱动库 | v0.2.6 | 通过库管理器或手动安装 |
| lvgl | lvgl 显示显示框架 | v8.4.0 | 通过库管理器或手动安装 |
| Arduino_DriveBus | I2C, 触摸驱动库 | v1.0.1 | 手动安装 |
| Adafruit_BusIO | 抽象化 I2C、SPI | v1.0.1 | 通过库管理器或手动安装 |
| Adafruit_XCA9554 | I2C GPIO 扩展器库 | v1.0.1 | 通过库管理器或手动安装 |
| Mylibrary | 开发板引脚宏定义 | —— | 手动安装 |
| ui_a | 自定义 ui 库 | —— | 手动安装 |
| ui_b | 自定义 ui 库库 | —— | 手动安装 |
| ui_c | 自定义 ui 库 | —— | 手动安装 |
| lv_conf.h | LVGL 配置文件 | —— | 手动安装 |
LVGL 及其驱动库的版本之间存在较强的依赖关系。例如,为 LVGL v8 编写的驱动可能不兼容 LVGL v9。为确保示例能够稳定复现,推荐使用上表列出的特定版本。混合使用不同版本的库可能导致编译失败或运行时异常。
安装步骤:
-
下载 示例程序包。
-
将其
Arduino\libraries目录下的所有文件夹(Arduino_DriveBus、GFX_Library_for_Arduino 等)复制到 Arduino 的库文件夹中。信息Arduino 库文件夹的路径通常是:
c:\Users\<用户名>\Documents\Arduino\libraries。也可以在 Arduino IDE 中通过 文件 > 首选项,查看“项目文件夹位置”来定位。库文件夹就是此路径下的
libraries文件夹。 -
其他安装方式请参考:Arduino 库管理教程。
示例程序
Arduino 示例程序位于 示例程序包 的 Arduino/examples 目录中。
| 示例程序 | 基础例程说明 | 依赖库 |
|---|---|---|
| 01_HelloWorld | 展示了基本的图形库功能,也可以用于测试显示屏的基础性能以及随机文本显示效果 | GFX_Library_for_Arduino |
| 02_Drawing_board | 展示了基本的图形库功能,也可以用于测试显示屏的基础性能以及随机文本显示效果 | GFX_Library_for_Arduino,Arduino_DriveBus,Adafruit_XCA9554 |
| 03_GFX_AsciiTable | 根据屏幕尺寸,在显示屏上按行列打印 ASCII 字符 | GFX_Library_for_Arduino |
| 04_GFX_FT3168_Image | 展示显示图片效果,通过触摸更换显示的图片 | GFX_Library_for_Arduino,Arduino_DriveBus,Adafruit_XCA9554 |
| 05_GFX_PCF85063_simpleTime | GFX 库显示当前时间 | SensorLib,GFX_Library_for_Arduino |
| 06_GFX_ESPWiFiAnalyzer | 在屏幕上绘制 WiFi 频段信号强度 | GFX_Library_for_Arduino |
| 07_GFX_Clock | 通过简单的标记指针和时间管理实现时钟 | GFX_Library_for_Arduino |
| 08_LVGL_Animation | 自定义 UI,控制背光亮度 | LVGL,Arduino_DriveBus,ui_a |
| 09_LVGL_change_background | 自定义 UI,控制背景色 | LVGL,Arduino_DriveBus,ui_b |
| 10_LVGL_PCF85063_simpleTime | LVGL 库显示当前时间 | LVGL,SensorLib |
| 11_LVGL_QMI8658_ui | LVGL 绘制加速度折线图 | LVGL,SensorLib |
| 12_LVGL_Widgets | LVGL 演示 | LVGL,Arduino_DriveBus ,Adafruit_XCA9554 |
| 13_ES8311 | ES8311 驱动示例,播放简单的音频 | —— |
| 14_LVGL_Sqprj | squareline ui 结合 LVGL 示例 | LVGL |
- ESP32-C6-Touch-AMOLED-1.8 选择型号

01_HelloWorld
程序说明
- 本示例演示了如何使用 Arduino GFX 库控制 SH8601 显示屏,通过动态变化的文本展示了基本的图形库功能。该代码也可以用于测试显示屏的基础性能以及随机文本显示效果
硬件连接
- 将开发板接入电脑
代码分析
-
显示初始化:
if (!gfx->begin()) {
USBSerial.println("gfx->begin() failed!");
} -
清屏并显示文本:
gfx->fillScreen(BLACK);
gfx->setCursor(10, 10);
gfx->setTextColor(RED);
gfx->println("Hello World!"); -
动图显示:
gfx->setCursor(random(gfx->width()), random(gfx->height()));
gfx->setTextColor(random(0xffff), random(0xffff));
gfx->setTextSize(random(6), random(6), random(2));
gfx->println("Hello World!");
运行效果

02_Drawing_board
程序说明
- 本示例演示了如何使用 ESP32 通过 I2C 接口控制 FT3168 触摸控制器和 TCA9554 GPIO 扩展器,同时使用 Arduino GFX、Arduino_DriveBus 库来驱动 SH8601 显示屏
硬件连接
- 将开发板接入电脑
代码分析
-
显示屏初始化与亮度渐变动画:
gfx->begin();
gfx->fillScreen(WHITE);
for (int i = 0; i <= 255; i++) {
gfx->Display_Brightness(i);
gfx->setCursor(30, 150);
gfx->setTextColor(BLUE);
gfx->setTextSize(4);
gfx->println("Loading board");
delay(3);
} -
触摸中断处理和坐标读取:
gfx->fillScreen(BLACK);
gfx->setCursor(10, 10);
gfx->setTextColor(RED);
gfx->println("Hello World!"); -
动图显示:
void Arduino_IIC_Touch_Interrupt(void) {
FT3168->IIC_Interrupt_Flag = true;
}
int32_t touchX = FT3168->IIC_Read_Device_Value(FT3168->Arduino_IIC_Touch::Value_Information::TOUCH_COORDINATE_X);
int32_t touchY = FT3168->IIC_Read_Device_Value(FT3168->Arduino_IIC_Touch::Value_Information::TOUCH_COORDINATE_Y);
if (FT3168->IIC_Interrupt_Flag == true) {
FT3168->IIC_Interrupt_Flag = false;
USBSerial.printf("Touch X:%d Y:%d\n", touchX, touchY);
if (touchX > 20 && touchY > 20) {
gfx->fillCircle(touchX, touchY, 5, BLUE);
}
}
运行效果

03_GFX_AsciiTable
程序说明
- 本示例通过使用 Arduino GFX 库在 ESP32 上展示了如何在 SH8601 显示屏上显示一个基本的 ASCII 字符表格。代码的核心功能是初始化显示屏,并根据屏幕尺寸,在显示屏上按行列打印 ASCII 字符
硬件连接
- 将开发板接入电脑
代码分析
-
数据总线和图形显示对象的创建
- 这里创建了一个用于与显示屏通信的数据总线对象 bus,使用特定的引脚配置进行初始化。然后创建了一个图形显示对象 gfx,传入数据总线、复位引脚、旋转角度、是否为 IPS 屏以及显示屏的宽度和高度等参数
Arduino_DataBus *bus = new Arduino_ESP32QSPI(
LCD_CS /* CS */, LCD_SCLK /* SCK */, LCD_SDIO0 /* SDIO0 */, LCD_SDIO1 /* SDIO1 */,
LCD_SDIO2 /* SDIO2 */, LCD_SDIO3 /* SDIO3 */);
Arduino_GFX *gfx = new Arduino_SH8601(bus, -1 /* RST */,
0 /* rotation */, false /* IPS */, LCD_WIDTH, LCD_HEIGHT); -
绘制行列编号和字符表
- 首先设置文本颜色为绿色,在显示屏上逐个打印行号。然后设置文本颜色为蓝色,打印列号。接着使用循环逐个绘制字符,组成字符表,每个字符使用白色前景和黑色背景
gfx->setTextColor(GREEN);
for (int x = 0; x < numRows; x++) {
gfx->setCursor(10 + x * 8, 2);
gfx->print(x, 16);
}
gfx->setTextColor(BLUE);
for (int y = 0; y < numCols; y++) {
gfx->setCursor(2, 12 + y * 10);
gfx->print(y, 16);
}
char c = 0;
for (int y = 0; y < numRows; y++) {
for (int x = 0; x < numCols; x++) {
gfx->drawChar(10 + x * 8, 12 + y * 10, c++, WHITE, BLACK);
}
}
运行效果

04_GFX_FT3168_Image
程序说明
- 本示例通过 ESP32-S3 上的 QSPI 驱动的 SH8601 显示屏实现触摸屏显示界面。集成了一个用于检测触摸输入的 I2C 触摸控制器 (FT3168),以及一个用于管理额外输出引脚的 I2C GPIO 扩展器 (TCA9554)。该代码设置显示屏、触摸控制器和扩展器,并在触摸屏幕时循环显示多个图像
硬件连接
- 将开发板接入电脑
代码分析
- 图像显示:
if (fingers_number > 0) {
switch (Image_Flag) {
case 0: gfx->draw16bitRGBBitmap(0, 0, (uint16_t *)gImage_1, LCD_WIDTH, LCD_HEIGHT); break;
case 1: gfx->draw16bitRGBBitmap(0, 0, (uint16_t *)gImage_2, LCD_WIDTH, LCD_HEIGHT); break;
case 2: gfx->draw16bitRGBBitmap(0, 0, (uint16_t *)gImage_3, LCD_WIDTH, LCD_HEIGHT); break;
case 3: gfx->draw16bitRGBBitmap(0, 0, (uint16_t *)gImage_4, LCD_WIDTH, LCD_HEIGHT); break;
case 4: gfx->draw16bitRGBBitmap(0, 0, (uint16_t *)gImage_5, LCD_WIDTH, LCD_HEIGHT); break;
}
Image_Flag++;
if (Image_Flag > 4) {
Image_Flag = 0;
}
}
代码修改
- 图片内容资源较大,需要设置 Tools ->Partition Scheme -> 16M Flash (3MB APP/9.9MB FATFS)
运行效果
![]() | ![]() | ![]() |
|---|
05_GFX_PCF85063_simpleTime
程序说明
- 本示例演示了使用 PCF85063 RTC 模块在 SH8601 显示屏上显示当前时间,每秒检索时间并仅在时间发生变化时更新显示
硬件连接
- 将开发板接入电脑
代码分析
-
setup:进行程序的初始化设置
- 串口初始化,为输出错误信息提供通道
- 初始化实时时钟芯片,包括连接检查和设置初始时间,确保时间的准确性
- 初始化图形显示设备,设置背景颜色和亮度,为时间显示提供可视化界面
-
loop:在程序运行过程中不断检查时间变化并更新显示屏上的时间显示
- 定期检查时间是否变化,通过比较当前时间和上一次更新时间的差值来确定是否需要更新时间显示
- 获取实时时钟的时间信息并格式化,以便在显示屏上正确显示
- 如果时间发生变化,清除上一次的时间显示区域,设置文本颜色和大小,计算居中位置,并在显示屏上显示新的时间。最后保存当前时间作为上一次时间,以便下次比较
运行效果
06_GFX_ESPWiFiAnalyzer
程序说明
- 本示例演示了在 SH8601 显示器上绘制 WiFi 频段信号强度示例,实现 WiFi 分析器的功能
硬件连接
- 将开发板接入电脑
代码分析
-
setup:为整个程序进行初始化准备
- 初始化串口通信,设置波特率为 115200,用于输出信息和调试
- 将 WiFi 设置为站点模式并断开连接,为后续的网络扫描做准备
- 根据不同的硬件条件进行一些额外的预初始化操作(如果定义了 GFX_EXTRA_PRE_INIT)
- 初始化图形显示设备,计算一些与显示相关的参数,如文本大小、横幅高度等,并设置显示屏亮度。最后绘制初始的横幅信息
-
loop:主要的程序逻辑,包括进行 WiFi 网络扫描、处理扫描结果、绘制图表和显示统计信息,以及根据需要进行节能操作
- WiFi 扫描和处理:进行 WiFi 网络扫描,获取网络数量和各种网络信息;统计每个频道的接入点数量,计算噪声水平和确定信号峰值;根据扫描结果绘制 WiFi 信号强度图表,包括绘制椭圆表示信号强度和显示相关的网络信息
- 显示统计信息:在显示屏上打印找到的网络数量和噪声较小的频道信息,绘制图表的基线和频道标记,并显示每个频道的接入点数量
- 节能操作:根据配置的扫描次数,在满足条件时进行节能操作,如关闭显示屏电源引脚和进入深度睡眠模式
运行效果

07_GFX_Clock
程序说明
- 本示例演示了一个简单的 SH8601 时钟示例,通过简单的标记指针和时间管理实现时钟示例
硬件连接
- 将开发板接入电脑
代码分析
- 时针、分针、秒针的绘制
void redraw_hands_cached_draw_and_erase() {
gfx->startWrite();
draw_and_erase_cached_line(center, center, nsx, nsy, SECOND_COLOR, cached_points, sHandLen + 1, false, false);
draw_and_erase_cached_line(center, center, nhx, nhy, HOUR_COLOR, cached_points + ((sHandLen + 1) * 2), hHandLen + 1, true, false);
draw_and_erase_cached_line(center, center, nmx, nmy, MINUTE_COLOR, cached_points + ((sHandLen + 1 + hHandLen + 1) * 2), mHandLen + 1, true, true);
gfx->endWrite();
}
运行效果
08_LVGL_Animation
程序说明
- 本示例演示了一个简单的 LVGL 滑块示例,可以通过改变滑块的数值改变屏幕背光亮度
硬件连接
- 将开发板接入电脑
代码分析
- 实时修改背光亮度
int32_t slider_value = lv_slider_get_value(ui_Slider1);
int32_t brightness = map(slider_value, 0, 100, 5, 255);
gfx->Display_Brightness(brightness);
运行效果
09_LVGL_change_background
程序说明
- 本示例演示了一个 LVGL 背光明暗场景变化,通过定义简单的按钮组件实现背景颜色的变化
硬件连接
-将开发板接入电脑
代码分析
- setup:负责整个系统的初始化工作
- 首先初始化串口用于可能的调试输出
- 接着初始化 I²C 总线和扩展芯片,设置扩展芯片的引脚模式和初始状态
- 然后不断尝试初始化触摸控制器,成功后设置其电源模式
- 初始化图形显示设备并设置亮度,还打印 LVGL 和 Arduino 的版本信息
- 初始化 LVGL,包括注册调试打印回调函数、初始化显示驱动和输入设备驱动
- 创建并启动 LVGL 的定时器,初始化用户界面并打印设置完成信息
- loop
- 在主循环中不断调用 lv_timer_handler() 让 LVGL 图形库处理各种任务
- 添加了一个小的延迟,避免过度占用 CPU 资源
- my_touchpad_read:读取触摸板的坐标,根据触摸状态设置 LVGL 的输入设备状态,并更新触摸坐标
运行效果
10_LVGL_PCF85063_simpleTime
程序说明
- 本示例演示了在 LVGL 下使用 PCF85063 RTC 模块在 SH8601 显示屏上显示当前时间,每秒检索时间并仅在时间发生变化时更新显示,对比时间刷新效果更佳
硬件连接
- 将开发板接入电脑
代码分析
- setup:负责初始化各种硬件设备和 LVGL 图形库环境
- 串口初始化:USBSerial.begin(115200) 为串口调试做准备
- 实时时钟初始化:尝试初始化实时时钟 rtc,如果失败则进入死循环。设置日期和时间
- 触摸控制器初始化:不断尝试初始化触摸控制器 FT3168,如果初始化失败则打印错误信息并延迟等待,成功后打印成功信息
- 图形显示初始化:初始化图形显示设备 gfx,设置亮度,并打印 LVGL 和 Arduino 的版本信息。接着初始化 LVGL,包括注册打印回调函数用于调试,初始化显示驱动和输入设备驱动。创建并启动 LVGL 的定时器,最后创建一个标签并设置初始文本为 “Initializing...”
- loop
- lv_timer_handler():这是 LVGL 图形库中的一个重要函数,用于处理图形界面的各种定时器事件、动画更新、输入处理等任务。在每个循环中调用这个函数可以确保图形界面的流畅运行和及时响应交互操作
- 时间更新和显示:每秒钟获取一次实时时钟的时间,并通过串口打印出来。然后将时间格式化为字符串,并更新标签的文本显示当前时间。同时设置标签的字体为特定字体。最后添加一个小的延迟
运行效果
11_LVGL_QMI8658_ui
程序说明
- 本示例演示了使用 LVGL 进行图形显示,与 QMI8658 IMU 通信以获取加速度计和陀螺仪数据
硬件连接
- 将开发板接入电脑
代码分析
- setup:负责初始化各种硬件设备和 LVGL 图形库环境
- 串口初始化:USBSerial.begin(115200) 为串口调试做准备
- 触摸控制器初始化:不断尝试初始化触摸控制器 FT3168,如果初始化失败则打印错误信息并延迟等待,成功后打印成功信息
- 图形显示初始化:初始化图形显示设备 gfx,设置亮度,并打印 LVGL 和 Arduino 的版本信息。接着初始化 LVGL,包括注册打印回调函数用于调试,初始化显示驱动和输入设备驱动。创建并启动 LVGL 的定时器,最后创建一个标签并设置初始文本为 “Initializing...”
- 创建图表:创建一个图表对象 chart,设置图表的类型、范围、数据点数量等属性,并为加速度的三个轴添加数据系列
- 加速度传感器初始化:初始化加速度传感器 qmi,配置加速度计和陀螺仪的参数,启用它们,并打印芯片 ID 和控制寄存器信息
- loop
- lv_timer_handler():这是 LVGL 图形库中的一个重要函数,用于处理图形界面的各种定时器事件、动画更新、输入处理等任务。在每个循环中调用这个函数可以确保图形界面的流畅运行和及时响应交互操作
- 读取加速度传感器数据:如果加速度传感器数据准备好,读取加速度数据并通过串口打印出来,同时更新图表显示加速度数据。如果陀螺仪数据准备好,读取陀螺仪数据并通过串口打印出来。最后添加一个小的延迟,增加数据 polling 的频率
运行效果

12_LVGL_Widgets
程序说明
- 本示例演示了 LVGL Widgets 示例,动态状态下帧率可达 50~60 帧,通过优化 SH8601 显示库可实现更佳流畅的帧率,实际可对比 ESP-IDF 环境下启用双缓存、双加速的场景
硬件连接
- 将开发板接入电脑
代码分析
- setup:负责初始化各种硬件设备和 LVGL 图形库环境
- 串口初始化:USBSerial.begin(115200) 为串口调试做准备
- I²C 总线初始化:Wire.begin(IIC_SDA, IIC_SCL); 初始化 I²C 总线,用于与其他 I²C 设备通信
- 扩展芯片初始化:创建并初始化扩展芯片 expander,设置引脚模式为输出,并进行一些初始的引脚状态设置
- 触摸控制器初始化:不断尝试初始化触摸控制器 FT3168,如果初始化失败则打印错误信息并延迟等待,成功后打印成功信息
- 图形显示初始化:初始化图形显示设备 gfx,设置亮度,并获取屏幕的宽度和高度。然后初始化 LVGL,包括注册打印回调函数用于调试,设置触摸控制器的电源模式为监控模式,初始化显示驱动和输入设备驱动。创建并启动 LVGL 的定时器,创建一个标签并设置文本,最后调用 lv_demo_widgets() 展示 LVGL 的示例小部件
- loop
- lv_timer_handler():这是 LVGL 图形库中的一个重要函数,用于处理图形界面的各种定时器事件、动画更新、输入处理等任务。在每个循环中调用这个函数可以确保图形界面的流畅运行和及时响应交互操作
- delay(5);:添加一个小的延迟,避免过度占用 CPU 资源
运行效果
![]() | ![]() |
|---|
13_ES8311
程序说明
- 本示例演示了使用 I2S 驱动 ES8311 芯片,将转换的二进制音频文件进行播放
硬件连接
- 将开发板接入电脑
代码分析
- es8311_codec_init:初始化 ES8311 音频编解码器
- 创建一个 ES8311 编解码器的句柄 es_handle
- 配置 ES8311 的时钟参数,包括主时钟和采样时钟的频率、时钟极性等
- 初始化编解码器,设置音频分辨率为 16 位
- 配置采样频率
- 配置麦克风相关参数,如关闭麦克风、设置音量和麦克风增益
- setup:进行整体的初始化设置,包括串口、引脚、I2S 和 ES8311 编解码器
- 初始化串口用于调试输出
- 设置特定引脚为输出并置高
- 配置 I2S 总线,设置引脚、工作模式、采样率、数据位宽、声道模式等
- 初始化 I²C 总线
- 调用 es8311_codec_init 函数初始化 ES8311 编解码器
- 通过 I2S 总线播放一段预先定义的音频数据(canon_pcm)
运行效果
- 播放音频文件,屏幕无现象
14_LVGL_Sqprj
程序说明
- 本示例演示了 squareline ui 结合 LVGL 示例,使用 QMI8658 传感器实现自适应的屏幕显示方向,通过 WIFI 显示实时时间,通过检测特定区域的触摸输入来改变背光亮度
硬件连接
- 将开发板接入电脑
代码分析
- setup
- 串口初始化
- Wi-Fi 初始化: Wi-Fi 连接和网络时间配置
- I2C 通信与扩展器初始化:初始化 I2C 通信总线,指定 SDA 和 SCL 引脚,配置扩展器的多个引脚(引脚 0、1、2、6)
- 传感器初始化:初始化 QMI8658 传感器,初始化触摸控制器(FT3168 对象)
- 显示屏初始化与相关配置
- loop()
- 基于传感器数据的界面旋转处理
- LVGL 图形界面更新
- 显示屏亮度调节处理
- 界面元素数值更新
运行效果
- 图片内容资源较大,需要设置 Tools ->Partition Scheme -> 16M Flash (3MB APP/9.9MB FATFS)
- 修改为你的可用 wifi

运行效果





