【花雕学编程】Arduino BLDC 之红外巡线+动态避障复合系统

在这里插入图片描述
《Arduino 手册(思路与案例)》栏目介绍:
在电子制作与智能控制的应用领域,本栏目涵盖了丰富的内容,包括但不限于以下主题:Arduino BLDC、Arduino CNC、Arduino E-Ink、Arduino ESP32 SPP、Arduino FreeRTOS、Arduino FOC、Arduino GRBL、Arduino HTTP、Arduino HUB75、Arduino IoT Cloud、Arduino JSON、Arduino LCD、Arduino OLED、Arduino LVGL、Arduino PID、Arduino TFT,以及Arduino智能家居、智慧交通、月球基地、智慧校园和智慧农业等多个方面与领域。不仅探讨了这些技术的基础知识和应用领域,还提供了众多具体的参考案例,帮助读者更好地理解和运用Arduino平台进行创新项目。目前,本栏目已有近4000篇相关博客,旨在为广大电子爱好者和开发者提供全面的学习资源与实践指导。通过这些丰富的案例和思路,读者可以获取灵感,推动自己的创作与开发进程。
https://blog.csdn.net/weixin_41659040/category_12422453.html

在这里插入图片描述

Arduino BLDC 之 红外巡线 + 动态避障复合系统

一、主要特点
红外巡线功能:

系统使用红外传感器检测地面上的线路,通过简单的算法,机器人能够沿着预设路径稳定行驶,实现自动巡线。
动态避障能力:

集成多种传感器(如超声波传感器、激光雷达等),实时检测周围环境,识别障碍物并自动调整运动轨迹,确保机器人在动态环境中的安全性。
复合控制策略:

结合红外巡线和动态避障两种功能,系统能够在巡线的同时有效避开障碍物,提升导航的智能性和灵活性。
实时反馈与调整:

系统能够实时接收传感器反馈,快速调整运动策略,确保机器人在复杂环境中保持稳定和高效。
易于编程与扩展:

基于 Arduino 平台的设计使得系统易于编程和扩展,用户可以根据需求添加更多传感器或功能模块,增强系统的功能。

二、应用场景
智能物流:

在仓库和物流中心,红外巡线 + 动态避障系统可以用于自动搬运小车,优化物品运输和分拣流程,提高工作效率。
家庭服务机器人:

在智能家居中,该系统可用于清扫机器人,实现自主巡回清扫,同时避开家具等障碍物,提升用户体验。
教育与科研:

在机器人教育和科研项目中,红外巡线 + 动态避障系统是学习控制理论和机器人技术的理想平台,适用于实验和项目开发。
工业自动化:

在生产线中,机器人可通过此系统实现自动搬运、装配等任务,适应复杂的工作环境。
无人驾驶小车:

在无人驾驶技术中,该系统可用于开发小型自动驾驶车辆,实现智能巡航与避障。

三、注意事项
传感器选择与配置:

选择高精度的红外传感器和避障传感器,确保其在不同光照和环境条件下的稳定性和可靠性。
算法优化:

针对巡线和避障的算法需要进行优化,以确保系统在复杂环境中能够快速反应,避免路径偏差或碰撞。
环境建模:

在设计时考虑环境的复杂性,确保系统能够准确识别巡线和障碍物,避免误判。
电源管理:

合理管理电源,确保系统在长时间运行中的稳定性和续航能力,特别是在移动设备中。
安全性设计:

在控制系统中设置合理的安全限制,确保机器人在运行过程中的安全性,避免对人员和设备造成伤害。

在这里插入图片描述
1、基础红外巡线

#include <Servo.h>

Servo motorLeft;  // 左侧电机
Servo motorRight; // 右侧电机

const int leftSensor = A0;  // 左侧红外传感器
const int rightSensor = A1; // 右侧红外传感器

void setup() {
    Serial.begin(9600);
    motorLeft.attach(9);
    motorRight.attach(10);
}

void loop() {
    int leftValue = analogRead(leftSensor);
    int rightValue = analogRead(rightSensor);

    // 判断传感器的状态
    if (leftValue < 500 && rightValue < 500) {
        // 在线上,前进
        motorLeft.write(180);
        motorRight.write(180);
    } else if (leftValue < 500) {
        // 左侧在线,右转
        motorLeft.write(180);
        motorRight.write(90);
    } else if (rightValue < 500) {
        // 右侧在线,左转
        motorLeft.write(90);
        motorRight.write(180);
    } else {
        // 停止
        motorLeft.write(90);
        motorRight.write(90);
    }

    delay(100); // 每100毫秒更新一次
}

2、动态避障控制

#include <Servo.h>

Servo motorLeft;
Servo motorRight;

