You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现按钮释放后延迟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标记舵机是否已完成动作,确保每次按钮释放只触发一次舵机转动。

注意事项

  1. 请确保在setup()中给舵机绑定了正确的引脚(magazine_servo.attach(引脚号))。
  2. 如果你的按钮是下拉输入(按下为高电平),需要把边缘检测条件改成prev_btn_state && !btn_state。

内容的提问来源于stack exchange,提问作者KD Technology

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 07:04:52