Arduino智能小车——超声波避障

Arduino智能小车系列教程时空门:

Arduino智能小车——拼装篇 点击跳转

Arduino智能小车——测试篇 点击跳转

Arduino智能小车——调速篇 点击跳转

Arduino智能小车——超声波避障 点击跳转

Arduino智能小车——蓝牙小车 点击跳转

Arduino智能小车——循迹篇 点击跳转

Arduino智能小车——小车测速 点击跳转

文章目录

经过前几篇的测试大家应该对小车有一定的认识了,在实际的操作过程中经常会由于操作不当各种碰壁吧?那这次我们将给小车装上一只“眼睛”,让小车看到障碍,躲避障碍。

准备材料

超声波模块HC-SR04

在这里简单说下超声波测距的原理,相信大家也都知道。超声波发射装置发出超声波,它的根据是接收器接到超声波时的时间差,与雷达测距原理相似。 超声波发射器向某一方向发射超声波,在发射时刻的同时开始计时,超声波在空气中传播,途中碰到障碍物就立即返回来,超声波接收器收到反射波就立即停止计时。

采用Trig引脚触发,给至少10us的高电平脉冲信号

模块自动发送8个40kHz的方波,自动检测是否有信号返回

有信号返回,通过Echo引脚输出一个高电平脉冲,高电平脉冲持续的时间就是超声波从发射到反射返回的时间。距离=(高电平脉冲时间*340)/2。(声音在空气中传播速度为340m/s)

主要技术参数

工作电压

DC5V

静态电流

<2mA

输出电平

0-5V

感应角度

≤15度

探测距离

2cm-450cm

最高精度

0.3cm

舵机

在这里推荐9G舵机SG90,或者其他类似的舵机,这种舵机体积比较小,扭矩虽然不是大, 但是足够带动简易云台,很方便在小车上使用,大家购买时注意舵机的转动角度,有55度的,180度的等等,大家可以根据需要购买。

舵机固定架

舵机固定架的购买一定要配合舵机,所以大家购买的时候注意尺寸哦!!~

舵机安装

舵机在安装之前大家一定要记得校准,为什么要校准那,这个跟舵机的工作原理有关。控制信号由接收机的通道进入信号调制芯片,获得直流偏置电压。它内部有一个基准电路,产生周期为20ms,宽度为1.5ms的基准信号,将获得的直流偏置电压与电位器的电压比较,获得电压差输出。最后,电压差的正负输出到电机驱动芯片决定电机的正反转。当电机转速一定时,通过级联减速齿轮带动电位器旋转,使得电压差为0,电机停止转动。

舵机的控制一般需要一个20ms左右的时基脉冲,该脉冲的高电平部分一般为0.5ms-2.5ms范围内的角度控制脉冲部分,总间隔为2ms。以180度角度伺服为例,那么对应的控制关系是这样的:

高电平时间

对应位置

0.5ms

0度

1.0ms

45度

1.5ms

90度

2.0ms

135度

2.5ms

180度

也就是说当对舵机输入相同控制信号时,舵机会运动到固定位置,他的动作不是做圆周运动,而是在运动范围内,每一个位置对应一个控制信号。

因此我们需要在将舵机安装在固定架上之前,需要先将舵机初始化好,舵机一般为三根线:棕色——GND,红色——VCC,橙色——控制信号。因此我们将棕色线接到GND,红色线接到“+5V”引脚,橙色线接到“9”引脚,初始化程序如下:

`#include //加入含有舵机控制库的头文件

#define PIN_SERVO 9 //舵机信号控制引脚

Servo myservo;

void setup()

{

myservo.attach(PIN_SERVO); //舵机初始化

}

void loop()

{

myservo.write(90); //PWM输出

}`

* 1

* 2

* 3

* 4

* 5

* 6

* 7

* 8

* 9

* 10

* 11

* 12

* 13

* 14

在舵机初始化好之后将其安装在固定架上,然后装配在小车上,此时保证超声波模块超前。

超声波接线

估计不少朋友早已经发现板子上的“+5V”和“GND”引脚已经不够用了,这个时候你们可以向我这样焊一个扩展板出来,上面固定两排排针,一排用来扩展“+5V”,一边用来扩展“GND”引脚。

超声波模块有四个引脚,“VCC”接到Arduino UNO开发板的“+5V”引脚,“GND”接到开发板“GND”引脚,“Trig”引脚接到开发板“8”引脚,“Echo”引脚接到开发板“7”引脚。

线太乱了,真的没办法整理,我自己都没眼看。

代码测试

