Arduino 蓝牙循迹避障三轮小车制作教程
创作时间:
作者:
@小白创作中心
Arduino 蓝牙循迹避障三轮小车制作教程
引用
CSDN
1.
https://m.blog.csdn.net/2301_79907302/article/details/136634518
本文将详细介绍如何制作一个基于Arduino的蓝牙循迹避障三轮小车。通过本教程,你将学习到硬件连接、代码编写以及如何实现蓝牙控制、循迹和避障功能。
一.器材准备
- Arduino Uno 开发板
- L298N驱动模块
- HC-05蓝牙模块
- SG90舵机
- 超声波模块
- 两个红外线传感器模块
- 两个直流减速电机+两个车轮 + 小车底板
- 小型面包板
二.硬件连接
- Arduino Uno 板与L298N驱动模块的连接:
- 直流减速电机的连接:in1和in2分别接电机正极(红)和负极(黑),in3 和in4分别接电机正极和负极。
- 使用支持PWM调速的引脚5, 6, 9,10。
- 电池使用12V大容量锂电池,注意连接方式。
- HC-05蓝牙模块与Arduino Uno的连接
- VCC接板上的5v电压,GND接在板上的GND上,TXD接在板上的RXD引脚上,RXD接在板上TXD引脚上(这里必须反着接)。
- 舵机与超声波模块以及Arduino Uno板的连接
- 舵机棕线接板上的GND,红线接5v,黄线接引脚11。
- 超声波模块的Echo接在引脚A2上,Trig接在引脚A3上。
- 两个红外线传感器模块与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,不听话,所以用最简单的小车蓝牙控制)。当然这里的循迹在不碰到障碍物的情况下是成椭圆形轨迹运行的,一避障的话回到原轨迹可能有些困难,避障这块碰到障碍物的运动(先左向右向前向后运动的调和找)也是要优化的。
热门推荐
如何透过富时A50指数期货观察A股市场?
“洛阳纸贵”,造纸与印刷,中国古代出版行业的兴起与发展
如何高效利用 AI 工具提升开发效率?
【数据分析】2025年1月非农就业数据点评
公务员与事业编的职业前景比较:33岁是否晚于考公务员的黄金年龄?
希腊神话中的审判神:雅典娜
医疗事故证据收集与索赔指南
从著名品牌重塑失败案例中吸取教训
Raspberry Pi 5:硬件规格、电源管理和散热方案详解
贷款记录存在逾期未还:对公务员资格的影响与解决方案全面解析
高效合成酯类化合物:探秘酯化反应的关键条件
2025年,聚焦固态电池:多家车企宣布固态电池上车!
伺服电机转矩、功率、转速之间的关系
新进展!深圳将规划独立非机动车道
电动自行车管理新举措,深圳三年内100%覆盖非机动车道
团队素质如何全面提升
医学减重常用的6种减重饮食模式,你用过几个?
肺与脾的关系
浏阳烟花成功出圈:科技与情感的完美交融
项目管理通报单位内部怎么写
诱发偏头痛的原因是什么
偏头疼吃什么药效果好?偏头痛的药物治疗全解析
强基计划相当于降多少分?附各大学2024年本科批、强基计划最低分
如何查看临床文献数据库
如何选择最佳清洁方法?清洁方法的确认方案告诉你!
洗涤剂成分解析:科学选择家庭清洁用品
Query 改写综述:提升信息检索效率与准确性的关键技术
如何保证阅读和引用的文章的可信度?
发现:5 种你从未听说过的非洲猫
信创国产系统对国产芯片产业的推动作用