Arduino控制下能躲开障碍物的慧鱼车
0赞
发表于 2012/3/31 12:12:50
阅读(3169)
我已经写了三篇 涉及慧鱼车的博文了。先看看吧。
一、《Arduino开发实战指南》与慧鱼遥控车
http://blog.chinaaet.com/detail/25929.html
二、任天堂Wii手柄遥控慧鱼车
http://blog.chinaaet.com/detail/25976.html
三、夏普GP2D12红外线测距传感器与LCD1602液晶
http://blog.chinaaet.com/detail/26124.html
这篇《Arduino控制下能躲开障碍物的慧鱼车》博文中介绍的慧鱼车并不是被遥控的,而是有了自我思考的能力,它能够判断距离障碍物的远近,如果离障碍物太近,则会自动后退,再转弯,躲开障碍物,寻找其它出路。看视频。
与被遥控的慧鱼车对比,自主型慧鱼车少了无线通信模块,增加了夏普GP2D12红外传感器和集成了I2C接口的LCD1602面板,红外传感器通过其支架与万向轮支座用螺钉螺母固连在一起,1602LCD面板用透明胶带粘在小车的前端。
能躲开障碍物的慧鱼车的程序如下:(有详细注释)
/*慧鱼智能车通过夏普GP2D12红外传感器测量与障碍物的距离
并把距离显示在LCD1602液晶面板上,
如果小车距离障碍物小于20cm,则小车后退,然后右转;
否则小车前行。*/
// 声明集成了I2C接口的LCD1602编程所需库文件
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
int E_right =5; //连接小车电机1的使能端口到数字接口5
int M_right =4; //连接电机1的转向端口到数字接口4
int E_left =6;//连接小车电机2的使能端口到数字接口6
int M_left=7; //连接电机2的转向端口到数字接口7
float velocity=255;//车速调节
//设置LCD1602的I2C地址为0x27,LCD1602为两行,每行16个字符的液晶显示器
LiquidCrystal_I2C lcd(0x27,16,2);
int GP2D12 = 0;//把夏普GP2D12红外测距传感器连接在模拟量端口0
int val; //存储从GP2D12红外测距传感器读到的值
float distance_float;//存储由传感器读取值,通过算式处理后的浮点型距离值
int distance_int;//存储由传感器读取值,通过算式处理后的整数型距离值
//初始化程序
void setup() {
//给控制电机的各数字接口设置输入输出状态
pinMode(M_right, OUTPUT);
pinMode(E_right, OUTPUT);
pinMode(M_left, OUTPUT);
pinMode(E_left, OUTPUT);
//LCD1602的I2C通讯初始化需要执行两次
lcd.init(); // 给LCD的I2C通讯初始化
delay(20);
lcd.init(); // 给LCD的I2C通讯初始化
delay(20);
lcd.backlight();//点亮LCD1602背光灯
}
void advance()//小车前进
{
digitalWrite(M_right,HIGH);
analogWrite(E_right,int(velocity));
digitalWrite(M_left,HIGH);
analogWrite(E_left,int(velocity));
}
void back()//小车后退
{
digitalWrite(M_right,LOW);
analogWrite(E_right,int(velocity));
digitalWrite(M_left,LOW);
analogWrite(E_left,int(velocity));
}
void left()//小车左转
{
digitalWrite(M_right,HIGH);
analogWrite(E_right,int(velocity));
digitalWrite(M_left,HIGH);
analogWrite(E_left,int(0));
}
void right()//小车右转
{
digitalWrite(M_right,HIGH);
analogWrite(E_right,int(0));
digitalWrite(M_left,HIGH);
analogWrite(E_left,int(velocity));
}
void Stop()//小车停止
{
digitalWrite(E_right, LOW); //右电机停
digitalWrite(E_left, LOW); //左电机停
}
void Display()//LCD显示子程序
{
lcd.clear();//LCD清屏
// 定位光标在LCD第0行、第0列
lcd.setCursor(0, 0);
//在LCD第0行第0列开始显示"Distance:"
lcd.print("Distance:");
// 定位光标在LCD第1行、第7列
lcd.setCursor(7, 1);
//如果传感器读取值大于80或者小于10,
if(distance_float>80||distance_float<10)
{
//则在LCD第1行、第7列开始显示"OverRange"
lcd.print("OverRange");
//if(distance_float>80)
//由于夏普GP2D12红外测距传感器有效测距范围是10~80cm
//超过范围,所测距离与实际距离完全不符,
//故针对蔽障小车实验,把范围以外的距离设置为80cm
distance_float=80;
//if(distance_float<10)
//distance_float=1;
}
//如果传感器读取值在10到80之间,
else
{
//把浮点型距离值取整
distance_int=int(distance_float);
//则在LCD第1行、第7列开始显示距离值
lcd.print(distance_int);
//在距离值后显示单位"cm"
lcd.print("cm");
}
}
//主程序
void loop() {
//读取GP2D12红外测距传感器模拟量数据
val = analogRead(GP2D12);
//通过以下算式,把传感器读取值处理成浮点型距离值
distance_float=2547.8/((float)val*0.49-10.41)-0.42;
Display();//调用显示子程序
//如果小车距离障碍物大于20cm,则小车前进,直到小于20cm
if(distance_float>20)
{
advance();
//这个延时,是为了给LCD1602送显示数据的频率不致于太快
//给LCD1602送显示数据的频率不致于太快,LCD1602显示不正常
delay(200);
}
//如果小车距离障碍物小于20cm,则小车后退,然后右转
if (distance_float<20)
{
back();
delay(800);
right();
delay(1000);
}
}