`#include #define STOP 0

#define FORWARD 1

#define BACKWARD 2

#define TURNLEFT 3

#define TURNRIGHT 4

int leftMotor1 = 16;

int leftMotor2 = 17;

int rightMotor1 = 18;

int rightMotor2 = 19;

int leftPWM = 5;

int rightPWM = 6;

Servo myServo; //舵机

int inputPin=7; // 定义超声波信号接收接口

int outputPin=8; // 定义超声波信号发出接口

void setup() {

// put your setup code here, to run once:

//串口初始化

Serial.begin(9600);

//舵机引脚初始化

myServo.attach(9);

//测速引脚初始化

pinMode(leftMotor1, OUTPUT);

pinMode(leftMotor2, OUTPUT);

pinMode(rightMotor1, OUTPUT);

pinMode(rightMotor2, OUTPUT);

pinMode(leftPWM, OUTPUT);

pinMode(rightPWM, OUTPUT);

//超声波控制引脚初始化

pinMode(inputPin, INPUT);

pinMode(outputPin, OUTPUT);

}

void loop() {

// put your main code here, to run repeatedly:

avoidance();

}

void motorRun(int cmd,int value)

{

analogWrite(leftPWM, value); //设置PWM输出,即设置速度

analogWrite(rightPWM, value);

switch(cmd){

case FORWARD:

Serial.println("FORWARD"); //输出状态

digitalWrite(leftMotor1, HIGH);

digitalWrite(leftMotor2, LOW);

digitalWrite(rightMotor1, HIGH);

digitalWrite(rightMotor2, LOW);

break;

case BACKWARD:

Serial.println("BACKWARD"); //输出状态

digitalWrite(leftMotor1, LOW);

digitalWrite(leftMotor2, HIGH);

digitalWrite(rightMotor1, LOW);

digitalWrite(rightMotor2, HIGH);

break;

case TURNLEFT:

Serial.println("TURN LEFT"); //输出状态

digitalWrite(leftMotor1, HIGH);

digitalWrite(leftMotor2, LOW);

digitalWrite(rightMotor1, LOW);

digitalWrite(rightMotor2, HIGH);

break;

case TURNRIGHT:

Serial.println("TURN RIGHT"); //输出状态

digitalWrite(leftMotor1, LOW);

digitalWrite(leftMotor2, HIGH);

digitalWrite(rightMotor1, HIGH);

digitalWrite(rightMotor2, LOW);

break;

default:

Serial.println("STOP"); //输出状态

digitalWrite(leftMotor1, LOW);

digitalWrite(leftMotor2, LOW);

digitalWrite(rightMotor1, LOW);

digitalWrite(rightMotor2, LOW);

}

}

void avoidance()

{

int pos;

int dis[3];//距离

motorRun(FORWARD,200);

myServo.write(90);

dis[1]=getDistance(); //中间

if(dis[1]<30)

{

motorRun(STOP,0);

for (pos = 90; pos <= 150; pos += 1)

{

myServo.write(pos); // tell servo to go to position in variable 'pos'

delay(15); // waits 15ms for the servo to reach the position

}

dis[2]=getDistance(); //左边

for (pos = 150; pos >= 30; pos -= 1)

{

myServo.write(pos); // tell servo to go to position in variable 'pos'

delay(15); // waits 15ms for the servo to reach the position

if(pos==90)

dis[1]=getDistance(); //中间

}

dis[0]=getDistance(); //右边

for (pos = 30; pos <= 90; pos += 1)

{

myServo.write(pos); // tell servo to go to position in variable 'pos'

delay(15); // waits 15ms for the servo to reach the position

}

if(dis[0]=50)

{

//如果距离小于50厘米返回数据

return 50;

}//如果距离小于50厘米小灯熄灭

else

return distance;

}`

* 1

* 2

* 3

* 4

* 5

* 6

* 7

* 8

* 9

* 10

* 11

* 12

* 13

* 14

* 15

* 16

* 17

* 18

* 19

* 20

* 21

* 22

* 23

* 24

* 25

* 26

* 27

* 28

* 29

* 30

* 31

* 32

* 33

* 34

* 35

* 36

* 37

* 38

* 39

* 40

* 41

* 42

* 43

* 44

* 45

* 46

* 47

* 48

* 49

* 50

* 51

* 52

* 53

* 54

* 55

* 56

* 57

* 58

* 59

* 60

* 61

* 62

* 63

* 64

* 65

* 66

* 67

* 68

* 69

* 70

* 71

* 72

* 73

* 74

* 75

* 76

* 77

* 78

* 79

* 80

* 81

* 82

* 83

* 84

* 85

* 86

* 87

* 88

* 89

* 90

* 91

* 92

* 93

* 94

* 95

* 96

* 97

* 98

* 99

* 100

* 101

* 102

* 103

* 104

* 105

* 106

* 107

* 108

* 109

* 110

* 111

* 112

* 113

* 114

* 115

* 116

* 117