const int frontSensor = A0; // 前方超声波传感器
const int leftSensor = A1;  // 左侧红外传感器
const int rightSensor = A2; // 右侧红外传感器

void setup() {
    Serial.begin(9600);
    motorLeft.attach(9);
    motorRight.attach(10);
}

void loop() {
    int frontValue = analogRead(frontSensor);
    int leftValue = analogRead(leftSensor);
    int rightValue = analogRead(rightSensor);

    if (frontValue < 500) {
        // 前方有障碍物,后退并转向
        motorLeft.write(0);
        motorRight.write(0);
        delay(500);
        motorLeft.write(0);
        motorRight.write(180); // 向右转
        delay(500);
    } else {
        // 没有障碍物,进行巡线控制
        if (leftValue < 500 && rightValue < 500) {
            motorLeft.write(180);
            motorRight.write(180);
        } else if (leftValue < 500) {
            motorLeft.write(180);
            motorRight.write(90);
        } else if (rightValue < 500) {
            motorLeft.write(90);
            motorRight.write(180);
        } else {
            motorLeft.write(90);
            motorRight.write(90);
        }
    }

    delay(100);
}

3、红外巡线与动态避障复合控制

#include <Servo.h>

Servo motorLeft;
Servo motorRight;

const int frontSensor = A0; // 前方超声波传感器
const int leftSensor = A1;  // 左侧红外传感器
const int rightSensor = A2; // 右侧红外传感器

void setup() {
    Serial.begin(9600);
    motorLeft.attach(9);
    motorRight.attach(10);
}

void loop() {
    int frontValue = analogRead(frontSensor);
    int leftValue = analogRead(leftSensor);
    int rightValue = analogRead(rightSensor);

    if (frontValue < 500) {
        // 前方有障碍物,后退并转向
        motorLeft.write(0);
        motorRight.write(0);
        delay(500);
        motorLeft.write(0);
        motorRight.write(180); // 向右转
        delay(500);
    } else {
        // 没有障碍物,进行巡线控制
        if (leftValue < 500 && rightValue < 500) {
            motorLeft.write(180);
            motorRight.write(180);
        } else if (leftValue < 500) {
            motorLeft.write(180);
            motorRight.write(90);
        } else if (rightValue < 500) {
            motorLeft.write(90);
            motorRight.write(180);
        } else {
            motorLeft.write(90);
            motorRight.write(90);
        }
    }

    delay(100);
}

要点解读
红外巡线功能:

第一个示例实现了基础的红外巡线功能。通过读取左侧和右侧的红外传感器值,控制电机的转动,实现沿着黑线的巡行。传感器值小于500表示检测到黑线。
动态避障功能:

第二个示例实现了动态避障的功能。当前方传感器检测到障碍物时,机器人会后退并转向以避免碰撞。然后继续进行巡线控制。
复合控制系统:

第三个示例将红外巡线与动态避障功能结合在一起。该系统能够在巡线的同时,实时避开前方的障碍物,增强了机器人的智能性和灵活性。
传感器输入:

所有示例均使用红外传感器和超声波传感器(假设为模拟输入)来检测环境。红外传感器用于巡线,超声波传感器用于避障。
电机控制:

使用 Servo 库控制 BLDC 电机。根据传感器的反馈,调整电机的角度以实现前进、后退和转向。
延迟控制:

通过 delay() 函数控制动作之间的时间间隔,确保每个动作都能充分执行,避免过快引起的控制失效。
可扩展性:

这些示例提供了基础框架,可以根据需求扩展功能。例如,可以引入更多的传感器(如激光雷达)进行更精确的环境感知,或实现更复杂的控制算法(如 PID 控制)来提高系统的稳定性和响应速度。

在这里插入图片描述
4、基础红外巡线+超声波避障(单任务处理)
功能:通过红外传感器巡线,检测到障碍物时暂停巡线并避障。

#include <NewPing.h>  // 超声波库
#include <PID_v1.h>   // 用于巡线平滑控制
 
// 硬件连接
#define IR_LEFT   A0   // 左侧红外传感器
#define IR_RIGHT  A1   // 右侧红外传感器
#define TRIG_PIN  12   // 超声波Trig
#define ECHO_PIN  11   // 超声波Echo
#define MOTOR_PWM1 5   // BLDC驱动PWM1
#define MOTOR_PWM2 6   // BLDC驱动PWM2
#define MAX_DISTANCE 200 // 超声波最大检测距离(cm)
 
NewPing sonar(TRIG_PIN, ECHO_PIN, MAX_DISTANCE);
double Setpoint = 0.0;  // 巡线目标位置(传感器中间值)
double Input, Output;
double Kp = 2.0, Ki = 0.5, Kd = 1.0;
PID linePID(&Input, &Output, &Setpoint, Kp, Ki, Kd, DIRECT);
 
