ESP32-S3 决赛离线工具包

乐鑫 ESP32-S3-DevKitC-1-N8R8|Arduino + PlatformIO|八套押题 + 万能工程|完全离线

第一次打开,只做这五步

  1. 打开 押题工程选择器,按任务书关键词选择最接近的工程。
  2. 在 VS Code 中直接打开 D:\AI开发\ceping\arduino_pio\工程名,必须看得到 platformio.ini
  3. 先看 include/contest_user_config.h 改引脚,再看 src/task_logic.cpp改题目规则。
  4. 先点击 PlatformIO 的勾号编译,成功后再接线、烧录并打开 115200 串口。
  5. 输入 SELFTESTPINOUTSTATUS,然后按评分点逐项修改和验收。

比赛只走 Arduino 路线。不要新增 lib_deps,不要临时切换框架。每个代码文件顶部已经用中文说明文件作用、调用关系和现场修改位置。

30 秒选择工程

题目最难的部分首选工程任务书
分级报警、静音、闪烁mock_01_alarm押题 01
Touch、ADC 阈值、保持mock_02_touch_adc押题 02
ASCII 文本命令、查询上报mock_03_uart_controller押题 03
倒计时、阶段、顺序控制mock_04_traffic_timer押题 04
计数、秒表、反应时间mock_05_button_stopwatch押题 05
帧头、LEN、CMD、SUM/CRCmock_06_binary_uart押题 06
模拟量、PWM、亮度、频率mock_07_adc_pwm押题 07
密码、序列输入、三错锁定mock_08_touch_access押题 08
多个模块混合,无法归类universal_console万能速查

打开详细选择器可查看每种题通常改哪个函数。

整个离线工具包的结构

下面是你会在磁盘看到的完整逻辑结构。带“历史备份”或“自动生成”的目录比赛时不用打开。

D:\AI开发\ceping\
├─ README_FIRST.html                 ← 总入口,就是本页
├─ arduino_pio\                      ← 比赛真正使用的 9 个完整工程
│  ├─ universal_console\             ← 无法归类时的万能兜底
│  ├─ mock_01_alarm\                 ← 声光报警
│  ├─ mock_02_touch_adc\             ← Touch + ADC
│  ├─ mock_03_uart_controller\       ← UART 文本命令
│  ├─ mock_04_traffic_timer\         ← 倒计时/顺序状态机
│  ├─ mock_05_button_stopwatch\      ← 秒表/反应测试
│  ├─ mock_06_binary_uart\           ← UART 二进制帧
│  ├─ mock_07_adc_pwm\               ← ADC/PWM 联动
│  └─ mock_08_touch_access\          ← Touch 密码门禁
├─ docs\                             ← 全部离线 HTML 教程
│  ├─ index.html                     ← 文档目录
│  ├─ question_router.html           ← 题目关键词选工程
│  ├─ mock_01...mock_08.html         ← 八份任务书与评分表
│  ├─ arduino_quickstart.html        ← VS Code / PlatformIO 操作
│  ├─ quick_reference.html           ← 引脚、API、改题速查
│  ├─ special_drills.html            ← 八道专项训练
│  ├─ troubleshooting.html           ← 编译、烧录、硬件排障
│  ├─ build_verification.html        ← 九个固件大小和 SHA-256
│  ├─ idf_quickstart.html            ← 历史备份说明,不用打开
│  └─ style.css                      ← 所有 HTML 共用样式
├─ modules\                          ← 可复制的最小代码片段
│  ├─ arduino\                       ← 比赛可用,8 个中文注释片段
│  └─ esp_idf\                       ← 历史备份,不用打开
├─ tools\                            ← PowerShell/CMD 离线工具
│  ├─ build_arduino.ps1              ← 编译一个 Arduino 工程
│  ├─ build_all_arduino.ps1          ← 编译全部 9 个工程
│  ├─ verify_arduino_offline.ps1     ← 本地依赖扫描 + 全量编译
│  ├─ flash_arduino.ps1              ← 编译并烧录指定 COM 口
│  ├─ monitor.ps1                    ← 打开 115200 串口
│  ├─ detect_ports.ps1               ← 查找开发板 COM 口
│  ├─ open_docs.ps1                  ← 打开本页
│  ├─ *.cmd                          ← 可双击运行的脚本入口
│  └─ *idf*.ps1 / build_all.ps1      ← 历史双框架脚本,不用打开
├─ shared\arduino\ContestToolkit\   ← 公共库的中文注释母版
├─ esp_idf\                          ← 早期 ESP-IDF 四工程,历史备份
├─ .openteams\specs\                ← 工具包设计稿,不参与编译
└─ .playwright-mcp\                  ← 文档检查生成目录,不参与比赛

