Arduino中区分单击与双击:嘴部光敏开关误触优化问询
解决思路与代码实现
核心调整点
- 区分双传感器:给两个VCNL4010分配不同I2C地址(通过ADDR引脚接GND/VCC实现),单独初始化、读取数据
- 分离单击/双击逻辑:为每个传感器维护独立状态变量,一个仅响应单击(需等待超时确认无后续点击),另一个仅响应双击
- 隔离误触影响:两个传感器的状态与触发逻辑完全独立,互不干扰
具体实现代码
#include <Wire.h> #include "Adafruit_VCNL4010.h" // 初始化两个传感器,对应不同I2C地址(ADDR引脚一个接GND,一个接VCC) Adafruit_VCNL4010 vcnl_single; // 仅识别单击的传感器 Adafruit_VCNL4010 vcnl_double; // 仅识别双击的传感器 const int ledPin_single = 13; // 单击触发LED const int ledPin_double = 12; // 双击触发LED const int triggerPin_single = 8; // 单击触发输出引脚 const int triggerPin_double = 9; // 双击触发输出引脚 // 单击传感器状态变量 int single_firstClick = 0; int single_unClick = 0; unsigned long single_lastTime = 0; bool single_triggered = false; // 双击传感器状态变量 int double_firstClick = 0; int double_unClick = 0; int double_secondClick = 0; unsigned long double_lastTime = 0; void setup() { pinMode(ledPin_single, OUTPUT); pinMode(ledPin_double, OUTPUT); pinMode(triggerPin_single, OUTPUT); pinMode(triggerPin_double, OUTPUT); // 初始化双传感器,对应地址0x13(ADDR接GND)和0x14(ADDR接VCC) if (!vcnl_single.begin(0x13) || !vcnl_double.begin(0x14)) { while (1); // 初始化失败则死循环 } } void loop() { // -------------------------- 单击传感器逻辑 -------------------------- // 检测第一次按下 if (single_firstClick == 0 && vcnl_single.readProximity() > 60500) { single_firstClick = 1; single_lastTime = millis(); single_triggered = false; } // 检测释放 else if (single_firstClick == 1 && vcnl_single.readProximity() < 60500) { single_unClick = 1; } // 超时500ms无二次点击,确认单击并触发动作 if (single_unClick == 1 && millis() - single_lastTime > 500) { if (!single_triggered) { digitalWrite(ledPin_single, HIGH); analogWrite(triggerPin_single, 250); single_triggered = true; // 标记已触发,避免重复执行 } } // 超时1秒后重置状态 if (millis() - single_lastTime > 1000) { single_firstClick = 0; single_unClick = 0; single_triggered = false; digitalWrite(ledPin_single, LOW); analogWrite(triggerPin_single, 0); } // -------------------------- 双击传感器逻辑 -------------------------- // 检测第一次按下 if (double_firstClick == 0 && vcnl_double.readProximity() > 60500) { double_firstClick = 1; double_lastTime = millis(); } // 检测释放 else if (double_firstClick == 1 && vcnl_double.readProximity() < 60500) { double_unClick = 1; } // 500ms内检测到二次按下,判定双击并触发动作 if (double_unClick == 1 && vcnl_double.readProximity() > 60500 && millis() - double_lastTime < 500) { double_secondClick = 1; digitalWrite(ledPin_double, HIGH); analogWrite(triggerPin_double, 250); } // 超时500ms后重置状态 if (millis() - double_lastTime > 500) { double_firstClick = 0; double_unClick = 0; double_secondClick = 0; digitalWrite(ledPin_double, LOW); analogWrite(triggerPin_double, 0); } }
关键逻辑说明
- 单击传感器:必须等待500ms超时后才触发动作,确保这段时间内没有二次点击(避免误判为双击),用
single_triggered标记防止重复触发 - 双击传感器:仅在500ms内检测到「按下-释放-按下」序列才触发,超时未检测到二次点击则直接重置状态,不触发任何动作
- 硬件要求:两个VCNL4010的ADDR引脚需分别接GND和VCC,确保I2C地址不同,避免通信冲突
内容的提问来源于stack exchange,提问作者user2449986
相关产品推荐
相关产品推荐

