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
相关产品推荐
相关产品推荐

