编程虫2号小车的触摸按键功能主要通过电容式触摸传感器实现,能够检测人体接触或接近时的电容变化。以下是触摸按键的具体实现方式及编程要点。
硬件原理
电容式触摸按键基于检测电极电容变化的工作原理。当手指或金属接近或触摸感应电极时,电极与地之间的电容会增大,传感器通过检测这种变化来判定触摸动作。编程虫2号通常使用专用触摸芯片(如TTP223)或MCU的电容检测模块实现。
硬件连接通常包括:
- 触摸传感器信号引脚连接到MCU的GPIO(支持中断或ADC功能)
- 电源(3.3V/5V)与接地
- 部分模块需要外部电容调节灵敏度
软件实现方法
1. 初始化触摸引脚 配置GPIO为输入模式,若使用中断方式需启用上升沿/下降沿触发:
pinMode(TOUCH_PIN, INPUT);
attachInterrupt(digitalPinToInterrupt(TOUCH_PIN), touchISR, CHANGE);
2. 中断服务函数处理 检测到触摸信号变化时进入中断处理逻辑:
void touchISR() {
int state = digitalRead(TOUCH_PIN);
if(state == HIGH) {
// 触摸按下动作
} else {
// 触摸释放动作
}
}
3. 消抖处理 通过延时过滤信号抖动:
if(digitalRead(TOUCH_PIN) == HIGH) {
delay(50);
if(digitalRead(TOUCH_PIN) == HIGH) {
// 确认有效触摸
}
}
应用示例
控制小车启停 触摸按键按下时启动电机,再次触摸停止:
bool isRunning = false;
void loop() {
if(checkTouch()) {
isRunning = !isRunning;
setMotor(isRunning);
}
}
bool checkTouch() {
static unsigned long lastTouch = 0;
if(millis() - lastTouch < 200) return false; // 防误触
if(digitalRead(TOUCH_PIN)) {
lastTouch = millis();
return true;
}
return false;
}
灵敏度调节
部分触摸模块支持灵敏度调整:
- 硬件调节:通过改变外部电容容值
- 软件调节:修改检测阈值或采样次数
// 软件滤波示例
int samples = 0;
for(int i=0; i<5; i++) {
samples += digitalRead(TOUCH_PIN);
delay(10);
}
if(samples >= 3) { // 5次采样中3次高电平判定为触摸
// 触发动作
}
注意事项
- 避免触摸电极附近存在金属物体干扰
- 长按功能需结合定时器实现,区分单击/长按
- 潮湿环境可能导致灵敏度下降
代码
在上一篇的基础上优化代码并添加触摸按键模块。
// 引脚定义
#define FR1 6
#define FR2 10
#define FL1 5
#define FL2 9
#define BR1 A5
#define BR2 11
#define BL1 A4
#define BL2 3
#define TOUCH_PIN A0
bool isRunning = false;
// 停止所有电机
void stopCart();
// 前进
void moveForward();
// 后退
void moveBackward();
// 左转
void turnLeft();
// 右转
void turnRight();
void setup() {
pinMode(FR1, OUTPUT);
pinMode(FR2, OUTPUT);
pinMode(FL1, OUTPUT);
pinMode(FL2, OUTPUT);
pinMode(BR1, OUTPUT);
pinMode(BR2, OUTPUT);
pinMode(BL1, OUTPUT);
pinMode(BL2, OUTPUT);
stopCart(); // 初始状态停止所有电机
pinMode(TOUCH_PIN, INPUT);
attachInterrupt(digitalPinToInterrupt(TOUCH_PIN), touchISR, CHANGE);
}
// 中断服务函数处理
void touchISR() {
int state = digitalRead(TOUCH_PIN);
if (state == HIGH) {
if (digitalRead(TOUCH_PIN) == HIGH) {
delay(50);
if (digitalRead(TOUCH_PIN) == HIGH) {
isRunning = true;
}
}
} else {
isRunning = false;
}
}
void loop() {
touchISR();
if (isRunning) {
moveForward();
} else {
stopCart();
}
}
void stopCart() {
digitalWrite(FR1, 0);
digitalWrite(FR2, 0);
digitalWrite(FL1, 0);
digitalWrite(FL2, 0);
digitalWrite(BR1, 0);
digitalWrite(BR2, 0);
digitalWrite(BL1, 0);
digitalWrite(BL2, 0);
}
void moveForward() {
// 前右轮(FR) - 正转
digitalWrite(FR1, 0);
digitalWrite(FR2, 1);
// 前左轮(FL) - 正转
digitalWrite(FL1, 0);
digitalWrite(FL2, 1);
// 后右轮(BR) - 正转
digitalWrite(BR1, 0);
digitalWrite(BR2, 1);
// 后左轮(BL) - 正转
digitalWrite(BL1, 0);
digitalWrite(BL2, 1);
}
void moveBackward() {
// 前右轮(FR) - 反转
digitalWrite(FR1, 1);
digitalWrite(FR2, 0);
// 前左轮(FL) - 反转
digitalWrite(FL1, 1);
digitalWrite(FL2, 0);
// 后右轮(BR) - 反转
digitalWrite(BR1, 1);
digitalWrite(BR2, 0);
// 后左轮(BL) - 反转
digitalWrite(BL1, 1);
digitalWrite(BL2, 0);
}
void turnLeft() {
// 前右轮(FR) - 反转
digitalWrite(FR1, 1);
digitalWrite(FR2, 0);
// 前左轮(FL) - 正转
digitalWrite(FL1, 0);
digitalWrite(FL2, 1);
// 后右轮(BR) - 反转
digitalWrite(BR1, 1);
digitalWrite(BR2, 0);
// 后左轮(BL) - 正转
digitalWrite(BL1, 0);
digitalWrite(BL2, 1);
}
void turnRight() {
// 前右轮(FR) - 正转
digitalWrite(FR1, 0);
digitalWrite(FR2, 1);
// 前左轮(FL) - 反转
digitalWrite(FL1, 1);
digitalWrite(FL2, 0);
// 后右轮(BR) - 正转
digitalWrite(BR1, 0);
digitalWrite(BR2, 1);
// 后左轮(BL) - 反转
digitalWrite(BL1, 1);
digitalWrite(BL2, 0);
}