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

C++使用Blink without delay非阻塞方法实现单次事件的Arduino电机控制问题

问题根因

你的关停判断逻辑没有和DC电机的运行状态绑定,无论电机是否处于运行状态,只要时间差大于runinterval就会触发执行,自然会每隔runinterval重复触发关停指令。你之前用布尔变量测试失败的核心原因是把previousMillis的更新逻辑放在了关停判断块内,没有把时间更新和电机启动的动作绑定。

修正方案

你已经定义了CheckRAStatus变量用来标记RA电机(ID=1的DC电机)的运行状态,直接复用该变量即可,不需要额外新增标记位,只需要修改两处逻辑:

  1. 收到串口启动RA电机的指令时,同步记录当前时间为计时起始点
  2. 关停判断增加前置条件:仅当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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 12:06:04