3Pi+机器人巡线挑战故障:传感器正常时机器人直行无视线路
3Pi+巡线机器人仅直行不跟随线路修复方案
核心问题点
- 转向逻辑完全反向
现有逻辑中,左传感器检测到黑线时执行右转、右传感器检测到黑线时执行左转,完全和实际需求相反:左传感器压到黑线说明线路在机器人左侧,需要向左转向才能将中线拉回黑线,反之同理。 - 缺少状态兜底处理
仅设置了三种触发场景,只要不满足这三种条件(比如三个传感器同时在黑线上、同时在白地上、左右同时压黑线),电机就会保持初始的直行状态,不会触发任何转向动作。 - 阈值未绑定实测数据
固定的10000阈值需要和串口打印的实际读数匹配:白色地面的elapsed_time应小于阈值,黑色线路的elapsed_time应大于阈值,阈值设置错误会导致所有判断条件都无法触发。 - 传感器索引对应关系需要验证
确认ls_pin数组{左传感器、中传感器、右传感器}的顺序和实际硬件接线完全对应,接线顺序错误会导致所有逻辑失效。
修复后参考代码
const int left_sensor_pin = A0; const int right_sensor_pin = A3; const int centre_sensor_pin = A2; // 存储传感器引脚 #define NB_LS_PINS 3 int ls_pin[NB_LS_PINS] = { left_sensor_pin, centre_sensor_pin, right_sensor_pin }; // 时间相关变量 unsigned long start_time; unsigned long elapsed_time [3]; unsigned long end_time_ls [3]; // 统一定义巡线阈值,方便根据实测调整 #define LINE_THRESHOLD 10000 bool done = false; # define L_PWM_PIN 10 # define L_DIR_PIN 16 # define R_PWM_PIN 9 # define R_DIR_PIN 15 void setup() { Serial.begin (9600); pinMode (left_sensor_pin, INPUT); pinMode (right_sensor_pin, INPUT); pinMode (centre_sensor_pin, INPUT); delay(5000); pinMode(L_PWM_PIN, OUTPUT); pinMode(L_DIR_PIN, OUTPUT); pinMode(R_PWM_PIN, OUTPUT); pinMode(R_DIR_PIN, OUTPUT); digitalWrite(L_DIR_PIN, LOW); digitalWrite(R_DIR_PIN, LOW); } void loop() { // 电容充电 pinMode (left_sensor_pin, OUTPUT); pinMode (right_sensor_pin, OUTPUT); pinMode (centre_sensor_pin, OUTPUT); digitalWrite(left_sensor_pin, HIGH); digitalWrite(right_sensor_pin, HIGH); digitalWrite(centre_sensor_pin, HIGH); delayMicroseconds(10); start_time = micros(); pinMode (left_sensor_pin, INPUT); pinMode (right_sensor_pin, INPUT); pinMode (centre_sensor_pin, INPUT); bool pins_read [3] = {false, false, false}; done = false; while (done == false) { for (int which = 0; which < NB_LS_PINS; which++) { if (digitalRead(ls_pin[which]) == LOW && pins_read[which] == false) { end_time_ls[which] = micros(); pins_read[which] = true; } if (pins_read[0] && pins_read[1] && pins_read[2]) { done = true; } } } elapsed_time[0] = end_time_ls[0] - start_time; elapsed_time[1] = end_time_ls[1] - start_time; elapsed_time[2] = end_time_ls[2] - start_time; Serial.println(elapsed_time[0]); Serial.println(elapsed_time[1]); Serial.println(elapsed_time[2]); Serial.println("------------------------------"); // 修正后的电机控制逻辑 if (elapsed_time[0] < LINE_THRESHOLD && elapsed_time[1] > LINE_THRESHOLD && elapsed_time[2] < LINE_THRESHOLD) { // 中线压黑线,直行 analogWrite(L_PWM_PIN, 100); analogWrite(R_PWM_PIN, 100); } else if (elapsed_time[0] > LINE_THRESHOLD && elapsed_time[1] < LINE_THRESHOLD && elapsed_time[2] < LINE_THRESHOLD) { // 左传感器压黑线,左转 analogWrite(L_PWM_PIN, 0); analogWrite(R_PWM_PIN, 100); } else if (elapsed_time[0] < LINE_THRESHOLD && elapsed_time[1] < LINE_THRESHOLD && elapsed_time[2] > LINE_THRESHOLD) { // 右传感器压黑线,右转 analogWrite(L_PWM_PIN, 100); analogWrite(R_PWM_PIN, 0); } else { // 兜底逻辑,可根据需求调整,此处为低速直行找线 analogWrite(L_PWM_PIN, 50); analogWrite(R_PWM_PIN, 50); } }
验证步骤
- 先单独测试传感器,分别将三个传感器放在黑线和白地上,记录串口输出的elapsed_time数值,调整
LINE_THRESHOLD为黑白读数的中间值。 - 空载测试转向逻辑,手动将左传感器放在黑线上,确认左轮停转、右轮转动,机器人向左转向,反之右传感器压黑线时向右转向。
内容的提问来源于stack exchange,提问作者er281
相关产品推荐
相关产品推荐