* 118

* 119

* 120

* 121

* 122

* 123

* 124

* 125

* 126

* 127

* 128

* 129

* 130

* 131

* 132

* 133

* 134

* 135

* 136

* 137

* 138

* 139

* 140

* 141

* 142

* 143

* 144

* 145

* 146

* 147

代码详解

“Trig”引脚控制超声波发出声波,对应int outputPin=8;

“Echo”引脚反应接收到返回声波,对应int inputPin=7;

`int inputPin=7; // 定义超声波信号接收接口

int outputPin=8; // 定义超声波信号发出接口`

* 1

* 2

int getDistance()函数解析

超声波发出引脚“Trig”为高时对外发出超声波,为保证发出10μs声波,因此在发送之前需要将该引脚拉低,并给他一定反应时间。

`digitalWrite(outputPin, LOW); // 使发出发出超声波信号接口低电平2μs

delayMicroseconds(2);`

* 1

* 2

之后发送10μs超声波

`digitalWrite(outputPin, HIGH); // 使发出发出超声波信号接口高电平10μs,这里是至少10μs`

* 1

声波发送之后禁止其继续发送,同时开始检测是否反射回来的声波

`digitalWrite(outputPin, LOW); // 保持发出超声波信号接口低电平

int distance = pulseIn(inputPin, HIGH); // 读出脉冲时间`

* 1

* 2

pulseIn()单位为微秒,声速344m/s,所以距离cm=344_100/1000000_pulseIn()/2约等于pulseIn()/58.0distance= distance/58; // 将脉冲时间转化为距离(单位:厘米)

超声波模块工作受物体表面反射程度影响,并且在传播过程中信号强度容易衰减,因此该模块适用的检测距离有限,一般在50cm以内相对正确,而且我们在避障时不需要检测太远的距离,因此超过50cm以上的都按50cm计算

`if (distance >=50)

{

//如果距离小于50厘米返回数据

return 50;

}//如果距离小于50厘米小灯熄灭

else

return distance;`

* 1

* 2

* 3

* 4

* 5

* 6

* 7

void avoidance()函数解析

小车前进过程中只检测前方距离障碍的距离,并且控制舵机,保持超声波模块位于正前方。

`motorRun(FORWARD,200);

myServo.write(90);

dis[1]=getDistance(); //中间`

* 1

* 2

* 3

当检测到小车前方距离障碍距离小于30cm时停车,检测两边距离。

`motorRun(STOP,0);`

* 1

控制舵机每次运动一个周期后都返回正前方位置。由于舵机运动需要一定的时间,因此在每转过一个角度的时候都延时delay(15),供其运动。

`for (pos = 90; pos <= 150; pos += 1)

{

myServo.write(pos); // tell servo to go to position in variable 'pos'

delay(15); // waits 15ms for the servo to reach the position

}`

* 1

* 2

* 3

* 4

* 5

当运动到最左边时检测小车左边距离障碍的距离

`dis[2]=getDistance(); //左边`

* 1

向右边运动,检测右边距离

`for (pos = 150; pos >= 30; pos -= 1)

{

myServo.write(pos); // tell servo to go to position in variable 'pos'

delay(15); // waits 15ms for the servo to reach the position

if(pos==90)

dis[1]=getDistance(); //中间

}

dis[0]=getDistance(); //右边`

* 1

* 2

* 3

* 4

* 5

* 6

* 7

* 8

将前边、左边、右边距离障碍的距离都检测结束之后,舵机回到最初位置。

`for (pos = 30; pos <= 90; pos += 1)

{

myServo.write(pos); // tell servo to go to position in variable 'pos'

delay(15); // waits 15ms for the servo to reach the position

}`

* 1

* 2

* 3

* 4

* 5

注意事项

1.舵机使用时要防止其堵转,因为点击堵转时电流会增大,很容易烧坏舵机。

2.舵机的红色电源线接入电压一般要大于等于其工作电压,供电不足会导致舵机不停自传。

3.Arduino 《Servo.h》库里提供的write()函数输出的PWM即为舵机专用的20ms为周期的PWM波,如果使用其他开发板或者函数的话,请务必保证输出方波周期为20ms,否则舵机不会受控制

总结

这一篇讲解了舵机和超声波模块的使用方法,舵机在大家以后的开发生涯中应该会经常用到,因此舵机的使用规则(控制周期为20ms)请大家一定要记清楚,在舵机不受控制的时候建议大家可以购买一个舵机测试仪来测试舵机。

