基于Arduino UNO的智能摇头避障小车

前言

有需要帮忙代做Arduino,51和32小车或者其他单片机项目,课程设计,报告,PCB原理图的小伙伴,可以在文章最下方加我V交流咨询!!!

目录

1.首先介绍两个基本函数

2.L298N控制逻辑

3.让小车实现前后左右轮子动代码示例

4.串口介绍

5.跟随小车开发

6.摇头避障小车开发

7.实物展示


1.首先介绍两个基本函数

void setup() { 
// put your setup code here, to run once: 把你的设置代码放在这里,运行一次
}
void loop() {
// put your main code here, to run repeatedly: 把你的主代码放在这里,重复运行
}

2.L298N控制逻辑

根据我们的接线:

左电机由引脚2,3控制,右电机由4,5控制。正反转导致前进后退需要根据输出端子那边的电机接线实际验证 测试。

接线说明:

左电机安装朝向是接杜邦线的那侧朝外(朝轮子) 左轮上,接左端子的OUT2口, 左轮下,接左端子的OUT1口, IN1由2控制,IN2为3控制 右电机安装朝向是接杜邦线的那侧朝内(背对轮子) 右轮上,接右端子的OUT3口, 右轮下,接右端子的OUT4口, IN3由4控制,IN4为5控制

3.让小车实现前后左右轮子动代码示例:

void setup() {
    // put your setup code here, to run once:
    //左轮信号方向初始化
    pinMode(2,OUTPUT);// 配置2口为输出引脚
    pinMode(3,OUTPUT);// 配置3口为输出引脚
    //右轮信号方向初始化
    pinMode(4,OUTPUT);// 配置4口为输出引脚
    pinMode(5,OUTPUT);// 配置5口为输出引脚
}
void loop() {
    // put your main code here, to run repeatedly:
    //小车前进
    digitalWrite(2,LOW);
    digitalWrite(3,HIGH);
    digitalWrite(4,HIGH);
    digitalWrite(5,LOW);
    delay(1000);
    //小车后退
    digitalWrite(2,HIGH);
    digitalWrite(3,LOW);
    digitalWrite(4,LOW);
    digitalWrite(5,HIGH);
    delay(1000);
    //小车左转,右轮前,左轮后
    digitalWrite(2,HIGH);
    digitalWrite(3,LOW);
    digitalWrite(4,HIGH);
    digitalWrite(5,LOW);
    delay(1000);
    //小车右转,左轮前,右轮后
    digitalWrite(2,LOW);
    digitalWrite(3,HIGH);
    digitalWrite(4,LOW);
    digitalWrite(5,HIGH);
    delay(1000);
}
 可以用函数封装,代码示例:
void qianJin() {
	// 小车前进的功能
	digitalWrite(2,LOW);
	digitalWrite(3,HIGH);
	digitalWrite(4,HIGH);
	digitalWrite(5,LOW);
}

void houTui() {//函数的封装
	// 小车后退的功能
	digitalWrite(2,HIGH);
	digitalWrite(3,LOW);
	digitalWrite(4,LOW);
	digitalWrite(5,HIGH);
}

void zuoZhuan(){
	digitalWrite(2,HIGH);
	digitalWrite(3,LOW);
	digitalWrite(4,HIGH);
	digitalWrite(5,LOW);
}

void youZhuan(){
	digitalWrite(2,LOW);
	digitalWrite(3,HIGH);
	digitalWrite(4,LOW);
	digitalWrite(5,HIGH);
}

void carInit()
{
	// put your setup code here, to run once:
	pinMode(2,OUTPUT);// 配置2口为输出引脚
	pinMode(3,OUTPUT);// 配置3口为输出引脚
	//右轮信号方向初始化
	pinMode(4,OUTPUT);// 配置4口为输出引脚
	pinMode(5,OUTPUT);// 配置5口为输出引脚
}

void setup() {
	carInit();
}

void loop() {
	qianJin();//函数的调用
	delay(1000);
	houTui();
	delay(1000);
	zuoZhuan();
	delay(1000);
	youZhuan();
	delay(1000);
}

4.串口介绍

我们把程序通过电脑下载到WemosD1上的时候,就是通过串口通信

在程序中,我们也可以通过函数调用实现串口通信

串口的初始化函数:

描述:开启串口,通常置于setup()函数中。 Serial.begin(speed)

参数: speed:波特率,一般取值9600,115200等。

ArduinoUno通过串口发送一个消息给电脑

Serial.print(“test message,这里是消息,喜欢发什么消息,就写什么消息”)

Serial.println(“test message,这里是消息,喜欢发什么消息,就写什么消息”), 比上面多了ln,代表换行

代码示例:

​
void setup() {
    // put your setup code here, to run once:
    Serial.begin(115200);
}

void loop() {
    // put your main code here, to run repeatedly:
    Serial.print("zglnb");
    Serial.println("zglnb");
}

