如何实现按钮释放后延迟0.5秒让连续旋转舵机转动45度?
解决按钮释放后延时触发舵机动作的问题
我来帮你调整代码,实现检测按钮释放后等待0.5秒,再让舵机转动45度的需求。首先咱们梳理下原代码的问题:原逻辑没有正确处理按钮释放的边缘检测,直接用状态变化触发舵机会导致误触发,同时也没实现非阻塞的延时等待逻辑(得贴合你原本用millis()定时更新的设计)。
修改后的完整代码
#include <Servo.h> // 确保包含舵机库 #define UPDATE_MS (100) #define BTN_PIN (5) #define DELAY_AFTER_RELEASE (500) // 释放后等待的时间(毫秒) Servo magazine_servo; // 舵机对象,需在setup中初始化引脚 bool btn_state = 1; bool prev_btn_state = 1; bool btn_released = false; // 标记是否检测到按钮释放 unsigned long delay_start_time = 0; // 记录释放后开始计时的时间 bool servo_moved = false; // 标记舵机是否已执行动作,防止重复触发 unsigned long previous_millis = 0; // 原代码遗漏的变量,补上 void setup() { pinMode(BTN_PIN, INPUT_PULLUP); // 假设用内部上拉,按钮按下为低电平 magazine_servo.attach(9); // 替换成你的舵机实际引脚 } void loop () { // 每100ms更新一次按钮状态 if (millis() - previous_millis >= UPDATE_MS) { previous_millis = millis(); prev_btn_state = btn_state; // 先保存上一次状态 btn_state = digitalRead(BTN_PIN); // 读取当前按钮状态 // 检测按钮释放的边缘:从按下(低电平0)变为释放(高电平1) if (!prev_btn_state && btn_state) { btn_released = true; delay_start_time = millis(); // 记录释放时刻的时间点 servo_moved = false; // 重置舵机动作标记 } } // 处理延时后的舵机动作 if (btn_released && !servo_moved) { if (millis() - delay_start_time >= DELAY_AFTER_RELEASE) { magazine_servo.write(45); // 控制舵机转动到45度 servo_moved = true; // 标记已执行,避免重复触发 btn_released = false; // 重置释放标记,等待下一次按钮操作 } } }
关键逻辑说明
- 边缘检测:通过对比前后两次的按钮状态,只在按钮从按下切换到释放的瞬间启动延时计时,避免持续检测状态导致的误触发。
- 非阻塞延时:用
millis()记录释放时刻的时间,之后每次循环检查是否已过500ms,完全贴合你原本用millis()定时更新的设计,不会阻塞其他代码执行。 - 防重复触发:用
servo_moved标记舵机是否已完成动作,确保每次按钮释放只触发一次舵机转动。
注意事项
- 请确保在
setup()中给舵机绑定了正确的引脚(magazine_servo.attach(引脚号))。 - 如果你的按钮是下拉输入(按下为高电平),需要把边缘检测条件改成
prev_btn_state && !btn_state。
内容的提问来源于stack exchange,提问作者KD Technology
相关产品推荐
相关产品推荐

