Arduino智能避障小车避障程序Word格式.docx
《Arduino智能避障小车避障程序Word格式.docx》由会员分享,可在线阅读,更多相关《Arduino智能避障小车避障程序Word格式.docx(24页珍藏版)》请在冰豆网上搜索。
pinMode(IN4,OUTPUT);
pinMode(trigger,OUTPUT);
pinMode(echo,INPUT);
write(90);
//舵机复位至90°
delay(6000);
//上电等待6s后进入主循环
}
//主程序
voidloop()
read_ahead=readDistance();
//调用readDistance()函数读出前方距离
println(”AHEAD:
"
);
Serial.println(read_ahead);
//串行监视器显示机器人前方距离
if(read_ahead<
no_good)//如果前方距离小于警戒值
{
fastStop();
//就令机器人紧急刹车
waTch();
//然后左右查看,分析得出最佳路线
goForward();
//*此处调用看似多余,但可以确保机器人高速运转下动作的连贯性
}
elsegoForward();
//否则就一直向前行驶
}
主程序用到了两个库,Servo库是IDE自带的,NwePing库是第三方库,需要下载安装。
接下来建立一个名为move.ino的标签。
//move。
ino,机动模块。
//刹车
voidfastStop()
println(”STOP"
);
//串行监视器显示机器人状态为STOP(停止)
//左电机急停(注:
L298N和L293D均带有刹车功能,在使能成立的条件下,同时向两相写入高电平可令电机急停,详见芯片手册)
digitalWrite(ENA,HIGH);
digitalWrite(IN1,HIGH);
digitalWrite(IN2,HIGH);
//右电机急停
digitalWrite(ENB,HIGH);
digitalWrite(IN3,HIGH);
digitalWrite(IN4,HIGH);
//前进
voidgoForward()
Serial.println(”FORWARD"
//串行监视器显示机器人状态为FORWARD(前进)
//左电机逆时针旋转
analogWrite(ENA,106);
//左电机PWM,可微调这个数值使小车左右两侧车轮转速相等,右电机同理
digitalWrite(IN1,LOW);
digitalWrite(IN2,HIGH);
//右电机顺时针旋转
analogWrite(ENB,118);
digitalWrite(IN3,HIGH);
digitalWrite(IN4,LOW);
//原地左转
voidturnLeft()
{
println(”LEFT"
//串行监视器显示机器人状态为LEFT(向左转)
//左电机正转
analogWrite(ENA,106);
digitalWrite(IN1,HIGH);
digitalWrite(IN2,LOW);
//右电机正转
analogWrite(ENB,59);
//*微调这个数值,使转弯时内侧车轮起主导作用。
相当于让小车向后打一把轮再拐弯。
右转同理
digitalWrite(IN3,HIGH);
digitalWrite(IN4,LOW);
delay(205);
//*延迟,数值以毫秒为单位,调节此值可使机器人动作连贯
}
//原地右转
voidturnRight()
println(”RIGHT"
//串行监视器显示机器人状态为RIGHT(向右转)
//左电机反转
analogWrite(ENA,53);
//右电机反转
analogWrite(ENB,118);
digitalWrite(IN3,LOW);
digitalWrite(IN4,HIGH);
delay(205);
//*调节此值可使机器人动作连贯
//原地掉头(暂时用不到)
voidturnAround()
Serial.println(”TURN180"
//串行监视器显示机器人状态为TURN180(原地顺时针旋转180°
)
analogWrite(ENA,106);
digitalWrite(IN2,HIGH);
digitalWrite(IN3,LOW);
delay(500);
//*
//ping。
ino,测距模块
intreadDistance()
delay(30);
//声波发送间隔30ms,大约每秒探测33次.受系统所限,此值不可小于29ms
intcm=sensor。
ping()/US_ROUNDTRIP_CM;
//把Ping值(μs)转换为cm
return(cm);
//readDistance()返回的数值是cm
最后是驱动云台扫描并分析左右两侧距离的watch。
ino模块.
//watch.ino,查看模块
voidwaTch()
//测量右前方距离.
//*注意舵机旋转方向,SG5010为逆时针旋转
write(20);
//*舵机右转至20°
.调节此值会影响传感器扫描区域,夹角越小,机器人转弯越谨慎
delay(1200);
//延迟1。
2s待舵机稳定
intread_right=readDistance();
//调用readDistance()函数读出右前方距离
Serial.print(”RIGHT:
”);
println(read_right);
//sensorStation.write(90);
//*舵机复位至90度。
廉价舵机大角度旋转会产生抖动,要加上这两行以求读数准确。
//delay(500);
//延迟0.5s
//测量左前方距离
sensorStation.write(160);
//舵机左转至160°
//延迟1。
2s待舵机稳定。
intread_left=readDistance();
//调用函数读出距离左前方距离。
Serial.print("
LEFT:
Serial.println(read_left);
sensorStation.write(90);
//这一行确保只要小车处于行驶状态,传感器就面向正前方
//延迟0。
5s。
//分析得出最佳行进路线.
if(read_right>
read_left)//如果右前方距离比较大
turnRight();
//就向右转,
}
elseturnLeft();
//否则就向左转
//此处也可以加入另一层逻辑:
如果左右两侧读数相等就调用turnAround()原地掉头。
但实际上触发的几率不大。
//I2C液晶测试程序,Arduino版本1。
5.6-r2,LiquidCrystal_I2C库版本2。
Wire.h〉
#include"
LiquidCrystal_I2C.h"
//导入I2C液晶库
LiquidCrystal_I2Clcd(0x27,16,2);
//设定I2C地址及液晶屏参数
voidsetup()
lcd。
init();
//始化液晶屏
backlight();
lcd.print("
Hello,world!
”);
//开始打印信息
setCursor(3,1);
//设定显示位置,第3列,第1行
lcd.print(”ZANG。
HAIBO"
voidloop()
Serial.println(”FORWARD”);
intval1=analogRead(A0);
//手动调整左电机转速.电位器两端分别接至+5V和GND,中心抽头接至A0
intleftSpeed=map(val1,0,1023,0,255);
//把读数映射为PWM
analogWrite(ENA,leftSpeed);
//写入速度。
下面的右电机同理
//右电机顺时针旋转
intval2=analogRead(A1);
intrightSpeed=map(val2,0,1023,0,255);
analogWrite(ENB,rightSpeed);
ino,红外测距模块
//trigger脚沿用D9,echo脚换成A3
digitalWrite(trigger,HIGH);
//点亮红外发射管
delayMicroseconds(200);
//给接收管留出200μs响应时间
IRvalue=analogRead(echo);
//读取自然光和红外线下反射值的总和
digitalWrite(trigger,LOW);
//关闭红外发射管以读取自然光下的反射值
delayMicroseconds(200);
//留出200μs响应时间
IRvalue=IRvalue-analogRead(echo);
//刨除自然光得出实际值(红外发射管产生的部分)
returnmap(IRvalue,120,930,30,0);
//用map()函数把读数转换为距离
代码1:
HC—SR04超声波传感器典型代码
digitalWrite(TrigPin,LOW);
delayMicroseconds
(2);
digitalWrite(TrigPin,HIGH);
//发送10μs的高电平触发信号
delayMicroseconds(10);
digitalWrite(TrigPin,LOW);
distance=pulseIn(EchoPin,HIGH)*340/60/2;
//检测脉冲宽度即为超声波往返时间
代码2:
简易超声波测距代码
constintTrigPin=2;
constintEchoPin=3;
//设定SR04连接的Arduino引脚
floatdistance;
voidsetup(){
//初始化串口通信及连接SR04的引脚
begin(9600);
pinMode(TrigPin,OUTPUT);
//要检测引脚上输入的脉冲宽度,需要先设置为输入状态
pinMode(EchoPin,INPUT);
Serial.println("
Ultrasonicsensor:
}
voidloop(){
//产生一个10μs的高脉冲去触发TrigPin
digitalWrite(TrigPin,LOW);
delayMicroseconds
(2);
digitalWrite(TrigPin,HIGH);
delayMicroseconds(10);
digitalWrite(TrigPin,LOW);
//检测脉冲宽度,并计算出距离
distance=pulseIn(EchoPin,HIGH)/58。
00;
print(distance);
print("
cm”);
Serial.println();
delay(1000);
代码3:
具有温度补偿的超声波测距代码
OneWire。
h>
#include〈DallasTemperature。
h〉
//设定SR04连接的Arduino引脚
constintTrigPin=2;
constintEchoPin=3;
floatdistance;
floattemperature_value;
#defineONE_WIRE_BUS4
OneWireoneWire(ONE_WIRE_BUS);
DallasTemperaturesensors(&
oneWire);
voidsetup(){//初始化串口通信及连接SR04的引脚
pinMode(TrigPin,OUTPUT);
//要检测引脚上输入的脉冲宽度,需要先设置为输入状态
pinMode(EchoPin,INPUT);
sensors.begin();
voidloop(){
sensors.requestTemperatures();
temperature_value=sensors.getTempCByIndex(0);
temperature="
print(temperature_value);
Serial.print(”C”);
digitalWrite(TrigPin,LOW);
delayMicroseconds
(2);
digitalWrite(TrigPin,HIGH);
digitalWrite(TrigPin,LOW);
//检测脉冲宽度,并计算出距离
distance=pulseIn(EchoPin,HIGH)*(331.4+0。
6*temperature_value)/2;
distance="
Serial.print(distance);
cm"
println();
delay(1000);
代码4:
基于GP2D12的红外测距系统代码
inti;
floatval;
voidsetup(){
Serial.begin(9600);
voidloop(){
i=analogRead(A0);
val=2547.8/((float)i*0。
49-10.41)—0。
42;
println(val,2);
//蓝牙遥控小车
//Arduino
源程序
//定稿日期:
2016-3-16
//程序功能简介:
//程序采用软件PWM方式,控制两支直流电机的运行行为,实现直行、后退、左转和右转动作。
//操作者使用Android手机的蓝牙功能发出指令,操控小车动作.
//操作者还通过蓝牙对小车的动作参数进行调试。
//使用自定义串口收发数据
//使用软件PWM,输出引脚可任意制定
//使用Atmega48芯片
//Arduio
版本1.0.5
#include〈avr/io。
h〉
#include<
avr/interrupt。
EEPROM。
#include"
usart.h"
unsignedintcounter;
//PWM计数器
unsignedcharwCnt=0;
//接收字计数
unsignedintpwm_LH;
//左电机高电平计数
unsignedintpwm_RH;
//右电机高电平计数
unsignedcharlDirect;
//左电机运转方向
unsignedcharrDirect;
//右电机运转方向
unsignedintLP=0;
unsignedintRP=0;
unsignedintLD=0;
unsignedintRD=0;
unsignedintPWM[6];
//存放当前PWM参数的整数型数组,全局变量
unsignedcharinputString[8];
//
存输入数据字符串变量
booleanstringComplete=false;
数据串结束标志
//定时器2初始化函数
voidtimer2_init()
{
cli();
TCCR2B=0x00;
//
TCNT2=0xF6;
TCCR2A=0x00;
TCCR2B=0x02;
TIMSK2=0x01;
//定时器2中断允许
sei();
}
//定时器2中断服务函数
//PWM波形产生器
ISR(TIMER2_OVF_vect)
TCNT2=0xF6;
counter++;
if(counter==0x3ff)
if(rDirect==1)
bitSet(PORTD,5);
else
bitSet(PORTD,4);
if(lDirect==1)
bitSet(PORTD,7);
bitSet(PORTD,6);
counter=0;
if(counter==pwm_RH)
bitClear(PORTD,4);
bitClear(PORTD,5);
if(counter==pwm_LH)
bitClear(PORTD,6);
bitClear(PORTD,7);
//电机运行函数
voidMove(unsignedintLS,unsignedcharLD,unsignedintRS,unsignedcharRD)
asm(”BCLR7”);
//关中断
pwm_LH=LS;
pwm_RH=RS;
lDirect=LD;
rDirect=RD;
asm("
BSET7”);
//开中断
//获取EEPROM数据函数
//功能:
从EEPROM里顺序读出六个PWM参数,存入PWM数组
voidGetData()
unsignedcharbytes[2];
//暂时存放PWM参数的字节数组,全局变量
unsignedchari;
unsignedcharj;
unsignedchark;
for(i=0;
i〈6;
i++)
//for循环,读六个参数
for(j=0;
j<
2;
j++)
//内循环,每次读两个字节
k=i*2+1-j;
//地址计算
bytes[j]=EEPROM。
read(k);
//EEPROM读操作
PWM
=word(bytes[0],bytes[1]);
//将读出的两个字节合成一个PWM整数数据
//数据发送函数
将一个整数拆分成四个ASCII代码,通过蓝牙串口发出的函数。
//例如:
整数784,将拆分成;
’’,’7'
,’8'
,'
4'
四个字符
voidNumber(intval)
inttmp;
//中间变量
unsignedchari;
//循环计数变量
unsignedcharbuf[4];
//存字符数组
tmp=val/1000;
buf[0]=tmp+0x30;
//获得千位
val=val%1000;
tmp=val/100;
buf[1]=tmp+0x30;
//获得百位
val=val%100;
tmp=val/10;
buf[2]=tmp+0x30;
//获得十位
val=val%10;
buf[3]=val+0x30;
//获得个位
for(i=0;
i〈4;
i++)
if(buf
==0x30)
//从高位整理,如果是