第10周个人作业:手势控制迷你风扇与LED 
1. 项目介绍 
本周个人项目的主要目标是:向你设计的微控制器板添加输出设备并编程使其工作。基于我之前的手势传感器集成和最终项目创意,我决定设计一个手势控制系统,将输入设备(APDS-9960手势传感器)与输出设备(Grove迷你风扇和板载LED)相结合,创建一个互动电子项目。在我的最终项目,迷你风扇的电机将会用来驱动灯罩旋转,所以这次的实验对我的最终项目有重要的技术验证价值。
项目具体目标包括:
- 设计并实现手势控制风扇和LED的电路连接
- 编写程序实现基于不同手势的控制功能
- 测试手势识别的可靠性和响应速度
- 探索与多个输出设备交互的方法
2. 材料与设备 
硬件组件 
- XIAO ESP32C3开发板(自制)
- APDS-9960手势传感器模块(XLOT品牌)
- Grove迷你风扇模块
- 连接线/杜邦线
- USB数据线
- 电源适配器(5V/2A)
软件工具 
- Arduino IDE
- XLOT_APDS9960AD库(用于手势传感器)
3. 系统设计 
3.1 接口挑战与解决方案 
在为自制的XIAO ESP32C3扩展板添加手势传感器和风扇模块时,我面临了一个关键挑战:我设计的扩展板没有直接引出I2C接口(SDA/SCL)引脚。
我的 XIAO 开发板的 8 针引脚如下图所示。

我设计的 XIAO 开发板的引脚编号标注
XIAO ESP32C3扩展板上8针引脚连接器(J1)的功能说明:
| 引脚号 | 标识 | 功能 | GPIO编号 | 
|---|---|---|---|
| 1 | GND | 接地连接 | - | 
| 2 | 3.3V | 3.3V电源输出 | - | 
| 3 | RX/D7 | 串口接收引脚 | GPIO20 | 
| 4 | TX/D6 | 串口发送引脚 | GPIO21 | 
| 5 | SCK/D8 | SPI时钟信号 | GPIO8* | 
| 6 | MISO/D9 | SPI主机输入从机输出 | GPIO9* | 
| 7 | MOSI/D10 | SPI主机输出从机输入 | GPIO10 | 
| 8 | RST | 复位信号或其他功能扩展 | - | 
_注:带_标记的是Strapping引脚,用于ESP32C3启动模式选择。
针对这一限制,我采用了ESP32C3的软件I2C功能,通过重新映射引脚来解决问题:
- 使用RX/D7(GPIO20)作为SDA数据线
- 使用TX/D6(GPIO21)作为SCL时钟线
- 使用MOSI/D10(GPIO10)作为风扇控制引脚
此外,开发板上已有6个LED(D0-D5),我可以直接使用这些LED作为视觉反馈输出设备。
3.2 功能设计 
手势控制系统将通过APDS-9960手势传感器识别四种基本手势,并控制风扇和LED:
| 手势方向 | 控制功能 | 
|---|---|
| 右划 | 开启风扇 | 
| 左划 | 关闭风扇 | 
| 上划 | 增加点亮的LED数量 | 
| 下划 | 减少点亮的LED数量 | 
这种设计使操作更加直观:
- 左右手势用于控制风扇的启停
- 上下手势用于控制LED的亮度/数量,象征性地表示风扇速度等级
3.3 硬件连接设计 
电源和地线共享解决方案 
由于两个设备都需要连接到电源和地线,而J1接口只有一组3.3V和GND引脚,因此我采用了Y型分线连接的方式解决此问题:
- 制作Y型分线连接器: - 使用杜邦线制作两个简易的Y型分线器
- 一个用于3.3V供电(引脚2),另一个用于GND(引脚1)
- 每个Y型分线器将一个引脚拓展为两个接口
 
- 替代方案: - 也可以直接使用XIAO ESP32C3板上的额外GND和3.3V引脚
- 或使用面包板进行电源分配
 
