我是一名小学6年级的学生,就叫我小花生吧。我就读于北京市朝阳区垂杨柳中心小学金都分校。我学习Python编程已经两年多了,曾获得蓝桥杯全国选拔赛二等奖(Python中级青少年组)和北京复赛二等奖。打算明年初开始学习C++, 由于Arduino语言有些类似C++语言而且简单,所以在父亲的帮助下我学习了Arduino单片机和Arduino编程语言,这篇文章介绍了我使用Arduino单片机制作超声波+红外线智能避障小车并附上程序源代码。
最开始我做的是超声波避障小车,做成之后我发现超声波测量距离有死角和盲区,小车在稍复杂的障碍物的环境下会探测不到障碍物,小车会撞到障碍物上。经过和父亲聊,父亲建议我在超声波传感器两边增加2路红外线传感器来探测超声波死角和盲区障碍物。这样超声波+红外线一起来探测障碍物,消除了小车在复杂障碍物的环境下发生碰撞的现象。
使用材料:
1. Arduino UNO R3 主控
2. L298P 电机驱动扩展版
3. 超声波传感器(HC-SR04)
4. 红外避障传感器X2
5. 直流减速电机X2(6V)
6. 舵机+云台
7. 小车底板+直流电机安装支架+万向轮
8. LED灯模块X4
9. 铜柱+五金件若干
10. 杜邦线若干
11. 电池和电池盒
12. 扎带
13. 巡线传感器X3(这个小车用不到,为其他程序预先装配)
14. HC-05蓝牙模块(这个小车用不到,为其他程序预先装配)
以上这些材料从4家淘宝电商分别采购,价格如下图:
我的小车接线图(所有的线都接在L298P电机驱动扩展板上),接线示意图如下:
我计划要小车实现的运动和功能:
小车在行使过程中探测到40CM内有障碍物或者红外线避障传感器探测到障碍时,小车停下,舵机左右摆动,摆动时超声波探测小车左侧和右侧的距离。如果左侧大于右侧,那么左转,否则右转。前进时,前车灯点亮,后退时后车灯点亮蜂鸣器响起,左转左侧灯点亮蜂鸣器响起。右转右侧灯点亮蜂鸣器响起。停车全部灯点亮。
在程序编写和调试过程中遇到的困难和发现的问题:
1. 舵机控制我开始调用了库函数<Servo.h>, 但是我发现只要使用舵机库代码,那么有一个直流电机就一直无法转动。后来经过学习凌寒11的博客了解到舵机库会禁用Arduino 数字10引脚的PWM功能。而L298P电机驱动扩展板固化了Arduino数字 10,11,12,13引脚,而且10号引脚正是固化用来调速的(PWM)。
解决办法:参考凌寒11的博客:(19条消息) arduino-解决舵机与直流电机冲突问题_u010351766的专栏-CSDN博客https://blog.csdn.net/u010351766/article/details/64904756
2. 我的L298P电机驱动扩展板的D3和D5引脚之间的GND引脚其实并不是GND,也不是5V,建议接线的时候避开这个GND引脚就可以了。
程序代码:
int EchoPin = 8;
int TrigPin = 7;
int lval;
int rval;
int buzz = 4;
int E1 = 10;
int M1 = 12;
int E2 = 11;
int M2 = 13;
int fleft = A3;
int fright = A0;
int bleft = A1;
int bright = A2;
int lsensor = 6;
int rsensor = 5;
int servoPin = 9;
float distance,distance_left,distance_right;
void setup()
{
pinMode(M1,OUTPUT);
pinMode(M2,OUTPUT);
pinMode(EchoPin,INPUT);
pinMode(TrigPin,OUTPUT);
pinMode(E1,OUTPUT);
pinMode(E2,OUTPUT);
pinMode(servoPin,OUTPUT);
pinMode(fleft,OUTPUT);
pinMode(fright,OUTPUT);
pinMode(bleft,OUTPUT);
pinMode(bright,OUTPUT);
pinMode(lsensor,INPUT);
pinMode(rsensor,INPUT);
pinMode(buzz,OUTPUT);
servo(90);
}
void buzz0()
{
digitalWrite(buzz,LOW);
}
void buzz1()
{
digitalWrite(buzz,HIGH);
delay(135);
digitalWrite(buzz,LOW);
delay(135);
}
void buzz2()
{
digitalWrite(buzz,HIGH);
}
void servo(int angle) {
for(int i=0;i<50;i++){
int pulsewidth = (angle * 11) + 500;
digitalWrite(servoPin, HIGH);
delayMicroseconds(pulsewidth);
digitalWrite(servoPin, LOW);
delayMicroseconds(20000 - pulsewidth);
}
delay(100);
}
void measdist()
{
digitalWrite(TrigPin,LOW);
delayMicroseconds(10);
digitalWrite(TrigPin,HIGH);
delayMicroseconds(10);
digitalWrite(TrigPin,LOW);
distance = pulseIn(EchoPin,HIGH);
distance = distance / 58;
}
void scsr()
{
measdist();
lval = digitalRead(lsensor);
rval = digitalRead(rsensor);
if(distance<40||lval==0||rval==0)
{
car_stop();
servo(165); //舵机左转
delay(1000);
measdist();
distance_left = distance;
distance_left = distance_left / 58;
servo(0);//舵机右转
delay(1000);
measdist();
distance_right = distance;
distance_right = distance_right / 58;
servo(90);//舵机转回中间
delay(1000);
if(distance_left<distance_right)
{
car_back();
delay(500);
car_right();
delay(450);
car_stop();
}
else
{
car_back();
delay(500);
car_left();
delay(450);
car_stop();
}
}
else
{
car_up();
}
}
void car_left()
{
digitalWrite(M1,HIGH);
digitalWrite(M2,HIGH);
analogWrite(E1,80);
analogWrite(E2,0);
digitalWrite(fleft,HIGH);
digitalWrite(fright,LOW);
digitalWrite(bleft,HIGH);
digitalWrite(bright,LOW);
buzz1();
}
void car_right()
{
digitalWrite(M1,HIGH);
digitalWrite(M2,HIGH);
analogWrite(E1,0);
analogWrite(E2,80);
digitalWrite(fright,HIGH);
digitalWrite(fleft,LOW);
digitalWrite(bleft,LOW);
digitalWrite(bright,HIGH);
buzz1();
}
void car_up()
{
digitalWrite(M1,HIGH);
digitalWrite(M2,HIGH);
analogWrite(E1,85);
analogWrite(E2,85);
digitalWrite(fleft,HIGH);
digitalWrite(fright,HIGH);
digitalWrite(bleft,LOW);
digitalWrite(bright,LOW);
buzz0();
}
void car_back()
{
digitalWrite(M1,LOW);
digitalWrite(M2,LOW);
analogWrite(E1,85);
analogWrite(E2,85);
digitalWrite(bleft,HIGH);
digitalWrite(bright,HIGH);
digitalWrite(fleft,LOW);
digitalWrite(fright,LOW);
buzz2();
}
void car_stop(){
digitalWrite(M1,LOW);
digitalWrite(M2,LOW);
analogWrite(E1,0);
analogWrite(E2,0);
digitalWrite(fleft,HIGH);
digitalWrite(fright,HIGH);
digitalWrite(bleft,HIGH);
digitalWrite(bright,HIGH);
buzz1();
}
void loop()
{
scsr();
}
本文手稿原作者:小花生
本文的修改 / 网络排版 / 网络码字:小花生父亲
以下是原作手稿的一部分截图: