C++使用Blink without delay非阻塞方法实现单次事件的Arduino电机控制问题
问题根因
你的关停判断逻辑没有和DC电机的运行状态绑定,无论电机是否处于运行状态,只要时间差大于runinterval就会触发执行,自然会每隔runinterval重复触发关停指令。你之前用布尔变量测试失败的核心原因是把previousMillis的更新逻辑放在了关停判断块内,没有把时间更新和电机启动的动作绑定。
修正方案
你已经定义了CheckRAStatus变量用来标记RA电机(ID=1的DC电机)的运行状态,直接复用该变量即可,不需要额外新增标记位,只需要修改两处逻辑:
- 收到串口启动RA电机的指令时,同步记录当前时间为计时起始点
- 关停判断增加前置条件:仅当RA电机处于运行状态时才判断是否到达运行时长,触发关停后不需要再更新
previousMillis
修改后的代码片段
串口接收逻辑修改
if (parsemotorparameters.ReturnMotorId() == 1) { Serial.println(runinterval); //RAMOTOR->setSpeed(RASpeed); //RAMOTOR->run(parsemotorparameters.ReturnMotorDirection()); CheckRAStatus = true; previousMillis = millis(); // 新增该行,电机启动时记录计时起始时间 }
关停判断逻辑修改
// 仅当RA电机处于运行状态时才做超时判断 if (CheckRAStatus && (currentMillis - previousMillis > runinterval)) { //RAMOTOR->fullOff(); Serial.println("OFF"); CheckRAStatus = false; // 删掉原有的previousMillis = currentMillis逻辑,无需再更新 }
逻辑说明
- 只有接收到启动指令、电机实际开始运行时才会重置计时起始点,计时逻辑和电机运行动作完全对齐
- 关停判断增加了运行状态校验,电机关停后
CheckRAStatus变为false,不会再进入该判断块,关停指令只会执行一次 - 全程都是非阻塞逻辑,不会影响串口输入的正常接收
内容的提问来源于stack exchange,提问作者Fabian Butkovich
相关产品推荐
相关产品推荐