每个 Arduino 工程编译后还会出现:
└─ .pio\build\esp32s3_n8r8\         ← PlatformIO 自动生成,不要手改
   ├─ firmware.bin                   ← 最终固件
   └─ firmware.elf / 中间文件

一个押题工程里面有什么

arduino_pio\mock_XX_xxx\
├─ platformio.ini
├─ include\
│  └─ contest_user_config.h
├─ src\
│  ├─ main.cpp
│  ├─ task_logic.h
│  └─ task_logic.cpp
└─ lib\ContestToolkit\
   ├─ library.json
   └─ src\
      ├─ ContestToolkit.h / .cpp
      └─ Ws2812Rmt.h / .cpp
文件它是干什么的现场是否修改
platformio.ini选择 ESP32-S3、Arduino、N8R8 内存和 115200 串口通常不改
contest_user_config.h集中放 RGB、Touch、ADC、按键、蜂鸣器、UART 和普通输出引脚先改这里
main.cpp程序起点,只负责创建应用并调用 begin/loop通常不改
task_logic.h把当前题型的回调注册函数告诉 main.cpp通常不改
task_logic.cpp状态、按键动作、Touch 动作、ADC 规则、定时输出和专属命令主要改这里
ContestToolkit.h/.cpp消抖、定时器、Touch、ADC、通用命令、NVS、输出的稳定底层不要先改
Ws2812Rmt.h/.cpp把 RGB 数值转换成板载 WS2812 需要的精准波形通常不改
library.json告诉 PlatformIO 这是本地库;JSON 格式不能写注释不要改

程序从哪里开始,到哪里结束

顺序函数通俗解释
1setup()上电后只执行一次,是整个程序起点。
2app.begin()初始化串口、默认参数、NVS、GPIO、定时器、Touch 和当前题型。
3loop()setup 结束后无限重复,程序正常运行没有传统意义上的“结束”。
4app.loop()每 10 ms 检查串口、按键、Touch、ADC 和蜂鸣器超时。
5shortPress / touchChanged / adcSample公共底层确认输入可靠后,通知当前题型发生了什么。
6tick()根据当前状态决定 RGB、蜂鸣器、GPIO 或 PWM 应该怎样输出。
7回到 loop()继续下一轮,直到断电或复位。

一句话:公共库负责“看见输入”,task_logic.cpp负责“决定怎么办”,输出函数负责“让硬件表现出来”。

task_logic.cpp 常用函数翻译

函数什么时候调用题目变化时通常改什么
beginTask(app)硬件初始化完成后调用一次默认状态、题型专属默认参数
printHelp(app)输入 HELP 时新增专属命令后补帮助文案
shortPress(app)按键消抖后确认一次短按短按切换哪个状态或增加什么数值
longPress(app)按住至少约 1.2 秒再松开复位、确认、清零、紧急模式
touchChanged(app, active)Touch 稳定触发或松开通常只在 active=true时执行一次动作
adcSample(app, millivolts)完成一轮 ADC 去极值平均阈值、分档、映射和传感器触发规则
tick(app, now_ms)约每 10 ms状态转换、倒计时、灯、声音和 GPIO 输出
command(app, command, arguments)公共命令不认识时增加题目专属串口命令和参数校验
status(app)输入 STATUS 时打印本题最关键的内部变量
createTaskHooks()main.cpp 创建 app 时通常不改;它把上面函数注册给底层

题目不完全一样时怎样改

  1. 先选最难模块作为底座。二进制协议选 06,复杂倒计时选 04,ADC/PWM 选 07。
  2. 先只改引脚。修改 contest_user_config.h 后立即编译,确认工程基础没有坏。
  3. 把题目写成状态。例如待机、运行、报警就是 mode 0、1、2。
  4. 把输入规则放进事件函数。短按做什么写 shortPress,ADC 超限做什么写 adcSample
  5. 把状态对应输出放进 tick。不要用长 delay() 等待。
  6. 需要另一题的能力时只复制相关函数思路。九个工程的 ContestApp接口相同,不要复制整份公共库。
  7. 每拿一个评分点就编译和测试。先输入输出,再状态机,再串口/NVS,最后做错误处理。
