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

Arduino通过串口传入目标值时PID循环失效问题排查求助

Arduino通过串口传入目标值时PID循环失效问题排查求助

看起来你遇到了一个典型的变量作用域问题,这也是很多Arduino开发者容易踩的小坑!让我帮你拆解问题根源并给出解决方案:

核心问题:变量作用域冲突

在你的串口接收代码块里,你重新声明了一个局部变量rpm,这会覆盖全局定义的rpm变量:

if (Serial.available() > 0) {
    String received_speed = Serial.readStringUntil('\n');
    // 这里的int rpm是局部变量,和全局rpm不是同一个!
    int rpm = round(rpm_correction_factor * (received_speed.toInt())/(wheel_circumference * 3.14 * 60));
    Serial.print("transmission received");
}

也就是说,你在这个if块里计算出的rpm值只在当前代码块内有效,全局的rpm变量始终保持初始的0值。后面代码里int target = rpm拿到的自然就是0,这就是为什么串口监视器里target显示为0的原因。

解决方案:修正变量赋值方式

只需要去掉局部变量声明的int关键字,直接给全局的rpm变量赋值即可:

if (Serial.available() > 0) {
    String received_speed = Serial.readStringUntil('\n');
    // 直接给全局rpm赋值,不再声明新的局部变量
    rpm = round(rpm_correction_factor * (received_speed.toInt())/(wheel_circumference * 3.14 * 60));
    // 建议增加调试输出,确认赋值结果
    Serial.print("transmission received, target rpm set to: ");
    Serial.println(rpm);
}

额外优化建议

  • 给全局rpm显式初始化默认值:int rpm = 0;(虽然Arduino全局变量默认初始为0,但显式初始化代码可读性更强)
  • 把计算里的3.14定义为常量:#define PI 3.14159,这样圆周率的精度更高,代码也更易维护
  • 可以在串口接收时增加合法性校验,比如判断received_speed.toInt()是否为有效数值,避免异常输入影响程序运行

修改完成后,全局rpm会正确接收串口传来的数值,target变量也能被正确赋值,你的PID循环应该就能正常工作了!

备注:内容来源于stack exchange,提问作者TJ Webster

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.22 14:32:59