Arduino Uno项目技术求助:按键控制伺服与真空泵逻辑实现
Arduino Uno 按键控制顺序动作与分支执行方案
硬件引脚定义(可根据实际接线调整)
| 部件 | Arduino 引脚 | 说明 |
|---|---|---|
| servo1(升降系统) | 10 | PWM 驱动引脚 |
| servo2(旋转龙头) | 11 | PWM 驱动引脚 |
| 真空泵1继电器 | 2 | 数字输出引脚 |
| 真空泵2继电器 | 3 | 数字输出引脚 |
| 真空泵3继电器 | 4 | 数字输出引脚 |
| 真空泵4继电器 | 5 | 数字输出引脚 |
| 按键1 | 6 | 内部上拉输入(按下为LOW) |
| 按键2 | 7 | 内部上拉输入(按下为LOW) |
| 按键3 | 8 | 内部上拉输入(按下为LOW) |
| 按键4 | 9 | 内部上拉输入(按下为LOW) |
核心代码实现
#include <Servo.h> // 舵机对象初始化 Servo servo1; Servo servo2; // 继电器与按键引脚数组 const int relayPins[] = {2, 3, 4, 5}; const int buttonPins[] = {6, 7, 8, 9}; // 按键防抖变量 int buttonStates[4] = {HIGH, HIGH, HIGH, HIGH}; int lastButtonStates[4] = {HIGH, HIGH, HIGH, HIGH}; unsigned long lastDebounceTimes[4] = {0, 0, 0, 0}; const unsigned long debounceDelay = 50; // 动作参数(需根据机械结构实际调整) const int servo2TargetAngle = 70; // 旋转龙头目标角度 const long servo1RotateDuration = 2000; // 升降舵机单方向转动时长(控制圈数) const long pumpRunDuration = 3000; // 真空泵运行时长 void setup() { // 初始化舵机引脚 servo1.attach(10); servo2.attach(11); // 初始化继电器引脚(默认低电平关闭) for (int i = 0; i < 4; i++) { pinMode(relayPins[i], OUTPUT); digitalWrite(relayPins[i], LOW); } // 初始化按键为内部上拉输入 for (int i = 0; i < 4; i++) { pinMode(buttonPins[i], INPUT_PULLUP); } // 旋转龙头归位到初始角度 servo2.write(0); } // 控制servo1转动指定圈数(1=正转,-1=反转) void rotateServo1(int direction) { int pulseWidth = (direction == 1) ? 2000 : 1000; unsigned long startTime = millis(); while (millis() - startTime < servo1RotateDuration) { servo1.writeMicroseconds(pulseWidth); delay(20); // 维持舵机驱动脉冲 } // 停止舵机(输出中立脉冲) servo1.writeMicroseconds(1500); } // 执行对应按键的顺序动作 void runSequence(int buttonIndex) { // 步骤1:servo1正转指定圈数 rotateServo1(1); // 步骤2:servo2转到70度并等待到位 servo2.write(servo2TargetAngle); delay(500); // 步骤3:触发对应真空泵并维持运行时长 digitalWrite(relayPins[buttonIndex], HIGH); delay(pumpRunDuration); digitalWrite(relayPins[buttonIndex], LOW); // 步骤4:servo2转回初始角度并等待到位 servo2.write(0); delay(500); // 步骤5:servo1反转指定圈数归位 rotateServo1(-1); } void loop() { // 遍历检测4个按键状态 for (int i = 0; i < 4; i++) { int currentReading = digitalRead(buttonPins[i]); // 按键状态变化时重置防抖计时器 if (currentReading != lastButtonStates[i]) { lastDebounceTimes[i] = millis(); } // 防抖时间过后更新按键状态 if (millis() - lastDebounceTimes[i] > debounceDelay) { if (currentReading != buttonStates[i]) { buttonStates[i] = currentReading; // 检测到按键按下(内部上拉模式下,按下为LOW) if (buttonStates[i] == LOW) { runSequence(i); } } } lastButtonStates[i] = currentReading; } }
关键说明
- 分支逻辑实现:通过按键索引传递给
runSequence函数,函数内部根据索引触发对应继电器,避免编写重复的动作代码,实现按键与真空泵的一一对应。 - 舵机整圈转动:MG996R默认是角度舵机,通过持续输出极限脉冲(1000us/2000us)实现连续转动,
servo1RotateDuration需根据实际机械结构调整,确保转动指定圈数。 - 按键防抖:使用
millis()实现非阻塞防抖,避免按键抖动导致误触发,同时不影响后续动作执行。 - 电源提醒:MG996R舵机和真空泵需外接独立电源供电,不能直接使用Arduino Uno的5V引脚,否则会因电流不足导致故障,注意电源与Arduino共地。
内容的提问来源于stack exchange,提问作者Samuel Olds
相关产品推荐
相关产品推荐

