很多朋友制作了超声波避障智能小车,不过可惜超声波测量平面物体相对比较准确,对于细长形的物体,经常无法形成有效的反射,因此测量不到,使得智能小车容易“卡”在桌子、凳子脚下或其他障碍物下面。
又由于超声波一般装在车头,对于左右两侧出现的“障碍”无法处理。所以我在小车底盘左右两侧加装了红外线感应,基本达到小车在房间了到处走,不会“卡死”的效果,也能够及时处理突然在车身左右出现的障碍物,行走时速度快,比较灵活。
本人使用某国内厂家的小车底盘,他们自己生产的HJduino控制板,拓展板(兼容Arduino),红外感测器,通用的超声波。我不是厂家的人,没必要在这里给他做广告,只是本人穷,在两百多块左右的价位选择这个厂家的东西还是比较合适的。
红外感应器的感测距离我自己可以调到6cm至7cm左右,但是这仪器“怕太阳光”。即使没有直接被阳光直射到,白天在室内也可能被太阳辐射热影响到红外信号,小车失灵。一般是晚上八点之后,小车的红外感应比较灵敏、准确。
本文中的超声波没有安装舵机,是固定的。
从理论上说,在小车上多装几个超声波或者红外线是没有问题的。
我也计划过买一台小孩开的玩具车(可以坐人的那种)来改装成“自动行驶”避障车,但是由于时间、精力、财力等问题,目前实现不了。希望有朋友可以做出来。
个人拍的一些视频已经上传到优酷,有兴趣的朋友可以去看看。
我的自频道-优酷视频
优酷用户1475903255365918
我拍视频时是用
手机随便拍的,没有分清是“1路”避障还是“3路”避障。个人感觉3路避障灵活些,不过我做的1路避障效果也还可以。
以下是“3路”避障源代码:
//ARDUINO 超声波加红外线智能避障小车 L = 左 R = 右 F = 前 B = 后
int pinLB=14;
int pinLF=15;
int pinRB=17;
int pinRF=16;
int MotorRPWM=3;
int MotorLPWM=5;
int inputPin = 9; // 超声波接收管脚号
int outputPin =8; // 超声波发射管脚号
const int SensorLeft = 12; //左红外线输入脚
const int SensorRight = 13; //右输入脚
int SL; //左
int SR; //右
int Fspeedd = 0; // 前进速度
void setup()
{
Serial.begin(9600); //波特率
pinMode(pinLB,OUTPUT);
pinMode(pinLF,OUTPUT);
pinMode(pinRB,OUTPUT);
pinMode(pinRF,OUTPUT);
pinMode(MotorLPWM, OUTPUT); //PWM
pinMode(MotorRPWM, OUTPUT);
pinMode(inputPin, INPUT); // 超声波接收
pinMode(outputPin, OUTPUT); //超声波发射
pinMode(SensorLeft, INPUT); //定义左红外线感应
pinMode(SensorRight, INPUT); //定义右红外线
}
void advance(int a) // 前进
{
digitalWrite(pinRF,HIGH);
digitalWrite(pinRB,LOW);
analogWrite(MotorRPWM,150);
digitalWrite(pinLF,HIGH);
digitalWrite(pinLB,LOW);
analogWrite(MotorLPWM,150);
delay(a * 100);
}
void right(int b) //单轮
{
digitalWrite(pinRB,LOW);
digitalWrite(pinRF,HIGH);
analogWrite(MotorRPWM,200);
digitalWrite(pinLB,LOW);
digitalWrite(pinLF,LOW);
delay(b * 100);
}
void left(int c) //单轮
{
digitalWrite(pinRB,LOW);
digitalWrite(pinRF,LOW);
digitalWrite(pinLB,LOW);
digitalWrite(pinLF,HIGH);
analogWrite(MotorLPWM,200);
delay(c * 100);
}
void turnR(int d) //双轮右转
{
digitalWrite(pinRB,HIGH);
digitalWrite(pinRF,LOW);
analogWrite(MotorRPWM,200);
digitalWrite(pinLB,LOW);
digitalWrite(pinLF,HIGH);
analogWrite(MotorLPWM,200);
delay(d * 50);
}
void turnL(int e) //双轮左转
{
digitalWrite(pinRB,LOW);
digitalWrite(pinRF,HIGH);
analogWrite(MotorRPWM,200);
digitalWrite(pinLB,HIGH);
digitalWrite(pinLF,LOW);
analogWrite(MotorLPWM,200);
delay(e * 50);
}
void stopp(int f) //停止
{
digitalWrite(pinRB,LOW);
digitalWrite(pinRF,LOW);
digitalWrite(pinLB,LOW);
digitalWrite(pinLF,LOW);
delay(f * 100);
}
void back(int g) //后退
{
digitalWrite(pinRF,LOW);
digitalWrite(pinRB,HIGH);
analogWrite(MotorRPWM,150);
digitalWrite(pinLF,LOW);
digitalWrite(pinLB,HIGH);
analogWrite(MotorLPWM,150);
delay(g * 100);
}
void ask_pin_F() // 测量前方距离
{
digitalWrite(outputPin, LOW); // 超声波发射低电平2μs
delayMicroseconds(2);
digitalWrite(outputPin, HIGH); // 超声波发射高电平10μs
delayMicroseconds(10);
digitalWrite(outputPin, LOW); // 维持超声波发射低电平
float Fdistance = pulseIn(inputPin,HIGH); //读取相差时间
Fdistance= Fdistance/5.8/10; //将时间转化为距离(单位:厘米)
Fspeedd = Fdistance; // 将距离输入前进速度
}
void loop()
{
ask_pin_F(); // 读取前方距离
SL = digitalRead(SensorLeft);
SR = digitalRead(SensorRight);
if(Fspeedd < 25) // 假如前方距离小于25厘米
{
stopp(2);
delay(500);
back(3);
turnL(6);
}
else //假如前方距离不小于25厘米
{
advance(1); //前进
if (SL == HIGH & SR == LOW) //如果右边红外线感测到物体,单轮向左
{
left(7);
}
else if (SR == HIGH & SL == LOW)//如果左边红外线感应到物体,向右
{
right(7);
}
}
}