​

打开测试

5.跟随小车开发

主要用到超声波模块,型号:HC-SR04

 原理图:

超声波代码通过串口测验:

void setup() {
	// put your setup code here, to run once:
	// Trig 接 9,通过9发送一个触发信号给超声波
	pinMode(9,OUTPUT);
	// Echo 接 8,通过读取8高电平维持的时间,确认超声波在空气中传播的时间
	pinMode(8,INPUT);
	Serial.begin(9600);
}

void loop() {
	long shijian;
	long juli;
	// put your main code here, to run repeatedly:
	// 发送一个10us的信号给超声波,9Trig
	digitalWrite(9, LOW);
	delayMicroseconds(2);
	digitalWrite(9, HIGH);
	delayMicroseconds(10);
	digitalWrite(9, LOW);//超声波内部开始震荡,准备发送波
	// 关注Echo高电平维持的时间,代表超声波发送到返回的时间,微秒
	shijian = pulseIn(8,HIGH);
	// 距离(cm) = 时间(s) * 速度340m/s 34000cm/s = cm
	juli = shijian * 0.017;
	Serial.print(juli);
	Serial.println("cm");
}

//封装测距代码
//函数:名 参数 返回值
long getDis() {
	// 测距函数
	long shijian;
	long juli;
	// put your main code here, to run repeatedly:
	// 发送一个10us的信号给超声波,9Trig
	digitalWrite(9, LOW);
	delayMicroseconds(2);
	digitalWrite(9, HIGH);
	delayMicroseconds(10);
	digitalWrite(9, LOW);//超声波内部开始震荡,准备发送波
	// 关注Echo高电平维持的时间,代表超声波发送到返回的时间,微秒
	shijian = pulseIn(8,HIGH);
	// 距离(cm) = 时间(s) * 速度340m/s 34000cm/s = cm
	juli = shijian * 0.017;
	return juli;
}

void setup() {
	// put your setup code here, to run once:
	// put your setup code here, to run once:
	// Trig 接 9,通过9发送一个触发信号给超声波
	pinMode(9,OUTPUT);
	// Echo 接 8,通过读取8高电平维持的时间,确认超声波在空气中传播的时间
	pinMode(8,INPUT);
	Serial.begin(9600);
}

void loop() {
	// put your main code here, to run repeatedly:
	long juli;
	juli = getDis();
	Serial.print(juli);
	Serial.println("cm");
}

 跟随小车代码:

//前进
void qianJin() {
	// 小车前进的功能
	digitalWrite(2,LOW);
	digitalWrite(3,HIGH);
	digitalWrite(4,HIGH);
	digitalWrite(5,LOW);
}

//后退
void houTui() {//函数的封装
	// 小车后退的功能
	digitalWrite(2,HIGH);
	digitalWrite(3,LOW);
	digitalWrite(4,LOW);
	digitalWrite(5,HIGH);
}

//ting
void ting() {//函数的封装
	// 小车后退的功能
	digitalWrite(2,LOW);
	digitalWrite(3,LOW);
	digitalWrite(4,LOW);
	digitalWrite(5,LOW);
}

//测距
//函数:名 参数 返回值
long getDis() {
	// 测距函数
	long shijian;
	long juli;
	// put your main code here, to run repeatedly:
	// 发送一个10us的信号给超声波,9Trig
	digitalWrite(9, LOW);
	delayMicroseconds(2);
	digitalWrite(9, HIGH);
	delayMicroseconds(10);
	digitalWrite(9, LOW);//超声波内部开始震荡,准备发送波
	// 关注Echo高电平维持的时间,代表超声波发送到返回的时间,微秒
	shijian = pulseIn(8,HIGH);
	// 距离(cm) = 时间(s) * 速度340m/s 34000cm/s = cm
	juli = shijian * 0.017;
	return juli;
}

void carInit()
{
	// put your setup code here, to run once:
	pinMode(2,OUTPUT);// 配置2口为输出引脚
	pinMode(3,OUTPUT);// 配置3口为输出引脚
	//右轮信号方向初始化
	pinMode(4,OUTPUT);// 配置4口为输出引脚
	pinMode(5,OUTPUT);// 配置5口为输出引脚
}

void setup() {
	// put your setup code here, to run once:
	carInit();
	// Trig 接 9,通过9发送一个触发信号给超声波
	pinMode(9,OUTPUT);
	// Echo 接 8,通过读取8高电平维持的时间,确认超声波在空气中传播的时间

	pinMode(8,INPUT);
}

void loop() {
	// put your main code here, to run repeatedly:
	delay(50);//为了放缓超声波交互的速度,交互过快,得出距离后会卡顿,影响效果体验
	long juli;
	juli = getDis();
	
	//如果距离大于3且小于13,后退
	if( 3 < juli && juli < 15){
		houTui();
	}
	
	//如果距离大于14且小于40,前进
	if( 14 < juli && juli < 40){
		qianJin();
	}
	
	if(juli > 50){
		ting();
	}
}

