项目简介:
在这个项目中我们使用一个Arduino主控板通过红外接近传感器控制直流电机的速度及方向,来达到让小车自动避让障碍物的效果。
成品图:
器材:
Arduino主控板x1(推荐UNO,MEGA或Due);
2WD机器人底盘x1;
双H桥直流电机驱动板x1;
红外接近传感器(或超声波传感器)x2-3;
直流电机x2;
电池组x1-2;
面包板x1(可选);
杜邦跳线若干;
实施步骤:
我们将这个项目分成几部分来进行:
1.使用Arduino通过直流电机驱动板控制电机转动;
2.使用Arduino从红外接近传感器中读取数据;
3.零件的组装与电路的连接;
4.编写并调试程序;
ok,我们从第一部分开始。
我们需要先了解一下如何使用直流电机驱动板。(以L298为例)。
图片来源:robotbase.taobao.com
在这块驱动板上我们主要使用到的引脚有如下几个:
其中,上方红,绿色的引脚分别连接两个电机,下方蓝色VMS和GND引脚风别接电池组的正、负极。下方EA,EB分别为两个电机的使能引脚,输入高电平或模拟值使电机运转。I2,I1及I4,I3分别控制电机A、B的转动方向。(比如I1接低电平I2接高电平使电机顺时针转;I1接高电平I2接低电平使电机逆时针转)。
下面我们按照下图连接电路,
将以下代码输入Arduino IDE:
int pinI1 = 2; //定义I1
int pinI2 = 4; //定义I2
int speedpin = 3; //定义EA
void setup() {
//将以上引脚设为输出
pinMode(pinI1, OUTPUT);
pinMode(pinI2, OUTPUT);
pinMode(speedpin, OUTPUT);
}
void loop() { //使电机以全速的39%顺时针运转2秒
digitalWrite(pinI1, LOW);
digitalWrite(pinI2, HIGH);
analogWrite(speedpin, 100); //这个值用于PWM调速,介于1-255之间
delay(2000); //延时2000毫秒
//逆时针运转2秒
digitalWrite(pinI1, HIGH);
digitalWrite(pinI2, LOW);
analogWrite(speedpin, 100);
delay(2000);
}
如果没有发生错误,电机将会顺时针转动两秒,然后逆时针转动两秒,然后循环。
我们已经知道了如何通过电机驱动板来控制电机旋转,然后我们需要使用红外接近传感器来判断障碍物。
我使用的是如图的传感器,
引脚定义为:
红色–5v电源;
绿色–接地;
黄色–输出,无障碍物时输出高电平,有障碍物时输出低电平;
下面我们来进行测试
保留上面的电路,然后将红色线接入5v(vin或5v)输出,绿色线接GND引脚,黄色线接11引脚。
输入以下代码:
int inpin = 11;
int pinI1 = 2;
int pinI2 = 4;
int speedpin = 3;
void setup() {
pinMode(pinI1, OUTPUT);
pinMode(pinI2, OUTPUT);
pinMode(speedpin, OUTPUT);
pinMode(inpin, INPUT);
}
void loop() {
int in = digitalRead(inpin);
if ( in == LOW) {
digitalWrite(pinI1, LOW);
digitalWrite(pinI2, HIGH);
analogWrite(speedpin, 100);
}
}
将红外探头挡住,此时电机会顺时针方向运转。
了解了元件的使用方法之后,我们现在开始组装小车。
这是我使用的小车底盘:
图片来源:swbee.taobao.com/
小车的组装并不复杂,按照说明书即可。
然后按照下图连接Arduino及各元件。
将下面的代码输入IDE:
//motorpin
int pinI1 = 2;
int pinI2 = 4;
int speedpinr = 3;
int pinI3 = 7;
int pinI4 = 8;
int speedpinl = 5;
//senorpin
int inl = 11;
int inr = 12;
//int inm=9;
long ti = 0;
long s = 0;
void setup() {
//motorpin
pinMode(pinI1, OUTPUT);
pinMode(pinI2, OUTPUT);
pinMode(pinI3, OUTPUT);
pinMode(pinI4, OUTPUT);
pinMode(speedpinl, OUTPUT);
pinMode(speedpinr, OUTPUT);
//senorpin
pinMode(inl, INPUT);
//pinMode(inm,INPUT);
pinMode(inr, INPUT);
//sensor5vin
pinMode(6, OUTPUT);
digitalWrite(6, HIGH);
pinMode(A5, OUTPUT);
digitalWrite(A5, HIGH);
Serial.begin(9600);
Serial.flush();
}
void loop() {
s = s + 1;
if (s >= 120) {
s = 0;
}
Serial.print(“ = ”);
Serial.print(s);
Serial.print(“[“); Serial.print(ti); Serial.print(“]”);
//sensorM
int l = digitalRead(inl);
int r = digitalRead(inr);
// Serial.print(l);
// Serial.print(r);
if (l == HIGH && r == HIGH) {
forward();
delay(100);
}
l = digitalRead(inl);
r = digitalRead(inr);
// Serial.print(l);
// Serial.print(r);
if (l == LOW && r == LOW) {
if (s < 120 && ti >= 3) {
leftx();
} else {
reverse();
}
delay(100);
}
l = digitalRead(inl);
r = digitalRead(inr);
if (l == LOW && r == HIGH) {
right();
delay(100);
}
l = digitalRead(inl);
r = digitalRead(inr);
if (l == HIGH && r == LOW) {
left();
delay(100);
}
}
void forward() {
digitalWrite(pinI1, LOW);
digitalWrite(pinI2, HIGH);
digitalWrite(pinI3, LOW);
digitalWrite(pinI4, HIGH);
analogWrite(speedpinl, 130);
analogWrite(speedpinr, 100);
//delay(1000);
}
void right() {
digitalWrite(pinI1, LOW);
digitalWrite(pinI2, HIGH);
digitalWrite(pinI3, LOW);
digitalWrite(pinI4, HIGH);
analogWrite(speedpinl, 140);
analogWrite(speedpinr, 55);
}
void left() {
digitalWrite(pinI1, LOW);
digitalWrite(pinI2, HIGH);
digitalWrite(pinI3, LOW);
digitalWrite(pinI4, HIGH);
analogWrite(speedpinl, 55);
analogWrite(speedpinr, 135);
}
void reverse() {
digitalWrite(pinI1, HIGH);
digitalWrite(pinI2, LOW);
digitalWrite(pinI3, HIGH);
digitalWrite(pinI4, LOW);
analogWrite(speedpinl, 95);
analogWrite(speedpinr, 75);
ti = ti + 1;
delay(1500);
}
void leftx() {
digitalWrite(pinI1, LOW);
digitalWrite(pinI2, HIGH);
digitalWrite(pinI3, HIGH);
digitalWrite(pinI4, LOW);
analogWrite(speedpinl, 85);
analogWrite(speedpinr, 85);
ti = 0;
s = 0;
delay(2000);
}
然后小车即可运行,并且自动避开障碍物。
后记:
1.虽然这个代码可以正常运行,但是效率并不高;
2.由于条件所限我只使用了2个传感器,只能够满足基本的要求,如果要实现更好的效果,请使用至少3个传感器;
3.红外传感器只能探测前方有无障碍存在,并且探测距离不定,如果有条件可以使用可以精确测距的超声波传感器;
4.小车出现2个轮子不一样快是正常的,请调节EA/EB引脚的模拟值来调节速度;
5.在上面的代码中我使用了串口通信对程序进行调试(Serial打头的语句),在对arduino编程的时候用好串口调试会有很大帮助;
6.在上面的代码中我加入了一种异常处理,可以实现在一段时间(大约10秒)内连续3次触发reverse()函数,小车将会180度掉头并向前行驶,机器人在运行过程中会遇到各种异常情况,所以在代码中一定要考虑到异常情况的处理;
发表回复/Leave a Reply