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

如何使用Arduino编写双按钮控制伺服电机摆动与停止的代码?

伺服电机往复摆动与停止控制代码修复

原代码存在的问题

  • 嵌套循环逻辑错误:内层for循环被放在外层循环的代码块内,导致每次外层循环递增pos时都会执行一次从90到0的摆动,运动完全不符合预期。
  • 无状态跟踪机制:一旦启动摆动,会阻塞直到循环完成,无法中途响应停止按钮。
  • 位置记录失效:lastpos仅初始化一次,未随伺服电机位置更新,无法正确保持停止时的当前位置。
  • 按钮引脚配置问题:使用INPUT模式但未配置上拉电阻,引脚会处于浮空状态,导致按钮读取不稳定。

修复后的代码

#include <Servo.h>

Servo myservo;
int pos = 0;                    // 当前伺服位置
const int button1 = 5;          // 启动摆动按钮引脚
const int button2 = 6;          // 停止摆动按钮引脚
bool isMoving = false;          // 运动状态标记:true=摆动中,false=停止
int direction = 1;              // 运动方向:1=从0到90,-1=从90到0
unsigned long lastDebounceTime = 0; // 按键防抖时间记录
const unsigned long debounceDelay = 50; // 防抖延时(毫秒)

void setup() {
  myservo.attach(3);            // 将伺服连接到引脚3
  pinMode(button1, INPUT_PULLUP); // 使用内部上拉电阻,按键按下时引脚为LOW
  pinMode(button2, INPUT_PULLUP);
}

void loop() {
  unsigned long currentTime = millis();

  // 处理启动按钮(按键按下时触发)
  if (digitalRead(button1) == LOW && currentTime - lastDebounceTime > debounceDelay) {
    isMoving = true;
    lastDebounceTime = currentTime;
  }

  // 处理停止按钮(按键按下时触发)
  if (digitalRead(button2) == LOW && currentTime - lastDebounceTime > debounceDelay) {
    isMoving = false;
    lastDebounceTime = currentTime;
  }

  // 如果处于摆动状态
  if (isMoving) {
    pos += direction; // 更新当前位置

    // 到达边界时反转方向
    if (pos <= 0 || pos >= 90) {
      direction *= -1;
      // 确保位置不超出范围
      pos = constrain(pos, 0, 90);
    }

    myservo.write(pos); // 更新伺服位置
    delay(15); // 控制摆动速度,数值越小摆动越快
  }
  // 停止时保持当前位置(伺服会自动维持最后一次写入的位置)
}

代码说明

  • 运动状态管理:通过isMoving标记控制伺服是否摆动,实现按钮的即时响应。
  • 方向控制:使用direction变量切换运动方向,实现0-90度的往复摆动。
  • 按键防抖:通过millis()实现非阻塞式防抖,避免按键误触发。
  • 引脚配置:使用INPUT_PULLUP模式,无需额外外接上拉电阻,简化电路。
  • 位置约束:使用constrain()确保伺服位置不会超出0-90度范围。

内容的提问来源于stack exchange,提问作者Eduardo Peixoto

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 01:40:22