问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

Arduino 蓝牙循迹避障三轮小车制作教程

创作时间:
作者:
@小白创作中心

Arduino 蓝牙循迹避障三轮小车制作教程

引用
CSDN
1.
https://m.blog.csdn.net/2301_79907302/article/details/136634518

本文将详细介绍如何制作一个基于Arduino的蓝牙循迹避障三轮小车。通过本教程,你将学习到硬件连接、代码编写以及如何实现蓝牙控制、循迹和避障功能。

一.器材准备

  1. Arduino Uno 开发板
  2. L298N驱动模块
  3. HC-05蓝牙模块
  4. SG90舵机
  5. 超声波模块
  6. 两个红外线传感器模块
  7. 两个直流减速电机+两个车轮 + 小车底板
  8. 小型面包板

二.硬件连接

  1. Arduino Uno 板与L298N驱动模块的连接:
  • 直流减速电机的连接:in1和in2分别接电机正极(红)和负极(黑),in3 和in4分别接电机正极和负极。
  • 使用支持PWM调速的引脚5, 6, 9,10。
  • 电池使用12V大容量锂电池,注意连接方式。
  1. HC-05蓝牙模块与Arduino Uno的连接
  • VCC接板上的5v电压,GND接在板上的GND上,TXD接在板上的RXD引脚上,RXD接在板上TXD引脚上(这里必须反着接)。
  1. 舵机与超声波模块以及Arduino Uno板的连接
  • 舵机棕线接板上的GND,红线接5v,黄线接引脚11。
  • 超声波模块的Echo接在引脚A2上,Trig接在引脚A3上。
  1. 两个红外线传感器模块与Arduino Uno板的连接:
  • 正极接5v,GND接地,另外两个分别接引脚A0和A1。

最后,需要使用面包板将多个设备连接起来共用5v和GND引脚。

三.代码实现

#include<SoftwareSerial.h> // 蓝牙连接  
#include <Servo.h> //声明调用Servo.h库  

#define in1 5 //电机的四个引脚连接  
#define in2 6  
#define in3 9  
#define in4 10  
#define L_S A0//左边的红外线传感器  
#define R_S A1 //右边的红外线传感器  
#define echo A2//超声波的Echo  
#define trigger A3//超声波的Trig  
int servo = 11; //具有PWM调速功能的数字引脚上  
int Set = 15; //用于红外线传感的15界限  
int speed = 60; //限制电机速度  
char xuan;  
int distance_L,distance_F, distance_R; //用于超声波以及红外线传感器的三个距离  

void setup()  
{  
  Serial.begin(9600);//波特率定为9600  
  pinMode(R_S, INPUT);  
  pinMode(L_S, INPUT);//两个红外线传感器  
  pinMode(echo, INPUT);  
  pinMode(trigger, OUTPUT);//超声波的两个接口  
  pinMode(in1, OUTPUT);  
  pinMode(in2, OUTPUT);  
  pinMode(in3, OUTPUT);  
  pinMode(in4, OUTPUT);  
  Serial.println("蓝牙连接正常");  
  pinMode(servo, OUTPUT);  
  distance_F = Ultrasonic_read(); //超声波测距  
  delay(500);  
}  

void loop()  
{  
  if(Serial.available() > 0) //蓝牙识别字符  
  {  
    xuan = Serial.read(); //蓝牙读取字符  
    if(xuan == 'A'){  
      forward();  
      Serial.println("向前运动");  
    }//调取前进函数  
    else if(xuan == 'B'){  
      backword();  
      Serial.println("向后运动。");  
    }//调取后退函数  
    else if(xuan == 'C'){  
      trunRight();  
      Serial.println("向右运动");  
    }//调取左转函数  
    else if(xuan == 'D'){  
      trunLeft();  
      Serial.println("向左运动");  
    }//调取右转函数  
    else if(xuan == 'E'){  
      Stop();  
      Serial.println("停止运动");  
    }//调取停止函数  
    else if(xuan == 'X')  
    {  
      delay(1000);  
      distance_F = Ultrasonic_read();  
      Serial.println("超声波测障完成。");  
      Serial.print("D F=");  
      Serial.println(distance_F);  
      Serial.println("红外线测障完成!");  
      if((digitalRead(R_S) == 0) && (digitalRead(L_S) == 0))  
      {  
        if(distance_F > Set)  
        {  
          forward();  
        }  
        else  
        {  
          check_side();  
          for(int i = 0; i < 90; i++)  
          {  
            servoPulse(servo, i);  
          }  
        }  
      }  
      else if((digitalRead(R_S) == 1) && (digitalRead(L_S) == 0))  
      {  
        trunRight();  
      }  
      else if((digitalRead(R_S) == 0) && (digitalRead(L_S) == 1))  
      {  
        trunLeft();  
      }  
      delay(10);  
    }  
  }  
}  

