很多朋友制作了超声波避障智能小车,不过可惜超声波测量平面物体相对比较准确,对于细长形的物体,经常无法形成有效的反射,因此测量不到,使得智能小车容易“卡”在桌子、凳子脚下或其他障碍物下面。 又由于超声波一般装在车头,对于左右两侧出现的“障碍”无法处理。所以我在小车底盘左右两侧加装了红外线感应,基本达到小车在房间了到处走,不会“卡死”的效果,也能够及时处理突然在车身左右出现的障碍物,行走时速度快,比较灵活。 本人使用某国内厂家的小车底盘,他们自己生产的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); } } }
|