聚升科技

 找回密码
 立即注册
搜索
精品 学习强国

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

[复制链接]
admin 发表于 2025-12-25 22:40 | 显示全部楼层 | LAN
微信图片_20251225224203_副本.jpg

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();
  */
}

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

微信:420080246|手机版|聚升科技

GMT+8, 2026-3-7 15:06

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表