修改后的设备连接方案 
APDS-9960手势传感器连接 
| APDS-9960引脚 | 连接到扩展板引脚 | XIAO ESP32C3引脚 | 功能 | 
|---|---|---|---|
| VCC(红线) | J1-2 (3.3V)的Y型分线 | 3.3V | 电源正极 | 
| GND(黑线) | J1-1 (GND)的Y型分线 | GND | 电源地线 | 
| SDA(黄线) | J1-3 (RX/D7) | GPIO20 | I2C数据线(软件实现) | 
| SCL(绿线) | J1-4 (TX/D6) | GPIO21 | I2C时钟线(软件实现) | 
Grove迷你风扇连接 
| Grove迷你风扇引脚 | 连接到扩展板引脚 | XIAO ESP32C3引脚 | 功能 | 
|---|---|---|---|
| 信号线 | J1-7 (MOSI/D10) | GPIO10 | 控制信号 | 
| VCC | J1-2 (3.3V)的Y型分线 | 3.3V | 电源正极 | 
| GND | J1-1 (GND)的Y型分线 | GND | 电源地线 | 
LED连接 
开发板上已有6个LED(D0-D5),这些LED直接通过板载电路连接到ESP32C3的对应GPIO引脚,无需额外连接。
3.4 电路连接 
系统硬件连接示意图,包括手势传感器、风扇控制和LED指示。

使用Y型分线器实现两个设备共享电源和地线的连接示意图
4. 程序设计 
4.1 程序结构设计 
程序主要分为以下几个部分:
- 初始化:设置串口通信、I2C通信、LED引脚、风扇引脚、手势传感器等。
- 主循环: - 读取手势传感器数据
- 根据手势更新风扇状态和LED数量
- 控制风扇和LED
 
4.2 核心代码实现 
#include <Wire.h>
#include "XLOT_APDS9960AD.h"
// 引脚重定义 - 适应自制扩展板
#define SDA_PIN 20      // RX/D7 (GPIO20)
#define SCL_PIN 21      // TX/D6 (GPIO21)
#define FAN_PIN 10      // MOSI/D10 (GPIO10)
// LED引脚定义
const int LED_PINS[] = {D5, D4, D3, D2, D1, D0};
const int LED_COUNT = 6;
// 手势传感器
XLOT_APDS9960AD apds;
// 风扇控制变量
bool fanState = false;         // 风扇状态(开/关)
unsigned long lastGestureTime = 0;  // 最后手势时间戳
const int gestureDelay = 500;  // 手势识别间隔(毫秒)
// LED控制变量
int ledCount = 0;  // 点亮的LED数量(0-6)
void setup() {
  Serial.begin(115200);
  delay(3000);  // 增加延迟,确保有足够时间上传新代码
  Serial.println("\n系统启动...");
  
  // 使用重定义的引脚初始化I2C
  Wire.begin(SDA_PIN, SCL_PIN);
  
  // 初始化所有LED引脚
  for(int i = 0; i < LED_COUNT; i++) {
    pinMode(LED_PINS[i], OUTPUT);
    digitalWrite(LED_PINS[i], LOW);  // 初始状态全部关闭
  }
  
  // 初始化风扇引脚
  pinMode(FAN_PIN, OUTPUT);
  digitalWrite(FAN_PIN, LOW);  // 初始状态关闭
  
  if(!apds.begin()){
    Serial.println("手势传感器初始化失败! 请检查接线。");
    // 错误指示 - 闪烁第一个LED
    while(1) {
      digitalWrite(LED_PINS[0], HIGH);
      delay(100);
      digitalWrite(LED_PINS[0], LOW);
      delay(100);
    }
  } else {
    Serial.println("手势传感器初始化成功!");
    apds.enableProximity(true);
    apds.enableGesture(true);
    apds.setProxGain(APDS9960_PGAIN_8X);
    apds.setGestureGain(APDS9960_PGAIN_8X);
    apds.setGestureGain(APDS9960_AGAIN_64X);
    apds.setGestureGain(APDS9960_GGAIN_8);
  
    // 成功指示 - 所有LED依次亮起再熄灭
    for(int i = 0; i < LED_COUNT; i++) {
      digitalWrite(LED_PINS[i], HIGH);
      delay(200);
    }
    delay(500);
    for(int i = 0; i < LED_COUNT; i++) {
      digitalWrite(LED_PINS[i], LOW);
      delay(200);
    }
  }
  
  Serial.println("系统初始化完成,等待手势控制...");
}
// 更新LED显示
void updateLEDs() {
  for(int i = 0; i < LED_COUNT; i++) {
    // 如果i小于ledCount,点亮LED,否则熄灭
    digitalWrite(LED_PINS[i], (i < ledCount) ? HIGH : LOW);
  }
}
void loop() {
  // 读取手势
  uint8_t gesture = apds.readGesture();
  
  // 处理手势(添加延迟以防止过快响应)
  if(gesture != 0 && millis() - lastGestureTime > gestureDelay) {
    lastGestureTime = millis();
  
    switch(gesture) {
      case APDS9960_RIGHT:
        // 右划 - 开启风扇
        if(!fanState) {
          fanState = true;
          digitalWrite(FAN_PIN, HIGH);
          Serial.println("风扇开启");
        }
        break;
      
      case APDS9960_LEFT:
        // 左划 - 关闭风扇
        if(fanState) {
          fanState = false;
          digitalWrite(FAN_PIN, LOW);
          Serial.println("风扇关闭");
        }
        break;
      
      case APDS9960_UP:
        // 上划 - 增加LED亮灯数量
        if(ledCount < LED_COUNT) {
          ledCount++;
          updateLEDs();
          Serial.print("LED亮灯数量: ");
          Serial.println(ledCount);
        }
        break;
      
      case APDS9960_DOWN:
        // 下划 - 减少LED亮灯数量
        if(ledCount > 0) {
          ledCount--;
          updateLEDs();
          Serial.print("LED亮灯数量: ");
          Serial.println(ledCount);
        }
        break;
    }
  }
}程序运行时会在串口监视器给出反馈,如下图所示。