void servoPulse(int pin, int angle) //舵机  
{  
  int pwm = (angle * 11) + 500;  
  digitalWrite(pin, HIGH);  
  delayMicroseconds(pwm);  
  digitalWrite(pin, LOW);  
  delay(50);  
}  

long Ultrasonic_read()  
{ //超声波  
  digitalWrite(trigger, LOW);  
  delayMicroseconds(2);  
  digitalWrite(trigger, HIGH);  
  delayMicroseconds(10);  
  long time = pulseIn(echo, HIGH);  
  return time / 29 / 2;  
}  

void compareDistance()  
{ //红外线传感器  
  if(distance_L > distance_R)  
  {  
    trunLeft();  
    delay(500);  
    forward();  
    delay(600);  
    trunRight();  
    delay(500);  
    forward();  
    delay(600);  
    trunRight();  
    delay(400);  
    forward();  
    delay(400);  
  }  
  else  
  {  
    trunRight();  
    delay(500);  
    forward();  
    delay(600);  
    trunLeft();  
    delay(500);  
    forward();  
    delay(600);  
    trunLeft();  
    delay(400);  
    forward();  
    delay(400);  
  }  
}  

void check_side()  
{ //红外线传感器  
  Stop();  
  delay(100);  
  for(int angle = 70; angle <= 140; angle += 5)  
  {  
    servoPulse(servo, angle);  
  }  
  delay(300);  
  distance_R = Ultrasonic_read();  
  Serial.print("D R=");  
  Serial.println(distance_R);  
  Serial.println("检查完毕!");  
  delay(100);  
  for(int angle = 140; angle >= 0; angle -= 5)  
  {  
    servoPulse(servo, angle);  
  }  
  delay(500);  
  distance_L = Ultrasonic_read();  
  Serial.print("D L=");  
  Serial.println(distance_L);  
  Serial.println("检查好了!");  
  delay(100);  
  for(int angle = 0; angle <= 70; angle += 5)  
  {  
    servoPulse(servo, angle);  
  }  
  Serial.println("左右旋转检查完成!");  
  delay(300);  
  compareDistance();  
}  

void trunRight()//左trunLeft  
{  
  digitalWrite(in1,HIGH); //给高电平  
  digitalWrite(in2,LOW); //给低电平  
  analogWrite(in1, speed);  
  digitalWrite(in3,HIGH);  
  analogWrite(in3, speed);//给高电平  
  digitalWrite(in4,LOW); //给低电平  
}  

void trunLeft() //向右trunRight  
{  
  digitalWrite(in1,LOW); //给低电平  
  analogWrite(in2, speed);  
  digitalWrite(in3,LOW); //给低电平  
  analogWrite(in4, speed);  
}  

void forward() //是前 forward  
{  
  digitalWrite(in2,LOW); //给低电平  
  analogWrite(in1, speed);  
  digitalWrite(in3,LOW);  
  analogWrite(in4, speed);  
}  

void backword() //是后 backword  
{  
  digitalWrite(in1,LOW); //给低电平  
  digitalWrite(in2,HIGH); //给高电平  
  analogWrite(in2, speed);  
  digitalWrite(in3,HIGH); //给高电平  
  digitalWrite(in4,LOW); //给低电平  
  analogWrite(in3, speed);  
  delay(50);  
}  

void Stop()  
{  
  digitalWrite(in1, LOW);  
  digitalWrite(in2, LOW);  
  digitalWrite(in3, LOW);  
  digitalWrite(in4, LOW);  
}  

值得注意的是,这里的小车前后左右运行的代码仅对我所接的线来说,其中调速部分左转和向后代码有必要的化可以去掉某些部分(电机前后左右的调速是我一遍遍试出来的代码,可能有更好的,但这个代码小车刚好都能调好速)。另外关于避障模块由于我这个蓝牙控制一次只能执行一次避障,所以你要是想一直避障就得执行完一次后再按按钮(这里是手机控制,用的是名为蓝牙调试器的手机软件)也许可以通过循环来能实现连续避障,但这里面的代码涉及的逻辑和东西可能比较复杂(我写的小车运行时有很多bug,不听话,所以用最简单的小车蓝牙控制)。当然这里的循迹在不碰到障碍物的情况下是成椭圆形轨迹运行的,一避障的话回到原轨迹可能有些困难,避障这块碰到障碍物的运动(先左向右向前向后运动的调和找)也是要优化的。

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号