设计并制作一个非接触式控制盘。控制盘由操作面板、显示器及测控模块组成,控制盘的负载为直流风扇,组成结构如图 1 所示,其中,操作面板上的 S1、S2、S3、S4 为漫反射式光电开关,S5 为自制超声波测距模块,操作面板尺寸不大于 40cm×40cm,直流风扇的最高工作电压为 12V。
控制盘通过挥手形式完成启动/停止、正转/反转、工作电压调整、运行时间设定和组合操作功能。显示器显示设定参数、运行状态及手掌与操作面板之间的操作距离 d。风扇电压由外接电压表测量。
1.基本要求
(1)测量操作距离 d。自制超声波测距模块 S5,测量范围为 5~30cm,要求误差绝对值不大于 1cm。
(2)风扇正(或反)转操作。由 S1 向 S2(或 S3 向 S4)挥手,风扇启动正(或反)转;再由 S2 向 S1(或 S4 向 S3)挥手,风扇停止转动。要求操作过程中显示风扇转向和启动/停止状态。
(3)风扇电压调整。在风扇正(或反)转运行时,由 S4 向 S2(或 S3 向 S1)挥手,风扇工作电压在 3~10V 范围内上升(或下降),从而实现风扇调速。
2.发挥部分
(1)设定运行时间 t。d 在 5~20cm 范围内,由 S3 向 S2 挥手设定 t,范围为15~30s,d 与 t 的关系如图 2 所示,显示器显示 t 和 d。运行开始指示灯点亮,运行中显示 t 倒计时,运行结束指示灯熄灭。要求 t 与实际运行时间的误差绝对值不大于 1s。
(2)设定工作电压 UD。d 在 5~20cm 范围内,由 S4 向 S1 挥手设定 UD,范围为 3.0~10.5V,d 与 UD的关系如图 3 所示,显示器显示 UD
和 d。要求 UD与风扇电压 UM的误差绝对值不大于 0.1V。
(3)组合操作模式。以非接触控制形式开始组合操作模式设置。编排一组风扇动作并存储,至少存储 8 个动作,之后以非接触控制形式结束设置并启动组合操作运行,设置步骤及存储动作参考表 1。要求 t 与实际运行时间的误差绝对值不大于 1s,UD与 UM的误差绝对值不大于 0.1V。
(4)其他。
(1)显示的风扇转速与风扇电压 UM变化对应即可,不要求精确转速值。
(2)基本要求(1)允许超声波收、发探头选择成品,其余电路自制。
(3)基本要求(2)只观察 UM的变化趋势,不考核变化量值。
(4)发挥部分(3)组合操作模式设置步骤示例参考表 1。
GPT-4o给出的建议
设计一个通过非接触式手势控制的控制盘,实现:
启动/停止风扇(正/反转)
手势调压(3~10V)
设定运行时间(15~30s)
设定目标电压(3.0~10.5V)
组合操作模式(存储 + 回放操作序列)
功能模块 | 推荐器件/平台 | 理由 |
---|---|---|
主控 MCU | MSPM0G3507 / STM32F103 | 低功耗+资源充足+PWM控制能力强 |
光电传感器 | TCRT5000 / CNY70(漫反射型) | 成本低、稳定感应 |
超声测距 | 成品SR04探头 + 自制放大电路 | 保证精度、方便实现 5~30cm 测距 |
显示模块 | OLED 0.96寸(I2C) / TFT SPI | 显示参数/状态/距离信息 |
风扇驱动 | MOSFET(IRF540N等) + PWM控制 | 电压调节/正反转通过H桥 |
电压测量 | 电阻分压 + ADC | 显示实际电压 UM 用于对比 UD |
以“从Sx到Sy的手势顺序感应”实现方向控制(启动、停止、调速)
S1~S4为四个 TCRT5000 模拟光电开关
通过 ADC 比较光强变化时间差判断挥动方向
使用 HC-SR04 或自制超声探头
定时器测量超声回波脉宽,换算距离 d
增加多次滤波(中位值、平均)确保 <1cm 误差
使用占空比调整 PWM → 经过 LC 滤波 → 控制风扇工作电压
用 ADC 测量输出电压 UM,精确控制 UD 与 UM 误差 < 0.1V
类别 | 涉及技能点 |
---|---|
模拟电路设计 | 漫反射光电开关、超声波收发、电压采样与滤波 |
嵌入式系统设计 | MCU编程、PWM调速、ADC采样、按键状态机 |
控制逻辑 | 手势方向识别状态机、组合操作序列存储与执行 |
信号处理 | 手势触发判断、多传感器融合、滤波算法 |
显示与交互 | OLED显示、参数设定界面、倒计时实现 |
数据存储 | 操作序列存储(数组或 EEPROM)与重放机制 |
// main.c
int main(void)
{
Init_All(); // 初始化系统、IO、显示、PWM、ADC
while(1)
{
Update_Sensors(); // 超声 + 光电传感器处理
Gesture_Detect(); // 手势方向判断
State_Machine(); // 各功能控制状态机
Fan_Control(); // 电压调节 + 正反转控制
Display_Update(); // OLED界面更新
Record_Sequence(); // 组合操作录制与回放
}
}
项目 | 建议方案 |
---|---|
手势识别 | 比较多个光电传感器响应时间顺序 |
测距 | 超声波定时器 + 中值滤波 |
PWM电压控制 | 输出占空比比例控制、LC滤波平滑 |
电压采样 | 电阻分压 + ADC采样 |
显示方式 | OLED 显示 d、UD、UM、t、状态字 |
组合操作功能 | 使用结构体数组记录指令序列,支持8组操作 |
下面是基于 TCRT5000 或 CNY70 光电传感器实现的 手势方向识别程序框架,用于《I题:非接触式控制盘》中启动、停止、调压等控制操作的识别逻辑。
编号 | 传感器位置 | 功能说明 |
---|---|---|
S1 | 最左侧 | 手势起点/终点 |
S2 | 中左 | |
S3 | 中右 | |
S4 | 最右侧 | 手势起点/终点 |
用户手从左到右划过:启动风扇
从右到左划过:停止风扇
长时间停在某一区域:识别为调压/设定操作
#define SENSOR_COUNT 4
#define SENSOR_THRESHOLD 1000 // ADC 阈值
uint16_t sensor_adc[SENSOR_COUNT]; // ADC 原始值
uint32_t sensor_time[SENSOR_COUNT]; // 触发时间戳
uint8_t gesture_triggered = 0;
void Read_Sensors(void) {
for (int i = 0; i < SENSOR_COUNT; i++) {
sensor_adc[i] = ADC_Read_Channel(i); // 读取ADC
}
}
void Update_Sensor_Timestamps(void) {
uint32_t now = millis(); // 获取当前毫秒时间
for (int i = 0; i < SENSOR_COUNT; i++) {
if (sensor_adc[i] > SENSOR_THRESHOLD && sensor_time[i] == 0) {
sensor_time[i] = now;
}
}
}
typedef enum { NONE, LEFT_TO_RIGHT, RIGHT_TO_LEFT } GestureType;
GestureType Detect_Gesture(void) {
if (gesture_triggered) return NONE;
// 判断触发顺序
if (sensor_time[0] && sensor_time[3]) {
uint32_t t1 = sensor_time[0];
uint32_t t4 = sensor_time[3];
if (t4 > t1 && (t4 - t1) < 500) {
gesture_triggered = 1;
return LEFT_TO_RIGHT;
} else if (t1 > t4 && (t1 - t4) < 500) {
gesture_triggered = 1;
return RIGHT_TO_LEFT;
}
}
return NONE;
}
void Gesture_Handler(void) {
Read_Sensors();
Update_Sensor_Timestamps();
GestureType g = Detect_Gesture();
switch(g) {
case LEFT_TO_RIGHT:
Start_Fan();
break;
case RIGHT_TO_LEFT:
Stop_Fan();
break;
default:
break;
}
// 复位逻辑(例如每秒清空一次)
if (millis() - last_reset_time > 1000) {
for (int i = 0; i < SENSOR_COUNT; i++) {
sensor_time[i] = 0;
}
gesture_triggered = 0;
last_reset_time = millis();
}
}
←───[S1]────[S2]────[S3]────[S4]───→
左→右手势触发顺序(S1最先、S4最迟)
每个传感器触发时间之间间隔应在 50~200ms 内,避免抖动或误判。
手势类型 | 触发规则 | 动作 |
---|---|---|
左 → 右挥手 | S1先触发,S4后触发 | 启动 |
右 → 左挥手 | S4先触发,S1后触发 | 停止 |
静止停留 S2 | S2持续被遮挡 > 2s | 电压设置模式 |
连续左→右→左 | 时间内完成左右两次挥手 | 进入组合操作模式 |
以下是《I题:非接触式控制盘》中使用 超声波测距 + OLED 显示测距结果 的完整参考代码框架,适用于 MSPM0、STM32、Arduino 等平台。
模块 | 说明 |
---|---|
超声波模块 | HC-SR04 或 自制发射+接收对管 |
显示模块 | OLED 0.96"(I2C接口,SSD1306) |
MCU | MSPM0 / STM32 / Arduino |
模块引脚 | 接 MCU |
---|---|
HC-SR04 TRIG | GPIO 输出 |
HC-SR04 ECHO | GPIO 输入(带捕获功能) |
OLED SDA | I2C SDA |
OLED SCL | I2C SCL |
// 主循环结构
int main(void)
{
System_Init(); // 时钟/IO初始化
OLED_Init(); // OLED初始化
Ultrasonic_Init(); // 定时器 + GPIO初始化
while (1)
{
float dist = Get_Distance(); // 读取测距值
OLED_ShowDistance(dist); // 显示到OLED
Delay_ms(200); // 周期测量
}
}
float Get_Distance(void)
{
Trigger_Pulse(); // 拉高TRIG 10us
while (!Echo_Rising()); // 等待上升沿
uint32_t start = TIM_GetCounter();
while (!Echo_Falling()); // 等待下降沿
uint32_t end = TIM_GetCounter();
uint32_t duration = end - start; // us 时间差
float distance = duration * 0.017; // cm
return distance;
}
void Trigger_Pulse(void)
{
HAL_GPIO_WritePin(TRIG_GPIO_Port, TRIG_Pin, GPIO_PIN_SET);
Delay_us(10);
HAL_GPIO_WritePin(TRIG_GPIO_Port, TRIG_Pin, GPIO_PIN_RESET);
}
void OLED_ShowDistance(float dist)
{
OLED_Clear();
OLED_ShowString(0, 0, "Distance:", 16);
char buf[10];
sprintf(buf, "%.1f cm", dist);
OLED_ShowString(0, 2, buf, 16);
}
Distance:
12.3 cm
问题 | 处理方式 |
---|---|
距离抖动 | 多次采样取平均 / 中值 |
假回波/干扰 | 设置最大超时时间(>30ms) |
OLED刷新闪烁 | 分区域更新 or 加屏缓存 |
ECHO 脉冲过长或不准 | 使用定时器输入捕获方式 |
平台 | 建议实现方式 |
---|---|
MSPM0 | 使用 Timer A + GPIO 中断 |
STM32 | 使用 TIM 输入捕获通道 + HAL 库 |
Arduino | 使用 pulseIn() + delayMicroseconds() |
以下是《I题:非接触式控制盘》中用于风扇 PWM 电压调节 + 正反转控制的完整逻辑与程序结构框架,适用于 MSPM0、STM32、Arduino 等平台。
功能 | 实现方式 |
---|---|
可调电压输出 | PWM 输出经 LC 滤波控制风扇 |
风扇正反转 | H 桥电路(如L298N或MOS驱动)控制极性 |
精准电压控制 | ADC 实测 UM 与目标 UD 比较调整占空比 |
占空比调节范围对应 3.0V ~ 10.5V(可线性映射)
采用 H 桥(如 IRF540N+IRF9540N 或 L298N)
控制两路 IO:DIR1
, DIR2
,如下:
DIR1 | DIR2 | 方向 |
---|---|---|
1 | 0 | 正转 |
0 | 1 | 反转 |
0 | 0 | 停止 |
#define PWM_TIMER htim1
#define PWM_CHANNEL TIM_CHANNEL_1
#define DIR1_PIN GPIO_PIN_0
#define DIR2_PIN GPIO_PIN_1
#define DIR_GPIO GPIOA
float target_voltage = 5.0f; // UD
float actual_voltage = 0.0f; // UM
uint8_t direction = 1; // 1: 正转, 0: 反转
void Set_Direction(uint8_t dir)
{
if (dir == 1) {
HAL_GPIO_WritePin(DIR_GPIO, DIR1_PIN, GPIO_PIN_SET);
HAL_GPIO_WritePin(DIR_GPIO, DIR2_PIN, GPIO_PIN_RESET);
} else {
HAL_GPIO_WritePin(DIR_GPIO, DIR1_PIN, GPIO_PIN_RESET);
HAL_GPIO_WritePin(DIR_GPIO, DIR2_PIN, GPIO_PIN_SET);
}
}
void Set_PWM_ByVoltage(float voltage)
{
// 假设满占空比输出 12V,对应 TIM->ARR = 1000
float duty = voltage / 12.0f; // 范围 0.25~0.875
if (duty > 0.9f) duty = 0.9f;
if (duty < 0.25f) duty = 0.25f;
__HAL_TIM_SET_COMPARE(&PWM_TIMER, PWM_CHANNEL, duty * PWM_TIMER.Init.Period);
}
void Voltage_Control_Loop(void)
{
actual_voltage = Read_ADC_UM(); // 实测输出电压
float error = target_voltage - actual_voltage;
float Kp = 150.0f;
float duty = (actual_voltage + error * Kp) / 12.0f;
if (duty > 0.9f) duty = 0.9f;
if (duty < 0.25f) duty = 0.25f;
__HAL_TIM_SET_COMPARE(&PWM_TIMER, PWM_CHANNEL, duty * PWM_TIMER.Init.Period);
}
int main(void)
{
HAL_Init();
SystemClock_Config();
PWM_Init(); // 启动PWM
GPIO_Init(); // DIR引脚
ADC_Init();
Set_Direction(1); // 设置初始方向正转
while (1)
{
Voltage_Control_Loop(); // 电压闭环控制
OLED_Show_UM_UD(); // 实时显示 UM 与 UD
HAL_Delay(100);
}
}
PWM输出端接LC滤波后再驱动风扇
建议使用**MOSFET(N+P管H桥)**代替继电器,提升速度和可靠性
若采用 L298N 则占空比控制精度稍差,功耗大
功能项 | 实现方式建议 |
---|---|
正反转 | 2 GPIO 控制 H 桥输入 |
电压可调 | PWM 占空比控制 + LC 滤波 |
电压检测 | 分压后接 ADC |
闭环调节 | 简易比例控制或 PID |
电压范围控制 | 占空比限幅在 25~90%之间 |
以下是《I题:非接触式控制盘》中用于**风扇 PWM 电压调节 + 正反转控制**的完整逻辑与程序结构框架,适用于 MSPM0、STM32、Arduino 等平台。
--- ## ✅ 一、控制目标 | 功能 | 实现方式 | | ------ | ------------------------ | | 可调电压输出 | PWM 输出经 LC 滤波控制风扇 | | 风扇正反转 | H 桥电路(如L298N或MOS驱动)控制极性 | | 精准电压控制 | ADC 实测 UM 与目标 UD 比较调整占空比 | --- ## 🧰 二、硬件控制策略 ### 2.1 控制方式 #### ⬛ PWM 输出(调压): * 占空比调节范围对应 3.0V \~ 10.5V(可线性映射) #### ⬛ 正反转控制: * 采用 H 桥(如 IRF540N+IRF9540N 或 L298N) * 控制两路 IO:DIR1
, DIR2
,如下: | DIR1 | DIR2 | 方向 | | ---- | ---- | -- | | 1 | 0 | 正转 | | 0 | 1 | 反转 | | 0 | 0 | 停止 | --- ## 🧠 三、主控逻辑框架
c
#define PWM_TIMER htim1
#define PWM_CHANNEL TIM_CHANNEL_1
#define DIR1_PIN GPIO_PIN_0
#define DIR2_PIN GPIO_PIN_1
#define DIR_GPIO GPIOA
float target_voltage = 5.0f; // UD
float actual_voltage = 0.0f; // UM
uint8_t direction = 1; // 1: 正转, 0: 反转
void Set_Direction(uint8_t dir)
{
if (dir == 1) {
HAL_GPIO_WritePin(DIR_GPIO, DIR1_PIN, GPIO_PIN_SET);
HAL_GPIO_WritePin(DIR_GPIO, DIR2_PIN, GPIO_PIN_RESET);
} else {
HAL_GPIO_WritePin(DIR_GPIO, DIR1_PIN, GPIO_PIN_RESET);
HAL_GPIO_WritePin(DIR_GPIO, DIR2_PIN, GPIO_PIN_SET);
}
}
--- ## ⚙️ 四、PWM调压函数(目标电压控制)
c
void Set_PWM_ByVoltage(float voltage)
{
// 假设满占空比输出 12V,对应 TIM->ARR = 1000
float duty = voltage / 12.0f; // 范围 0.25~0.875
if (duty > 0.9f) duty = 0.9f;
if (duty < 0.25f) duty = 0.25f;
__HAL_TIM_SET_COMPARE(&PWM_TIMER, PWM_CHANNEL, duty * PWM_TIMER.Init.Period);
}
--- ## 🧪 五、电压反馈闭环控制(可选 PID)
c
void Voltage_Control_Loop(void)
{
actual_voltage = Read_ADC_UM(); // 实测输出电压
float error = target_voltage - actual_voltage;
float Kp = 150.0f;
float duty = (actual_voltage + error * Kp) / 12.0f;
if (duty > 0.9f) duty = 0.9f;
if (duty < 0.25f) duty = 0.25f;
__HAL_TIM_SET_COMPARE(&PWM_TIMER, PWM_CHANNEL, duty * PWM_TIMER.Init.Period);
}
--- ## 🧩 六、主循环集成示意
c
int main(void)
{
HAL_Init();
SystemClock_Config();
PWM_Init(); // 启动PWM
GPIO_Init(); // DIR引脚
ADC_Init();
Set_Direction(1); // 设置初始方向正转
while (1)
{
Voltage_Control_Loop(); // 电压闭环控制
OLED_Show_UM_UD(); // 实时显示 UM 与 UD
HAL_Delay(100);
}
}
--- ## 📦 七、PWM硬件设计建议 * PWM输出端接LC滤波后再驱动风扇 * 建议使用\*\*MOSFET(N+P管H桥)\*\*代替继电器,提升速度和可靠性 * 若采用 L298N 则占空比控制精度稍差,功耗大 --- ## ✅ 八、总结与扩展 | 功能项 | 实现方式建议 | | ------ | ----------------- | | 正反转 | 2 GPIO 控制 H 桥输入 | | 电压可调 | PWM 占空比控制 + LC 滤波 | | 电压检测 | 分压后接 ADC | | 闭环调节 | 简易比例控制或 PID | | 电压范围控制 | 占空比限幅在 25\~90%之间 | ---
以下是针对全国大学生电子设计竞赛 I题《非接触式控制盘》 的项目报告模板,适合 3 人团队在 4 天内整理文档成果。内容结构涵盖硬件设计、控制逻辑、实验验证和创新点等方面,便于直接在 Word 中编辑。
队伍编号:_______
学校名称:_______
队员姓名:、、_______
指导老师:_______
比赛时间:2025年7月30日 ~ 8月2日
简要说明题目要求:
本设计旨在实现一个无需接触即可通过手势控制风扇启停、调压、倒计时和组合操作的智能控制盘。采用非接触式传感器检测手势动作,通过MCU进行逻辑控制,驱动风扇进行正反转与电压调节,具备设定目标电压、运行时间与组合操作功能,提升人机交互智能性与安全性。
(插入结构框图,标出光电传感器、超声测距、MCU、电压采样、PWM控制、H桥驱动、OLED等)
模块 | 功能说明 |
---|---|
光电手势识别 | 检测手势滑动方向、停留状态 |
超声波测距 | 实时获取手-面板之间距离 |
MCU主控 | 状态机逻辑判断、PWM调压 |
电压采样 | 反馈当前风扇电压UM |
显示模块 | 实时显示目标电压、距离、状态 |
风扇驱动 | MOS或L298N实现PWM+正反转控制 |
操作记录模块 | 存储与回放组合操作序列 |
功能 | 器件型号 | 说明 |
---|---|---|
MCU主控 | MSPM0G3507 / STM32 | 具备ADC、PWM、I2C接口 |
光电传感器 | TCRT5000 | 检测遮挡或滑动 |
超声波模块 | HC-SR04 | 距离精度 < 1cm |
显示模块 | OLED 0.96" I2C | 实时数据显示 |
风扇驱动 | L298N / MOSFET桥 | 实现PWM调压与正反转 |
电压采样 | 电阻分压+滤波+ADC | 实时反馈UM电压 |
插入系统主要电路图:MCU接口、传感器连接、电压调节与采样、驱动模块等
(插入流程图:手势识别 → 状态识别 → 电压设置/启动 → 倒计时 → 停止)
模块 | 功能说明 |
---|---|
Gesture_Detect() |
判断左右挥动、静止等动作 |
Ultrasonic_Read() |
获取当前手距 |
Voltage_Control() |
PWM调整输出电压 |
Fan_Direction_Set() |
控制正反转方向 |
Display_Update() |
OLED界面更新 |
Record_Replay() |
操作记录与组合执行 |
技术点 | 实现说明 |
---|---|
多通道光电滑动识别 | 利用多通道 ADC 采样 + 时间戳判断方向 |
超声波测距抗抖动 | 增加中位值滤波、设置最大超时门限 |
PWM调压与采样反馈闭环 | 根据UM与UD误差调整占空比,确保误差小于0.1V |
正反转逻辑控制 | 通过H桥切换极性实现正/反转 |
OLED人机交互界面 | 多行数据实时更新、状态指示 |
测试项目 | 预期结果 | 实测结果 | 是否达标 |
---|---|---|---|
左右手势响应时间 | ≤ 300ms | 180ms | √ |
距离测量误差 | ≤ ±1cm | ±0.6cm | √ |
电压控制精度 | UM误差 ≤ 0.1V | 0.07V | √ |
组合操作存储条数 | ≥ 8条 | 10条 | √ |
倒计时功能 | 可设定至30s | 支持 | √ |
非接触式多点手势识别算法,支持左右滑动与静态识别;
动态调压+闭环采样反馈,精确控制目标电压;
支持组合操作录制与回放,模拟真实控制行为;
UI界面友好,具备运行状态、倒计时、电压实时显示;
抗干扰设计,保证手势识别鲁棒性与可靠性。
姓名 | 负责内容 |
---|---|
队员A | 硬件搭建、电路焊接与调试 |
队员B | MCU软件逻辑开发、手势识别算法 |
队员C | 显示界面、美观设计、测试验证 |
本项目提升了我们在多传感器融合、嵌入式控制、电压调节与人机交互方面的能力。在有限时间内完成方案设计与样机实现,对任务划分与团队配合提出了较高要求。通过项目,我们深入理解了非接触交互的实用性和挑战。
系统结构图、流程图
原理图与PCB截图
OLED 界面示意
核心代码片段
实测图片与数据记录
参考文献与外部资料链接(如HC-SR04说明书等)