1. 硬件选型与传感器布局做循迹小车的第一步就是选对硬件。我刚开始玩Arduino的时候也踩过不少坑比如用了数字传感器发现根本达不到PID控制需要的精度。后来才发现模拟红外传感器才是王道它能输出连续变化的电压值比只有0/1的数字信号细腻多了。推荐用三路模拟红外传感器比如TCRT5000价格便宜又好用。这三个小家伙要一字排开中间间隔1.5-2cm比较合适。实测发现间距太近容易误判太远又会漏掉弯道。记得买带A/D引脚的版本接线时左边接A0中间A1右边A2这样后面编程时逻辑更清晰。传感器安装高度也有讲究。我建议离地面1cm左右太近了容易刮蹭太远了检测灵敏度会下降。可以用热熔胶临时固定调试好位置后再用螺丝加固。有个小技巧在黑色电工胶布上贴白色纸条作为测试赛道用串口监视器观察三个传感器的数值变化这样能快速验证安装是否合理。2. 模拟信号处理技巧拿到原始模拟值只是第一步关键是怎么处理这些数据。三个传感器的值会随着环境光线、赛道材质变化直接使用绝对数值很容易翻车。我的经验是采用差值法用左传感器值减去右传感器值得到一个反映偏离程度的相对值。具体算法可以这样优化int leftVal analogRead(A0) - 50; // 减去基础噪声值 int rightVal analogRead(A2) - 50; int midVal analogRead(A1); int deviation (leftVal - rightVal) offset; // offset是校准值当小车完全居中时deviation应该接近0。如果发现总是有偏差可以通过offset微调。遇到十字路口或断线时可以结合中间传感器的值做特殊处理if(midVal threshold abs(deviation) 20){ // 遇到急弯或十字路口的处理逻辑 }建议在代码里添加串口打印把三个传感器的原始值和计算后的deviation都输出出来。调试时用Excel画折线图能直观看到小车运动时的数据变化规律。3. PID控制原理与实现PID控制器就像是个老司机能根据当前偏离程度自动调整方向盘。P代表现在偏离多远I代表历史累计误差D预判未来趋势。这三个参数配合能让小车跑得又快又稳。先看最简单的P控制float Kp 0.1; // 比例系数 float error GetDeviation(); float output Kp * error;P值越大修正力度越强但太大容易画龙。我建议从0.05开始试每次增加0.01观察效果。加上I和D之后算法升级为float Kp0.05, Ki0.001, Kd0.02; float P error; I error; // 积分项 D error - lastError; // 微分项 PID_output Kp*P Ki*I Kd*D; lastError error;注意积分项I需要设限幅否则长时间运行会溢出。建议限制在±100范围内。微分项D能抑制振荡但噪声大的时候反而会添乱这时候可以加个低通滤波器。4. 电机控制与差速转向L298N电机驱动模块是经典选择能同时驱动两个直流电机。接线时要注意ENA/ENB接PWM引脚数字3,5,6等IN1-IN4接普通数字口。差速转向的原理很简单左转时右轮加速右转时左轮加速。具体实现代码void setMotor(int leftSpeed, int rightSpeed){ // 限制速度在0-255之间 leftSpeed constrain(leftSpeed, 0, 255); rightSpeed constrain(rightSpeed, 0, 255); analogWrite(LEFT_PWM, leftSpeed); analogWrite(RIGHT_PWM, rightSpeed); }将PID输出转化为电机速度int baseSpeed 150; // 基础速度 int leftSpeed baseSpeed - PID_output; int rightSpeed baseSpeed PID_output; setMotor(leftSpeed, rightSpeed);遇到全黑或全白区域时比如十字路口需要特殊处理。我的做法是记录最近的有效偏差方向保持原有转向直到重新检测到赛道。5. 参数调试实战技巧调参是个耐心活建议按这个顺序来先把Ki和Kd设为0只调Kp慢慢增加Kp直到小车开始轻微振荡引入Kd来抑制振荡从Kp的1/10开始试最后加Ki消除静态误差值要非常小调试时可以准备三种赛道直线、缓弯、急弯。记录下每种情况下小车的表现我常用的参数组合是直线赛道Kp0.05, Ki0, Kd0.01普通弯道Kp0.07, Ki0.001, Kd0.02复杂赛道Kp0.1, Ki0.002, Kd0.03遇到特别急的弯道时可以动态调整参数。比如检测到偏差突然变大时临时提高Kp值。也可以在弯道处贴反光条用额外传感器提前预警。6. 常见问题排查做第一个版本时我的小车总在弯道冲出赛道。后来发现是电机响应延迟导致的解决方法是在代码里加入加速限制// 限制加速度变化率 currentSpeed lastSpeed constrain(targetSpeed-lastSpeed, -10, 10);另一个常见问题是传感器受环境光干扰。可以在传感器周围加遮光罩或者改用主动式红外传感器。电源噪声也会影响模拟信号建议给传感器单独供电并加上0.1uF的滤波电容。如果发现PID输出剧烈波动可能是微分项太敏感。可以尝试// 对微分项做滑动平均滤波 D_buffer[D_index] error - lastError; D_index (D_index1) % 5; float filtered_D 0; for(int i0; i5; i) filtered_D D_buffer[i]; D filtered_D / 5;7. 性能优化进阶当基本功能实现后可以尝试这些优化动态速度控制直道加速弯道减速记忆赛道记录历史偏差值预测弯道多级PID针对不同赛道段切换参数组卡尔曼滤波处理噪声大的传感器信号一个实用的速度控制策略float speedFactor 1 - abs(PID_output)/maxOutput; currentSpeed baseSpeed * speedFactor;对于高级玩家可以移植到STM32平台获得更高性能。或者加上蓝牙模块用手机APP实时调整PID参数。我在最新版小车上加了OLED屏幕能实时显示传感器数据和PID参数调试方便多了。