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,不听话,所以用最简单的小车蓝牙控制)。当然这里的循迹在不碰到障碍物的情况下是成椭圆形轨迹运行的,一避障的话回到原轨迹可能有些困难,避障这块碰到障碍物的运动(先左向右向前向后运动的调和找)也是要优化的。
热门推荐
战争心理学:影响战斗表现的关键因素
动物辅助干预 为人类尽犬马之效
如何讨债最有效的方法
表格excel怎么自动四舍五入
经方应用之栀子厚朴汤医案
美时美刻·中国美术馆名作中的二十四节气——清明
AI技术动激情,智慧体育激发新活力与激情
临展之外│红歌《南泥湾》背后的故事
桃子的功效、作用及正确食用方法
也门三色国旗设计含义分析
江西:春节假期“红色游”持续升温 游客热情点燃别样“红”
高铁列车上能吸电子烟吗?
精选 U 盘恢复软件排名:8 种最佳 USB 恢复工具
交通事故责任该如何判断?
南美洲有多少日本移民?文化融合与移民历史解读
文豪野犬全员角色介绍图(文豪野犬角色全解析:性格揭秘)
多气体成分AI分析5G联网监测方案
夜盲症的治疗方法有哪些?
股票上证50是什么?解析上证50指数的构成
“真浓缩,1颗抵8盖”:年轻人喜欢的洗衣凝珠,香吗?
老年人摔骨折后怎么能恢复的快一点
大腿最爱长这种纹路,怎样做才能消掉?
C++面向对象编程基础:类与对象详解
【明仁与健康】吃对这些食物,帮你远离痴呆
低空经济第一站:无人机飞手人才培养技术详解
飞秒焕晶,点亮视界:安徽爱尔眼科医生家属手术纪实
如何利用生成式AI自动化工作,提升效率
中国茶文化概述
房贷利率调整后月供如何计算?详解等额本息和等额本金两种还款方式
提前还贷潮未平 银行推出“先息后本”新模式 存量房贷怎么还才划算?