void setup() {
  Serial.begin(115200);
  pinMode(MOTOR_PWM1, OUTPUT);
  pinMode(MOTOR_PWM2, OUTPUT);
  linePID.SetMode(AUTOMATIC);
  linePID.SetOutputLimits(-255, 255);
  
  // 红外传感器校准(根据实际读数调整)
  Setpoint = (analogRead(IR_LEFT) + analogRead(IR_RIGHT)) / 2.0;
}
 
void loop() {
  // 1. 超声波避障检测
  int distance = sonar.ping_cm();
  if (distance > 0 && distance < 30) { // 检测到障碍物
    avoidObstacle();
    return; // 跳过巡线逻辑
  }
 
  // 2. 红外巡线控制
  int leftVal = analogRead(IR_LEFT);
  int rightVal = analogRead(IR_RIGHT);
  Input = leftVal - rightVal; // 差值表示偏离程度
  
  linePID.Compute();
 
  // 3. 电机控制(差速转向)
  if (Output > 0) {
    // 向右转(左侧电机加速)
    analogWrite(MOTOR_PWM1, 150 + Output);
    analogWrite(MOTOR_PWM2, 150 - Output);
  } else {
    // 向左转(右侧电机加速)
    analogWrite(MOTOR_PWM1, 150 + Output);
    analogWrite(MOTOR_PWM2, 150 - Output);
  }
}
 
void avoidObstacle() {
  // 简单避障逻辑:后退->右转->前进
  Serial.println("Avoiding obstacle!");
  
  // 后退
  analogWrite(MOTOR_PWM1, -180);
  analogWrite(MOTOR_PWM2, -180);
  delay(300);
  
  // 右转
  analogWrite(MOTOR_PWM1, 200);
  analogWrite(MOTOR_PWM2, -200);
  delay(200);
  
  // 恢复巡线
  analogWrite(MOTOR_PWM1, 0);
  analogWrite(MOTOR_PWM2, 0);
}

要点解读:

单任务处理:避障为最高优先级,检测到障碍物时暂停巡线。
红外传感器校准:需根据实际地面反射率调整Setpoint。
差速转向:通过左右电机速度差实现转向,PID输出直接控制差速幅度。
超声波滤波:可对距离值做中值滤波,避免误判。

5、多传感器融合避障(优先级动态切换)

#include <NewPing.h>
#include <QTRSensors.h> // 多路红外传感器库
 
// 硬件定义
#define NUM_SENSORS 4    // 4路红外传感器
#define IR_PINS {A0, A1, A2, A3} // 传感器引脚数组
#define TRIG_PIN 12
#define ECHO_PIN 11
#define MOTOR_PWM1 5
#define MOTOR_PWM2 6
 
// 多路红外传感器
QTRSensors qtr;
unsigned int sensorValues[NUM_SENSORS];
NewPing sonar(TRIG_PIN, ECHO_PIN, 200);
 
// 状态机定义
enum State { LINE_FOLLOW, OBSTACLE_AVOID, STOP };
State currentState = LINE_FOLLOW;
unsigned long avoidStartTime = 0;
 
void setup() {
  Serial.begin(115200);
  qtr.setTypeAnalog();
  qtr.setSensorPins((const uint8_t[])IR_PINS, NUM_SENSORS);
  pinMode(MOTOR_PWM1, OUTPUT);
  pinMode(MOTOR_PWM2, OUTPUT);
}
 
void loop() {
  static int lastPosition = 0;
  
  // 1. 状态机切换
  switch (currentState) {
    case LINE_FOLLOW:
      // 红外巡线
      lastPosition = qtr.readLineBlack(sensorValues);
      int error = lastPosition - 1500; // 1500为中间值(4传感器)
      
      // 简单比例控制
      int speedLeft = 120 + error * 0.1;
      int speedRight = 120 - error * 0.1;
      setMotorSpeed(speedLeft, speedRight);
 
      // 超声波检测障碍物
      int distance = sonar.ping_cm();
      if (distance > 0 && distance < 25) {
        currentState = OBSTACLE_AVOID;
        avoidStartTime = millis();
      }
      break;
 
    case OBSTACLE_AVOID:
      // 避障动作(持续1秒)
      setMotorSpeed(-100, -100); // 后退
      delay(300);
      setMotorSpeed(150, -150);  // 右转
      delay(200);
      
      // 返回巡线状态
      if (millis() - avoidStartTime > 1000) {
        currentState = LINE_FOLLOW;
      }
      break;
 
    case STOP:
      setMotorSpeed(0, 0);
      break;
  }
}
 
