模拟任务书
- ADC 接电位器,输入范围 0–3.3 V。每 500 ms 采样一次。
- 每次采集 16 个样本,排序后去掉最高 2 个和最低 2 个,对剩余样本求平均并换算毫伏。
- 低于 1000 mV 显示绿色,1000–2199 mV 显示黄色,2200 mV 及以上显示红色并拉高 GPIO21。
- Touch 启动时自动采集基线,使用相对变化量判断触摸,必须兼容不同导电片。
- 每次有效触摸切换 LIVE/HOLD。HOLD 状态冻结最后一次有效 ADC 结果。
- 按键短按重新校准 Touch;长按恢复默认阈值。
- 串口可读 ADC/Touch 原始值,修改两个电压阈值、采样周期和 Touch 灵敏度并保存。
建议评分点
| 项目 | 分值 | 验收 |
|---|---|---|
| ADC1 和输入安全 | 10 | GPIO1,输入不超过 3.3 V |
| 定时采样与 16 点去极值平均 | 20 | 波动明显小于单次采样 |
| 三档 RGB 与 GPIO 输出 | 15 | 跨越阈值时状态正确 |
| Touch 基线、自适应阈值和消抖 | 20 | 换导电片后重新校准可用 |
| LIVE/HOLD 状态机 | 10 | HOLD 后转动电位器,显示保持 |
| UART 参数与状态查询 | 15 | 越界参数被拒绝 |
| NVS 和异常默认值 | 10 | 断电保存;损坏时恢复默认 |
直接使用
Arduino 工程:arduino_pio/mock_02_touch_adc。主要修改 include/contest_user_config.h 和 src/task_logic.cpp。
TOUCH CAL
TOUCH READ
ADC READ
SET ADC_LOW 1000
SET ADC_HIGH 2200
ADC AUTO 500
SAVE
STATUS最可能的变题
- 电位器改成光敏、电阻式传感器或电池电压。
- 三档改成百分比、频率或 LED 亮度映射。
- Touch 改为短触/长触或双击识别。
- 要求 ADC 阈值附近增加迟滞,避免颜色频繁跳变。
现场修改指南:先判断要不要改
当前代码已经实现三档 ADC、迟滞和 LIVE/HOLD。现场阈值、采样周期和迟滞不同,优先用串口改参数,不要立即改源码。
题目一句话对应哪里
| 题目关键词 | 函数/变量 | 作用 |
|---|---|---|
| 开机默认迟滞 | beginTask() | user1为 0 时设为 50 mV |
| 短按重新校准 | shortPress() | 调用 calibrateTouch() |
| Touch 保持/恢复 | touchChanged() | 在 LIVE 与 HOLD 间切换 |
| 阈值和分档 | adcSample() | 使用低、高阈值和迟滞更新 level |
| 颜色/GPIO21 | tick() | 低绿、中黄、高红,高档拉高 GPIO21 |
| HOLD/HYST 命令 | command() | 解析题型专属参数 |
变量翻译
| 代码 | 含义 |
|---|---|
display_mv | 当前用于显示和判断的毫伏值;HOLD 后不再更新 |
level | 0 低档、1 中档、2 高档 |
adc_low_mv | 低档和中档的分界 |
adc_high_mv | 中档和高档的分界 |
user1 | 迟滞毫伏数,避免阈值附近反复跳档 |
mode | 0 LIVE,1 HOLD |
最安全:先用串口改参数
| 现场要求 | 命令 | 是否改代码 |
|---|---|---|
| 阈值改为 800/2500 mV | SET ADC_LOW 800SET ADC_HIGH 2500 | 不需要 |
| 迟滞改为 80 mV | HYST 80 | 不需要 |
| 每 200 ms 采样 | ADC AUTO 200 | 不需要 |
| Touch 更灵敏 | SET TOUCH_DELTA 10 | 不需要;数值越小越容易触发 |
| 保存以上参数 | SAVE | 不需要 |
输入安全:无论代码如何映射,GPIO1 电压都不能超过 3.3 V。测更高电压必须先使用电阻分压。
三种高概率变题:可直接替换
示例 A:改变低、中、高三档的颜色和高档输出
替换范围:完整替换 tick()。
void tick(contest::ContestApp &app, uint32_t) {
if (app.touchActive()) {
app.setRgb(45, 45, 45); // 正在触摸:白色
} else if (level == 0) {
app.setRgb(0, 0, 70); // 低档:蓝色
} else if (level == 1) {
app.setRgb(0, 65, 0); // 中档:绿色
} else {
app.setRgb(90, 0, 0); // 高档:红色
}
app.setDigitalOutput(level == 2); // 只有高档拉高 GPIO21
}只要求高档亮灯、不要求 RGB 随 Touch 变白时,可以删除最前面的 if (app.touchActive())分支并从 level开始判断。
示例 B:三级改四级,固定分界 800/1600/2400 mV
此示例保持 HOLD 功能,但改用三个固定分界。先保留文件顶部的 uint8_t level,再替换下面两个完整函数。
完整替换 adcSample():
void adcSample(contest::ContestApp &app, uint32_t millivolts) {
if (app.config().mode == 1) return; // HOLD 时保持旧结果
display_mv = millivolts;
if (millivolts < 800) level = 0;
else if (millivolts < 1600) level = 1;
else if (millivolts < 2400) level = 2;
else level = 3;
app.emit("EVENT ADC MV=%lu LEVEL=%u HOLD=0",
static_cast<unsigned long>(display_mv), level);
}完整替换 tick():
void tick(contest::ContestApp &app, uint32_t) {
if (level == 0) app.setRgb(0, 0, 50);
else if (level == 1) app.setRgb(0, 60, 0);
else if (level == 2) app.setRgb(70, 30, 0);
else app.setRgb(90, 0, 0);
app.setDigitalOutput(level == 3);
}注意:这个入门版本没有迟滞。题目明确要求迟滞时,应继续使用原三级算法,或者为三个分界分别写上升/下降阈值。
示例 C:Touch 只进入 HOLD,长按才恢复 LIVE
替换范围:完整替换 touchChanged();现有 longPress()已经会恢复 LIVE,无需再改。
void touchChanged(contest::ContestApp &app, bool active) {
if (!active) return;
app.setMode(1); // 只进入 HOLD,不再来回切换
app.emit("STATE HOLD=1");
}如果题目改成“Touch 期间保持,松开恢复”,则使用:
void touchChanged(contest::ContestApp &app, bool active) {
app.setMode(active ? 1 : 0);
app.emit("STATE HOLD=%u", app.config().mode);
}示例 D:高于 2800 mV 时每 500 ms 蜂鸣一次
1. 在文件顶部的 level变量后加入:
uint32_t last_alarm_ms = 0;2. 把 tick()的第二个参数从省略名称改为 now_ms,并在函数末尾加入节流判断:
void tick(contest::ContestApp &app, uint32_t now_ms) {
if (app.touchActive()) {
app.setRgb(45, 45, 45);
} else if (level == 0) {
app.setRgb(0, 55, 0);
} else if (level == 1) {
app.setRgb(75, 30, 0);
} else {
app.setRgb(80, 0, 0);
}
app.setDigitalOutput(level == 2);
if (display_mv >= 2800 &&
now_ms - last_alarm_ms >= 500) {
last_alarm_ms = now_ms;
app.startBeep(2200, 80);
}
}公共 startBeep()会自动遵守静音设置,因此这里不必再读取 muted。
改完后的最短验收
- 编译后输入
ADC READ,确认毫伏值随电位器变化。 - 输入
SET ADC_LOW 1000和SET ADC_HIGH 2200,缓慢跨越阈值,观察颜色和 GPIO21。 - 触摸后转动电位器,HOLD 时
DISPLAY_MV应保持;恢复 LIVE 后继续变化。 - 在阈值附近轻微转动,开启迟滞时颜色不应快速来回跳。
- 输入
STATUS核对LEVEL、HOLD和HYST_MV。
不要改:公共库里的 16 点采样和 Touch 消抖。除非任务书明确改变滤波算法,否则只改本页列出的题型函数。