程序运行时会在串口监视器给出反馈
4.3 程序功能说明 
- 引脚重定义和初始化: - 使用RX/D7(GPIO20)和TX/D6(GPIO21)作为软件I2C的SDA和SCL引脚
- 使用MOSI/D10(GPIO10)作为风扇控制引脚
- 定义并初始化6个板载LED(D0-D5)
- 所有设备初始状态为关闭
 
- 手势识别与处理: - 右划手势:开启风扇
- 左划手势:关闭风扇
- 上划手势:增加点亮的LED数量
- 下划手势:减少点亮的LED数量
 
- LED控制功能: - updateLEDs()函数控制LED的按序点亮/熄灭
- LED亮起数量(6-0)作为系统状态的视觉反馈
 
- 防抖处理: - 添加500ms的手势识别间隔,防止意外触发或重复识别
 
5. 硬件实现 
5.1 实物连接 
我按照设计方案,使用杜邦线将手势传感器和风扇模块连接到XIAO扩展板上,并用胶带固定在一个手机支架上,方便操作和展示效果,如下图所示。

实际的硬件连接,将手势传感器连接到RX/TX引脚,将风扇连接到MOSI引脚
连接过程中遇到的主要挑战是避免引脚间的短路和确保连接稳定。使用不同颜色的杜邦线有助于区分各个连接,提高操作可靠性。
5.2 组件布局 
为获得最佳的手势识别效果和风扇送风效果,组件布局做了以下考虑:
- 手势传感器放置: - 使用手机支架支撑扩展板和手势传感器,并保持传感器朝上
- 传感器表面向上,便于从上方进行手势操作
- 保持传感器前方约15cm无遮挡
 
- 风扇位置: - 风扇置于传感器下方约10cm处
- 确保风扇气流不会干扰手势识别
- 固定稳固,防止运转时晃动
 
- 连接线管理: - 使用胶带固定连接线,避免松动
- 连接线尽量短而直接,减少软件I2C的干扰问题
 
最终组件布局,优化了手势操作空间和设备放置
6. 系统测试与演示 
6.1 手势响应测试 
我测试了四种手势的识别和系统响应情况:
| 手势方向 | 控制功能 | 识别成功率 | 备注 | 
|---|---|---|---|
| 右划 | 开启风扇 | ~92% | 识别稳定 | 
| 左划 | 关闭风扇 | ~90% | 识别较稳定 | 
| 上划 | 增加LED亮灯数量 | ~85% | 偶有误判为下划 | 
| 下划 | 减少LED亮灯数量 | ~85% | 偶有误判为上划 | 
测试结果表明,左右手势识别率略高于上下手势,这与手势传感器的布局和光线反射特性相关。添加的500ms手势识别间隔有效防止了意外触发。
6.2 LED序列亮灯效果 
LED序列亮灯展示了良好的视觉反馈效果:
- 可以通过上下手势精确控制0-6个LED的点亮数量
- LED按顺序点亮/熄灭,提供直观的状态指示
- 系统启动时的LED初始化动画提供了视觉确认
6.3 风扇控制响应 
风扇控制表现出以下特性:
- 右划手势可以稳定开启风扇
- 左划手势可以稳定关闭风扇
- 风扇响应迅速,基本无延迟
- 直接使用高电平/低电平控制,操作简单可靠
6.4 系统演示视频 
视频展示了完整的系统功能,包括:
- 使用右划手势开启风扇
- 使用左划手势关闭风扇
- 使用上划手势增加LED亮灯数量
- 使用下划手势减少LED亮灯数量
7. 问题与解决方案 
7.1 遇到的问题 
- 引脚复用挑战: - 问题:自制扩展板未引出专用I2C引脚
- 解决方案:使用ESP32C3的软件I2C功能,将RX/TX复用为SDA/SCL
- 后果:导致使用这些引脚时无法同时使用串口通信功能,但可以上传完程序后使用
 
