// 控制红色LED灯的引脚
int red_led = 11;
// 存储8个红外传感器的读数
volatile int proximity[8];
// 8个红外传感器的引脚
unsigned char analogPin[8] = {A0, A1, A2, A3, A4, A5, A6, A7};
// 左电机PWM控制引脚
int PWM_left = 6;
// 左电机方向控制引脚
int left_dir = 7;
// 右电机PWM控制引脚
int PWM_right = 5;
// 右电机方向控制引脚
int right_dir = 2;
// 小车的基础速度
volatile int base_speed = 12;

// 地面传感器引脚
const int groundSensor1 = 8; 
const int groundSensor2 = 9;
const int groundSensor3 = 10;
const int groundSensor4 = 12;

void setup() {
  // 将红色LED引脚设置为输出模式
  pinMode(red_led, OUTPUT);
  // 设置串口通信的波特率为57600
  Serial.begin(57600);
  // 初始化红外LED
  initIRLED();
  // 设置地面传感器引脚为输入模式
  pinMode(groundSensor1, INPUT);
  pinMode(groundSensor2, INPUT);
  pinMode(groundSensor3, INPUT);
  pinMode(groundSensor4, INPUT);
}

void loop() {
  // 读取左侧红外传感器的距离
  int distanceLeft = readProximityDistance(7);
  // 读取右侧红外传感器的距离
  int distanceRight = readProximityDistance(5);
  // 读取前方红外传感器的距离
  int distanceFront = readProximityDistance(0);

  // 打印传感器距离值,用于调试
  Serial.print('distanceLeft:');
  Serial.println(distanceLeft);
  Serial.print('distanceRight:');
  Serial.println(distanceRight);
  Serial.print('distanceFront:');
  Serial.println(distanceFront);

  // 检查是否检测到黑色地面
  if (detectBlackGround()) {
    // 停止电机
    MotorStop();
  } else if (distanceFront >= 20 && distanceLeft >= 15 && distanceLeft < 20) { 
    // 前方无障碍物,左侧存在墙体,沿左侧墙运动
    leftMotorForward(base_speed + 2);
    rightMotorForward(base_speed);
  } else if (distanceFront < 20 && distanceRight >= 20) {
    // 前方有障碍物,右侧无障碍物,右转
    rightMotorForward(base_speed + 3);
    leftMotorBackward(base_speed);
  } else {
    // 其他情况,停止
    MotorStop();
  }
}

// 检测是否四个地面传感器都检测到黑色
bool detectBlackGround() {
  return (digitalRead(groundSensor1) == LOW) &&
         (digitalRead(groundSensor2) == LOW) &&
         (digitalRead(groundSensor3) == LOW) &&
         (digitalRead(groundSensor4) == LOW);
}

// 初始化红外LED
void initIRLED() {
  // 将8个红外LED引脚设置为输出模式
  DDRA |= B11111111;
  // 将8个红外LED引脚输出低电平
  PORTA &= B00000000;
}

// 打开指定红外LED
void proxLEDon(unsigned char proxIndex) {
  PORTA |= 1 << proxIndex;
}

// 关闭指定红外LED
void proxLEDoff(unsigned char proxIndex) {
  PORTA &= ~(1 << proxIndex);
}

// 读取指定红外传感器的距离
int readProximityDistance(unsigned char proxIndex) {
  int distance;
  // 打开指定红外LED
  proxLEDon(proxIndex);
  // 等待1毫秒,让红外LED发射出充足的红外线
  delay(1);
  // 读取红外传感器的模拟值
  proximity[proxIndex] = analogRead(analogPin[proxIndex]);
  // 将模拟值转换为距离值
  distance = 3.425 * pow(2.7182, 0.0026 * proximity[proxIndex]);
  // 关闭指定红外LED
  proxLEDoff(proxIndex);
  return distance;
}

// 停止电机运动
void MotorStop() {
  // 右电机方向引脚输出高电平
  digitalWrite(right_dir, HIGH);
  // 右电机PWM引脚输出高电平
  digitalWrite(PWM_right, HIGH);
  // 左电机方向引脚输出高电平
  digitalWrite(left_dir, HIGH);
  // 左电机PWM引脚输出高电平
  digitalWrite(PWM_left, HIGH);
}

// 左电机正转
void leftMotorForward(float duty) {
  // 将0-100的速度值映射到0-100的PWM值
  int dutyVal = map(duty, 0, 100, 0, 100);
  // 左电机PWM引脚输出PWM值
  analogWrite(PWM_left, dutyVal);
  // 左电机方向引脚输出低电平
  analogWrite(left_dir, 0);
}

// 右电机正转
void rightMotorForward(float duty) {
  // 将0-100的速度值映射到0-100的PWM值
  int dutyVal = map(duty, 0, 100, 0, 100);
  // 右电机PWM引脚输出PWM值
  analogWrite(PWM_right, dutyVal);
  // 右电机方向引脚输出低电平
  analogWrite(right_dir, 0);
}

// 左电机反转
void leftMotorBackward(float duty) {
  // 将0-100的速度值映射到0-80的PWM值
  int dutyVal = map(duty, 0, 100, 0, 80);
  // 左电机PWM引脚输出低电平
  analogWrite(PWM_left, 0);
  // 左电机方向引脚输出PWM值
  analogWrite(left_dir, dutyVal);
}

// 右电机反转
void rightMotorBackward(float duty) {
  // 将0-100的速度值映射到0-80的PWM值
  int dutyVal = map(duty, 0, 100, 0, 80);
  // 右电机PWM引脚输出低电平
  analogWrite(PWM_right, 0);
  // 右电机方向引脚输出PWM值
  analogWrite(right_dir, dutyVal);
}
Arduino循墙避障小车:使用红外传感器实现自主导航

原文地址: https://www.cveoy.top/t/topic/jpUi 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录