Arduino Uno双舵机项目(定时器+水位传感器触发)代码故障咨询
Arduino双舵机控制异常修复方案
核心问题点
- 两个舵机共用全局
angle变量,舵机A的角度修改会直接干扰舵机B的状态判断,反过来也一样,逻辑完全混乱 - 大量使用阻塞函数
delay(),执行delay的8秒内,所有按键检测、24小时计时、水位检测逻辑全部停止运行 - 按钮逻辑不符合需求:当前逻辑是按下按键保持舵机开启、松开就关闭,需求是触发后开启固定时长
- 水位判断逻辑无触发锁止,只要水位持续低于300就会反复执行8秒延迟,导致程序全程卡死
- loop函数中重复定义
waterLevel局部变量,与全局变量冲突,属于不规范写法
修复后代码
#include <Servo.h> Servo myservoA; Servo myservoB; const int BUTTONA_PIN = 8; const int BUTTONB_PIN = 6; const int SERVOA_PIN = 9; const int SERVOB_PIN = 7; const int WATER_SENSOR_PIN = A0; // 24小时自动触发相关参数 unsigned long dayTimer_ms = 0; const unsigned long AUTO_OPEN_DELAY_MS = 86400000UL; const unsigned long OPEN_DURATION_MS = 8000UL; // 舵机A独立状态变量 unsigned long servoA_start_ms = 0; bool servoA_isRunning = false; // 舵机B独立状态变量 unsigned long servoB_start_ms = 0; bool servoB_isRunning = false; // 水位检测相关变量 int waterLevel = 0; bool waterTriggered = false; void setup(){ myservoA.attach(SERVOA_PIN); myservoB.attach(SERVOB_PIN); pinMode(BUTTONA_PIN, INPUT_PULLUP); pinMode(BUTTONB_PIN, INPUT_PULLUP); myservoA.write(0); myservoB.write(0); } void loop() { unsigned long now = millis(); // millis溢出处理 if(now < dayTimer_ms) { dayTimer_ms = now; } // 舵机A 24小时自动触发逻辑 if(!servoA_isRunning && (now - dayTimer_ms > AUTO_OPEN_DELAY_MS)) { dayTimer_ms = now; servoA_isRunning = true; servoA_start_ms = now; myservoA.write(180); } // 舵机A 按键触发逻辑 if(!servoA_isRunning && !digitalRead(BUTTONA_PIN)) { servoA_isRunning = true; servoA_start_ms = now; myservoA.write(180); } // 舵机A 运行时长判断,到点自动关闭 if(servoA_isRunning && (now - servoA_start_ms >= OPEN_DURATION_MS)) { myservoA.write(0); servoA_isRunning = false; } // 舵机B 按键触发逻辑 if(!servoB_isRunning && !digitalRead(BUTTONB_PIN)) { servoB_isRunning = true; servoB_start_ms = now; myservoB.write(180); } // 水位检测逻辑 waterLevel = analogRead(WATER_SENSOR_PIN); if(!servoB_isRunning && waterLevel <= 300 && !waterTriggered) { waterTriggered = true; servoB_isRunning = true; servoB_start_ms = now; myservoB.write(180); } // 水位恢复正常后重置触发标记,避免反复触发 if(waterLevel > 300) { waterTriggered = false; } // 舵机B 运行时长判断,到点自动关闭 if(servoB_isRunning && (now - servoB_start_ms >= OPEN_DURATION_MS)) { myservoB.write(0); servoB_isRunning = false; } }
内容的提问来源于stack exchange,提问作者Matthew Kerry
相关产品推荐
相关产品推荐

