admin 发表于 2025-12-25 22:40

Arduino超声波红外传感器避障智能小车代码



int Echo = A0;// Echo回声脚(P2.0)
int Trig = A1;// Trig 触发脚(P2.1)

// 红外避障传感器引脚定义
int IR_left = 2;    // 左侧红外传感器(检测到障碍物时输出LOW)
int IR_right = 3;   // 右侧红外传感器(检测到障碍物时输出LOW)

int F_Distance = 0;
int L_Distance = 0;
int R_Distance = 0;

int L_motor_back = 5;   //左电机后退(IN1)
int L_motor_go = 6;       //左电机前进(IN2)

int R_motor_go = 9;       //右电机前进(IN3)
int R_motor_back = 10;    //右电机后退(IN4)

int servopin = 12;      //设置舵机驱动脚到数字口12
int angle;                //定义角度变量
int pulsewidth;         //定义脉宽变量
int val;

// 红外避障相关变量
bool left_obstacle = false;
bool right_obstacle = false;
bool use_ultrasonic = true;// 是否启用超声波避障
int avoid_delay = 300;       // 避障动作持续时间(ms)

void setup()
{
Serial.begin(9600);   // 初始化串口

// 初始化电机驱动IO为输出方式
pinMode(L_motor_go, OUTPUT);    // PIN 5 (PWM)
pinMode(L_motor_back, OUTPUT);// PIN 6 (PWM)
pinMode(R_motor_go, OUTPUT);    // PIN 9 (PWM)
pinMode(R_motor_back, OUTPUT);// PIN 10 (PWM)

// 初始化超声波引脚
pinMode(Echo, INPUT);   // 定义超声波输入脚
pinMode(Trig, OUTPUT);    // 定义超声波输出脚

// 初始化红外传感器引脚
pinMode(IR_left, INPUT_PULLUP);   // 使用内部上拉电阻
pinMode(IR_right, INPUT_PULLUP);// 使用内部上拉电阻

// LCD初始化(如果使用LCD)
// lcd.begin(16,2);      //初始化1602液晶工作模式
// 定义1602液晶显示范围为2行16列字符

pinMode(servopin, OUTPUT);//设定舵机接口为输出接口

Serial.println("System Initialized - Ultrasonic + IR Obstacle Avoidance");
}

//=======================智能小车的基本动作=========================
void run()   // 前进
{
analogWrite(R_motor_go, 90);    //右电机前进
analogWrite(R_motor_back, 0);
analogWrite(L_motor_go, 99);    //左电机前进
analogWrite(L_motor_back, 0);
}

void brake()   //刹车,停车
{
digitalWrite(R_motor_go, LOW);
digitalWrite(R_motor_back, LOW);
digitalWrite(L_motor_go, LOW);
digitalWrite(L_motor_back, LOW);
}

void left()    //左转(左轮不动,右轮前进)
{
analogWrite(R_motor_go, 100);   //右电机前进
analogWrite(R_motor_back, 0);
digitalWrite(L_motor_go, LOW);//左轮不动
digitalWrite(L_motor_back, LOW);
}

void spin_left()//左转(左轮后退,右轮前进)
{
analogWrite(R_motor_go, 100);   //右电机前进
analogWrite(R_motor_back, 0);
analogWrite(L_motor_go, 0);
analogWrite(L_motor_back, 100); //左轮后退
}

void right()   //右转(右轮不动,左轮前进)
{
digitalWrite(R_motor_go, LOW);    //右电机不动
digitalWrite(R_motor_back, LOW);
analogWrite(L_motor_go, 100);   //左电机前进
analogWrite(L_motor_back, 0);
}

void spin_right()//右转(右轮后退,左轮前进)
{
analogWrite(R_motor_go, 0);
analogWrite(R_motor_back, 100);   //右电机后退
analogWrite(L_motor_go, 100);   //左电机前进
analogWrite(L_motor_back, 0);
}

void back()    //后退
{
analogWrite(R_motor_go, 0);
analogWrite(R_motor_back, 100);   //右轮后退
analogWrite(L_motor_go, 0);
analogWrite(L_motor_back, 100);   //左轮后退
}
//==========================================================

// 超声波距离测量函数
float Distance_test()
{
digitalWrite(Trig, LOW);
delayMicroseconds(2);
digitalWrite(Trig, HIGH);
delayMicroseconds(10);
digitalWrite(Trig, LOW);

float Fdistance = pulseIn(Echo, HIGH);
Fdistance = Fdistance / 58;
return Fdistance;
}