6.摇头避障小车开发

需要舵机模块

 如下图所示,最便宜的舵机sg90,常用三根或者四根接线,黄色为PWM信号控制用处:垃圾桶项目开盖 用、智能小车的全比例转向、摄像头云台、机械臂等 常见的有0-90°、0-180°、0-360°

Arduino官方提供Servo类来支持舵机操作

//舵机的初始化
Servo myServo; //定义一个Servo变量
myServo.attach(10);//把舵机黄色信号线插在arduino的引脚10
myServo.write(0);//转到某角度,根据实际执行观看
myServo.write(90);//转到某角度,根据实际执行观看

摇头避障小车代码:

#include <Servo.h>

Servo myServo;//因为很多子函数要用这个变量,所以把servo定义成全局变量,作用域是整个代码文件

void ting() {
	// 小车前进的功能
	digitalWrite(2, LOW);
	digitalWrite(3, LOW);
	digitalWrite(4, LOW);
	digitalWrite(5, LOW);
}

void qianJin() {
	// 小车前进的功能
	digitalWrite(2, LOW);
	digitalWrite(3, HIGH);
	digitalWrite(4, HIGH);
	digitalWrite(5, LOW);
}

void houTui() {//函数的封装
	// 小车后退的功能
	digitalWrite(2, HIGH);
	digitalWrite(3, LOW);
	digitalWrite(4, LOW);
	digitalWrite(5, HIGH);
}

void zuoZhuan() {
	digitalWrite(2, HIGH);
	digitalWrite(3, LOW);
	digitalWrite(4, HIGH);
	digitalWrite(5, LOW);
}
void youZhuan() {
	digitalWrite(2, LOW);
	digitalWrite(3, HIGH);
	digitalWrite(4, LOW);
	digitalWrite(5, HIGH);
}

void carInit()
{
	// put your setup code here, to run once:
	pinMode(2, OUTPUT); // 配置2口为输出引脚
	pinMode(3, OUTPUT); // 配置3口为输出引脚
	//右轮信号方向初始化
	pinMode(4, OUTPUT); // 配置4口为输出引脚
	pinMode(5, OUTPUT); // 配置5口为输出引脚
}

long getDis() {
	// 测距函数
	long shijian;
	long juli;
	// put your main code here, to run repeatedly:
	// 发送一个10us的信号给超声波,9Trig
	digitalWrite(9, LOW);
	delayMicroseconds(2);
	digitalWrite(9, HIGH);
	delayMicroseconds(10);
	digitalWrite(9, LOW);//超声波内部开始震荡,准备发送波
	// 关注Echo高电平维持的时间,代表超声波发送到返回的时间,微秒
	shijian = pulseIn(8, HIGH);
	// 距离(cm) = 时间(s) * 速度340m/s 34000cm/s = cm
	juli = shijian * 0.017;
	return juli;
}

void setup() {
	// put your setup code here, to run once:
	//定义一个Servo变量
	carInit();
	myServo.attach(10);//把舵机黄色信号线插在arduino的引脚10
	// Trig 接 9,通过9发送一个触发信号给超声波
	pinMode(9, OUTPUT);
	// Echo 接 8,通过读取8高电平维持的时间,确认超声波在空气中传播的时间
	pinMode(8, INPUT);
	Serial.begin(9600);
}

void loop() {
	long youjuli;
	long zhongjuli;
	long zuojuli;
	
	//如果前面没有障碍物,我让小车往前走
	myServo.write(100);//中间方向
	delay(500);
	zhongjuli = getDis();
	Serial.print("中间距离是:");
	Serial.println(zhongjuli);
	
	if (zhongjuli < 35) {
		ting();//检测到前方右障碍物
		
		//往右边摇头,并测距
		myServo.write(30);//右方向
		delay(500);
		youjuli = getDis();
		Serial.print("右边距离是:");
		Serial.println(youjuli);
		myServo.write(100);//测完右边距离,再回到中间,此时可以不测距
		delay(500);
		
		//往左边摇头,测左边距离
		myServo.write(170);//左边方向
		delay(500);
		zuojuli = getDis();
		Serial.print("左边距离是:");
		Serial.println(zuojuli);
		myServo.write(100);//测完右边距离,再回到中间,此时可以不测距
		delay(500);
		
		if(zuojuli > youjuli) {
			Serial.println("左转");
			zuoZhuan();
			delay(100);
			ting();
		}
		
		if(zuojuli < youjuli) {
			Serial.println("右转");
			youZhuan();
			delay(100);
			ting();
		}
		
	} 
	else { //前方无障碍物,小车前进
		qianJin();
	}
}

7.实物展示

  • 13
    点赞
  • 68
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 12
    评论
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

热爱嵌入式的小佳同学

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值