如何使用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
相关产品推荐
相关产品推荐