// 红外传感器检测函数
void IR_Detection()
{
// 读取红外传感器状态(假设LOW表示检测到障碍物)
left_obstacle = (digitalRead(IR_left) == LOW);
right_obstacle = (digitalRead(IR_right) == LOW);

// 可选:串口输出红外传感器状态
Serial.print("IR Left: ");
Serial.print(left_obstacle ? "OBSTACLE" : "CLEAR");
Serial.print(" | IR Right: ");
Serial.println(right_obstacle ? "OBSTACLE" : "CLEAR");
}

// 红外避障决策函数
void IR_Avoidance()
{
IR_Detection();// 检测红外传感器

if (left_obstacle && right_obstacle) {
    // 两侧都有障碍物,后退然后随机转向
    Serial.println("Both sides blocked - Back and turn right");
    back();
    delay(200);
    brake();
    delay(100);
    spin_right();
    delay(400);
    brake();
}
else if (left_obstacle) {
    // 左侧有障碍物,右转
    Serial.println("Left obstacle - Turn right");
    back();
    delay(150);
    brake();
    delay(100);
    right();
    delay(avoid_delay);
    brake();
}
else if (right_obstacle) {
    // 右侧有障碍物,左转
    Serial.println("Right obstacle - Turn left");
    back();
    delay(150);
    brake();
    delay(100);
    left();
    delay(avoid_delay);
    brake();
}
// 无障碍物时不执行动作
}

// 超声波避障决策函数(原逻辑)
void Ultrasonic_Avoidance()
{
front_detection();// 测量前方距离

if (F_Distance < 32)// 当遇到障碍物时
{
    Serial.print("Front obstacle detected: ");
    Serial.print(F_Distance);
    Serial.println(" cm");

    back();   // 后退减速
    delay(200);
    brake();    // 停下来做测距

    left_detection();   // 测量左边距障碍物距离
    right_detection();// 测量右边距障碍物距离

    // Distance_display(L_Distance);// 如果需要显示距离
    // Distance_display(R_Distance);

    if ((L_Distance < 35) && (R_Distance < 35)) {
      // 当左右两侧均有障碍物靠得比较近
      Serial.println("Both sides too close - Spin left");
      spin_left();
      delay(100);
    }
    else if (L_Distance > R_Distance) {
      // 左边比右边空旷
      Serial.println("Left clearer - Turn left");
      left();
      delay(300);
      brake();
    }
    else {
      // 右边比左边空旷
      Serial.println("Right clearer - Turn right");
      right();
      delay(300);
      brake();
    }
}
else {
    // 无障碍物,直行
    run();
}
}

// 舵机控制函数
void servopulse(int servopin, int angle)
{
pulsewidth = (angle * 11) + 500;// 将角度转化为500-2480的脉宽值
digitalWrite(servopin, HIGH);
delayMicroseconds(pulsewidth);
digitalWrite(servopin, LOW);
delay(20 - pulsewidth / 1000);
}

void front_detection()
{
for (int i = 0; i <= 5; i++) {
    servopulse(servopin, 90);
}
F_Distance = Distance_test();
Serial.print("Front Distance: ");
Serial.println(F_Distance);
}

void left_detection()
{
for (int i = 0; i <= 15; i++) {
    servopulse(servopin, 175);
}
L_Distance = Distance_test();
Serial.print("Left Distance: ");
Serial.println(L_Distance);
}

void right_detection()
{
for (int i = 0; i <= 15; i++) {
    servopulse(servopin, 5);
}
R_Distance = Distance_test();
Serial.print("Right Distance: ");
Serial.println(R_Distance);
}

// 综合避障主循环
void loop()
{
while (1)
{
    // 首先进行红外避障检测(近距离优先)
    IR_Detection();

    if (left_obstacle || right_obstacle) {
      // 红外检测到障碍物,执行红外避障
      IR_Avoidance();
    }
    else {
      // 红外没有检测到障碍物,执行超声波避障
      Ultrasonic_Avoidance();
    }

    // 可选:添加短暂延迟,避免过于频繁的检测
    delay(50);
}
}

// 可选:LCD显示函数(如果使用LCD)
void Distance_display(int Distance)
{
/*
if ((2 < Distance) && (Distance < 400))
{
    lcd.home();
    lcd.print("    Distance: ");
    lcd.setCursor(6, 2);
    lcd.print(Distance);
    lcd.print("cm");
}
else
{
    lcd.home();
    lcd.print("!!! Out of range");
}
delay(250);
lcd.clear();
*/
}

页: [1]
查看完整版本: Arduino超声波红外传感器避障智能小车代码