例子选择底座怎样组合
“温度分档报警风扇”07 ADC/PWM保留 ADC/PWM,从 01 参考静音和报警闪烁规则
“串口协议控制交通灯”06 二进制 UART保留帧解析,把 04 的阶段状态机写进 06 的 tick
“密码门禁并定时上报”08 Touch 门禁保留密码状态机,参考 03 的 report_ms 周期上报

哪些能改,哪些不要先改

级别内容规则
优先修改contest_user_config.htask_logic.cpp引脚、阈值、时间、状态、输出、专属命令都在这里。
按需参考modules/arduino只复制你理解并需要的片段,先看文件顶部依赖说明。
通常不改main.cpptask_logic.hplatformio.ini除非题目或环境明确要求,否则保持原样。
不要先改lib/ContestToolkitshared它们是九套工程共同验证过的稳定底层。
绝对不手改.piofirmware.bin、中间文件每次编译自动生成,改了也会被覆盖。

默认接线

功能引脚接法
板载 RGBGPIO38v1.1;若不亮改为 GPIO48
TouchGPIO4接导电片,校准时不要触碰
ADCGPIO1电位器中间脚;两端接 3V3 和 GND
按键GPIO15按钮接 GPIO15 与 GND,使用内部上拉
蜂鸣器GPIO16无源蜂鸣器;大电流器件增加三极管
UART1TX17 / RX18交叉连接 USB-TTL,电平必须为 3.3 V并共地
普通 LED/PWMGPIO21GPIO21 → 220 Ω → LED → GND

禁止把 5 V 直接输入 GPIO 或 ADC。ESP32-S3 GPIO 不是 5 V 耐受,ADC 输入不得超过 3.3 V。N8R8 默认避开 GPIO35–37。

公共串口命令

HELP                  # 显示公共命令和本题专属命令
PINOUT                # 显示固件实际使用的引脚
SELFTEST              # RGB、蜂鸣器、ADC、Touch、按键、NVS 快速检查
STATUS                # 显示公共状态和本题内部状态
LED 255 0 0           # 手动设置 RGB
BEEP 2000 300         # 2000 Hz 鸣叫 300 ms
ADC READ              # 立即读取一次 ADC
ADC AUTO 500          # 每 500 ms 采样
TOUCH READ            # 查看 Touch 原始值和基线
TOUCH CAL             # 重新校准 Touch
MODE 2                # 切换本题 mode
SET ADC_LOW 1000      # 设置低阈值,单位 mV
SET ADC_HIGH 2200     # 设置高阈值,单位 mV
SET BLINK 300         # 设置闪烁半周期,单位 ms
SET REPORT 1000       # 设置自动上报周期,单位 ms
SAVE / LOAD / FACTORY # 保存、读取、恢复默认值

串口固定为 115200 8N1。文本命令不区分大小写,以回车或换行结束。06 二进制协议使用 UART1,USB 串口只看调试日志。

构建、烧录和串口

VS Code / PlatformIO

  1. “文件 → 打开文件夹”,选择一个含 platformio.ini 的押题工程。
  2. 状态栏勾号:编译;箭头:烧录;插头:串口监视器。
  3. 烧录失败时关闭串口监视器;必要时按住 BOOT、点 RESET、松开 BOOT 后重试。

PowerShell 备用

# 查 COM 口
.\tools\detect_ports.ps1

# 编译一套工程
.\tools\build_arduino.ps1 mock_04_traffic_timer

# 烧录,COM5 换成实际端口
.\tools\flash_arduino.ps1 mock_04_traffic_timer COM5

# 打开串口
.\tools\monitor.ps1 COM5

# 断网检查并编译全部 9 个工程
.\tools\verify_arduino_offline.ps1

比赛前检查清单

  • 关闭 Wi-Fi 后运行 tools\verify_arduino_offline.ps1,看到 ALL 9 ARDUINO PROJECTS BUILD OK
  • 连接开发板运行 tools\detect_ports.ps1,记下 COM 号。
  • 烧录万能工程,依次执行 SELFTESTPINOUTSTATUS
  • 确认板载 RGB 使用 GPIO38 还是 GPIO48,并固定配置。
  • 实测按键、Touch、ADC、蜂鸣器、普通 LED 和 UART1。
  • 给 USB 数据线、杜邦线、按键、蜂鸣器、电位器准备备件。
  • 把本页、选题页、八份任务书和排障页加入浏览器书签。

九个工程的最新固件大小与校验值见 构建验收记录。没有连接开发板时,“编译成功”不能代替“硬件已验证”。