distance在函数 int_Arduino智能小车——超声波避障相关推荐

  1. Arduino智能小车——超声波避障

    Arduino智能小车--超声波避障 Arduino智能小车系列教程时空门: Arduino智能小车--拼装篇 点击跳转 Arduino智能小车--测试篇 点击跳转 Arduino智能小车--调速篇 ...

  2. 51智能小车超声波避障

    #include <REGX52.H> #include <intrins.h> #include <QXA51.H>sbit DU = P2^6;//数码管段选 ...

  3. ZYAR20A 亚克力2驱 蓝牙 298寻迹避障机器人 —— 小车超声波避障实验(有舵机)

    在下载到开发板之前要选择好板和端口,具体参见: ZYAR20A 亚克力2驱 蓝牙 298寻迹避障机器人 -- Arduino相关设置 代码 // 智能小车超声波避障实验(有舵机) // 程序中电脑打印 ...

  4. ZYAR20A 亚克力2驱 蓝牙 298寻迹避障机器人 —— 小车超声波避障实验(无舵机)

    在下载到开发板之前要选择好板和端口,具体参见: ZYAR20A 亚克力2驱 蓝牙 298寻迹避障机器人 -- Arduino相关设置 代码 // 智能小车超声波避障实验(无舵机) //======== ...

  5. 智能小车红外避障原理

    红外避障电路 红外避障电路由电位器R17,R28:发光二极管D8,D9:红外发射管 D2,D4和红外接收管D3,D5和芯片LM324等组成,LM234用于信号的比较,并产生比较结果输出给单片机进行处理 ...

  6. 智能循迹避障小车C语言程序编写思路,基于单片机的智能小车红外避障循迹系统设计与制作...

    余秀玲 余秀娟 摘 要:随着科技的高速发展,人们对生活质量的要求越来越高,无人驾驶汽车已经被广为研发和试用,由此智能小车的快速发展也是在情理之中.通过对基于单片机的智能小车的硬件及软件设计分析,实现红 ...

  7. 51单片机之智能小车(避障、跟随、循迹)

    目录 基本概述 硬件组成 功能 关键字 模块介绍 电机模块L9110S 循迹模块(TCRT5000传感器) 红外避障模块 测速模块 小车 移动小车(控制电机转动,使小车前进.后退.左转.右转 ) 遥控 ...

  8. STM32 学习笔记4-智能小车-超声波避障

    目录 什么是超声波?超声波测距原理? 硬件: 超声波传感器: 车身结构件及其附件: 软件: 逻辑控制策略: 代码实现: main.c 主函数 UltrasonicWave.c 主函数: backup: ...

  9. 智能小车红外避障模块----使用教程

    博主本科期间做过两个智能小车,链接如下 b站小车视频分享 今天就给·大家分享一下,何如在你的单片机或者树莓派上调用红外避障模块. 循迹模块介绍 循迹模块和红外避障模块类似.循迹模块的红外发射二极管不断 ...

最新文章

  1. 在CentOS 6.9 x86_64上从源码安装xz命令的方法
  2. 【STM32】STM32系列教程汇总(暂时暂停更新...)
  3. mysql的count函数类型是什么意思_详细解读MySQL中COUNT函数的用法
  4. 基于vue(element ui) + ssm + shiro 的权限框架
  5. DSP之时钟与定时器之一时钟发生器
  6. sql查询数据库所有表、字、注释
  7. MySql安装root用户密码设置失败问题解决
  8. 整理了20个最全的设计师学习网站,推荐收藏!
  9. [转]求职面试-与女大学生网络对话(上)
  10. 自己写歌怎么编曲?4款超好用编曲软件推荐
  11. java驱动音响设备发音_XP环境下驱动正常、声卡正常但音响没声音怎么解决?
  12. 计算机网络链接密码,怎么连接局域网中计算机网络密码方法介绍
  13. 27 信息过滤与反垃圾
  14. html5 canvas消除锯齿,HTML5 Canvas笔划没有消除锯齿
  15. Java代码实现excel的导入和导出
  16. Spring AOP(获取入参和返回值)及其原理:动态代理
  17. CentOS6开启BBR加速
  18. Git你真的Get到了吗?
  19. WPFのImage控件souce引入的方法总结
  20. 2的2.8次方用计算机怎么算,2.8 计算器的使用(含答案)

热门文章

  1. GitHub的初次使用记录
  2. at指令 和c语言,学渣求指教,如何识别字符串中的AT命令并逐个输出,求程序!!!...
  3. python处理pdf提取指定数据_python从PDF中提取数据的示例
  4. Spring MVC 常用Jar包官方下载地址(官方Maven仓库)
  5. JavaScript——String转DOM对象解决方案
  6. Vue——项目部署到非根目录下的解决方案
  7. JAVA——基于HttpComponents(HttpClient)的简单网络爬虫DEMO
  8. PHP——获取当前日期时间错误解决方案(PHP当前时区设置)
  9. BugKuCTF WEB web基础$_GET
  10. Bear and Finding Criminals