void setMotorSpeed(int left, int right) {
  // BLDC驱动代码(需根据实际驱动模块调整)
  if (left >= 0) {
    analogWrite(MOTOR_PWM1, left);
  } else {
    // 反向控制逻辑(需硬件支持)
  }
  // 同理处理right电机
}

要点解读:

状态机设计:通过enum明确区分巡线和避障状态。
多路红外传感器:使用QTRSensors库提高巡线精度,支持多传感器融合。
动态避障:避障动作完成后自动返回巡线状态。
时间控制:通过millis()实现避障动作的时序控制。

6、复杂环境自适应(巡线+避障+记忆路径)
功能:在巡线过程中动态避障,并记录障碍物位置实现路径记忆。

#include <NewPing.h>
#include <QTRSensors.h>
#include <EEPROM.h> // 用于存储障碍物位置
 
// 硬件定义
#define NUM_SENSORS 6
#define IR_PINS {A0, A1, A2, A3, A4, A5}
#define TRIG_PIN 12
#define ECHO_PIN 11
#define MOTOR_PWM1 5
#define MOTOR_PWM2 6
#define BUZZER 7
 
// 全局变量
QTRSensors qtr;
unsigned int sensorValues[NUM_SENSORS];
NewPing sonar(TRIG_PIN, ECHO_PIN, 200);
bool obstacleDetected = false;
int obstacleMemory[10][2]; // 存储障碍物坐标(简化版)
int obstacleCount = 0;
 
void setup() {
  Serial.begin(115200);
  qtr.setTypeAnalog();
  qtr.setSensorPins((const uint8_t[])IR_PINS, NUM_SENSORS);
  pinMode(MOTOR_PWM1, OUTPUT);
  pinMode(MOTOR_PWM2, OUTPUT);
  pinMode(BUZZER, OUTPUT);
  
  // 从EEPROM加载障碍物记忆(示例)
  // EEPROM.get(0, obstacleMemory);
}
 
void loop() {
  // 1. 巡线控制(PID简化版)
  int position = qtr.readLineBlack(sensorValues);
  int error = position - 2500; // 中间值(6传感器)
  int baseSpeed = 100;
  
  int leftSpeed = baseSpeed + error * 0.05;
  int rightSpeed = baseSpeed - error * 0.05;
 
  // 2. 超声波避障检测
  int distance = sonar.ping_cm();
  if (distance > 0 && distance < 30 && !obstacleDetected) {
    obstacleDetected = true;
    recordObstacle(position, distance); // 记录障碍物位置
    avoidObstacle();
  } else if (distance >= 40) {
    obstacleDetected = false;
  }
 
  // 3. 电机控制
  if (obstacleDetected) {
    setMotorSpeed(0, 0); // 避障时暂停巡线
  } else {
    setMotorSpeed(leftSpeed, rightSpeed);
  }
}
 
void recordObstacle(int linePos, int dist) {
  if (obstacleCount < 10) {
    obstacleMemory[obstacleCount][0] = linePos; // 巡线位置
    obstacleMemory[obstacleCount][1] = dist;    // 障碍物距离
    obstacleCount++;
    
    // 蜂鸣器提示
    digitalWrite(BUZZER, HIGH);
    delay(100);
    digitalWrite(BUZZER, LOW);
  }
}
 
void avoidObstacle() {
  // 高级避障逻辑(示例:根据记忆绕行)
  setMotorSpeed(-80, -80); // 后退
  delay(200);
  
  // 尝试从右侧绕行
  setMotorSpeed(100, -100);
  delay(300);
  
  // 前进一段距离
  setMotorSpeed(120, 120);
  delay(400);
}
 
void setMotorSpeed(int left, int right) {
  // 实际BLDC驱动代码(需适配驱动模块)
  analogWrite(MOTOR_PWM1, constrain(left, 0, 255));
  analogWrite(MOTOR_PWM2, constrain(right, 0, 255));
}

要点解读:

路径记忆:使用数组或EEPROM存储障碍物位置,为后续优化路径提供基础。
多传感器冗余:6路红外传感器提高复杂线路识别能力。
避障策略升级:根据障碍物位置动态选择绕行方向(如优先右侧)。
用户反馈:通过蜂鸣器提示障碍物记录事件。

注意,以上案例只是为了拓展思路,仅供参考。它们可能有错误、不适用或者无法编译。您的硬件平台、使用场景和Arduino版本可能影响使用方法的选择。实际编程时,您要根据自己的硬件配置、使用场景和具体需求进行调整,并多次实际测试。您还要正确连接硬件,了解所用传感器和设备的规范和特性。涉及硬件操作的代码,您要在使用前确认引脚和电平等参数的正确性和安全性。

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

驴友花雕

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值