- PWM与模拟输出兼容性: - 问题:ESP32C3的 ledcSetup/ledcWrite函数在编译时报错
- 解决方案:改用标准 digitalWrite函数进行数字控制
- 影响:只能实现开关控制,无法进行速度调节,但符合我们简化的控制需求
 
- 问题:ESP32C3的 
- 手势识别不稳定: - 问题:初始测试中,上/下手势经常被误识别
- 原因:环境光干扰和手势角度不一致
- 解决方案:增加简易遮光罩并添加手势识别延迟(500ms)
 
- 电源电压挑战: - 问题:手势传感器推荐使用5V,但扩展板只提供3.3V
- 解决方案:将传感器直接连接到3.3V,尽管可能减小检测距离
- 测试结果:在3.3V下仍能正常工作,检测距离约为标称值的70%
 
7.2 改进方向 
- 硬件设计优化: - 在下一版扩展板中引出专用I2C引脚
- 增加5V输出选项,提高传感器兼容性
- 考虑添加电机驱动电路,支持精确的PWM控制
 
- 手势识别增强: - 优化手势识别算法,减少误识别
- 添加更多手势组合,实现更丰富功能
- 增加接近检测功能,自动开启/关闭
 
- 用户界面优化: - 设计更丰富的LED显示模式,如闪烁、流水灯效果
- 添加声音反馈,提高交互体验
- 开发双手协作手势,增加控制维度
 
8. 结论与反思 
8.1 项目成果 
本项目成功克服了扩展板设计限制,实现了手势控制风扇和LED系统,完成了以下目标:
- 通过软件I2C解决了连接难题,实现了APDS-9960手势传感器与XIAO的通信
- 成功控制Grove迷你风扇,实现了简单的开/关控制
- 实现了板载LED的序列点亮控制,提供视觉反馈
- 设计了直观的手势交互系统,让控制更自然
项目证明了ESP32C3强大的I/O复用能力,展示了如何在现有硬件限制下实现创新功能。
8.2 学习收获 
- 软件I2C的实现与应用: - 学习了ESP32C3的引脚映射技术
- 了解了通信时序和电气特性对信号质量的影响
- 掌握了处理非标准硬件配置的方法
 
- 多设备控制技能: - 学习了控制风扇等执行器的基本方法
- 掌握了LED序列控制技术
- 理解了人机交互中视觉反馈的重要性
 
- 系统集成能力: - 成功集成输入设备(手势传感器)和多个输出设备(风扇和LED)
- 构建完整的交互系统
- 解决设备间通信和协同工作问题
 
- 问题解决与创新思维: - 在硬件限制下找到软件解决方案
- 通过实验发现和解决实际操作中的问题
- 学会利用现有资源实现创新功能
 
8.3 与最终项目的关联 
本项目是我最终项目"智幻走马灯"的重要技术验证,特别是:
- 验证了APDS-9960手势传感器在3.3V下的可靠性和适用性
- 测试了ESP32C3的软件I2C功能和GPIO控制能力
- 探索了手势交互系统的设计方法,为最终项目奠定了交互基础
- 验证了使用ESP32C3控制电机的可行性,为灯罩旋转机构提供参考
这些技术和经验将直接用于最终项目中灯带控制和交互设计,是项目成功的关键基础。通过本次实验,我更加确信在现有硬件条件下,能够实现理想的"智幻走马灯"交互控制方案。
 Lei Feng Fab Academy 2025
Lei Feng Fab Academy 2025