中科因仑“3+1”工程特种兵精英论坛
标题:
arduino 追踪小车
[打印本页]
作者:
刘登辉
时间:
2015-5-24 18:48
标题:
arduino 追踪小车
最近一直在尝试用舵机带动超声波传感器寻找目标,但由于扫描的角度和小车的转向精度不够,结果总是不尽人意。
来看段视频:
http://v.youku.com/v_show/id_XMjUzNDcxNzky.html
于是修改了项目,将小车重构,放弃四个轮子改用两个(小车灵活性大大提高),以红外线为主,超声波为辅,从目前来看效果很不错。
思路是:
设定左中右三个红外线传感器探测距离为:180mm、50mm、180mm;
如果所有红外线传感器都没检测到信号,而且超声波探测的目标距离超过了最大范围(目前是300mm),说明目标不在前方,就慢速向右转圈寻找其他方向的目标;
如果所有红外线传感器都没检测到信号,但超声波探测的目标距离小于最大范围,说明目标在前方,此时缓慢前进接近目标;
如果左侧红外线检测到目标,说明目标在左侧,则迅速左转,面向目标;
如果右侧红外线检测到目标,说明目标在右侧,则迅速右转,面向目标;
如果中间的红外线检测到目标,说明目标就在正前方,而且距离合适,搜寻完成。
硬件列表:
Arduino Diecimila / ATmega168
Arduino Sensor Shield V5.0 传感器扩展板
双 H 桥直流电机驱动板
红外线距离传感器(博光 E18-D80NK)
DC-DC
11.1V 1300mAH 聚合物锂电池
乐高积木
EMAX 9g 舵机
超声波传感器(最便宜的,35元那种)
来看小车的图片:
[attach]3504[/attach]
[attach]3505[/attach]
再来看视频:
http://v.youku.com/v_show/id_XMjU0NDkzNDM2.html
最后是源代码:
#include <MazeSensor.h>
#include <BaseCar.h>
#include <Ultrasonic.h>
#include <Servo.h>
// for Ultrasonic
const int TRIGGER_PIN = 1;
const int RESPONSE_PIN = 2;
// for Maze Sensor
const int LEFT_PIN = 7;
const int MIDDLE_PIN = 4;
const int RIGHT_PIN = 8;
// for detect Servo
const int DETECT_SERVO_PIN = 9;
// for car
const int I11_PIN = A1; // 15
const int I12_PIN = A2; // 16
const int I21_PIN = A3; // 17
const int I22_PIN = A4; // 18
const int MOTO1_PIN = 3;
const int MOTO2_PIN = 11;
// log
const boolean VERBOSE = true;
const int SERIAL_SPEED = 9600;
// for Ultrasonic
const int MAX_DISTANCE = 300;
const double C = 0.96;
// for detect Servo
const int DETECT_SERVO_CENTER_POS = 80;
// speed
const int SPEED_VAL = 150;
const int SPEED_VAL_SLOW = 100;
// direction adjustment
const int ADJ = 0;
// sensor
MazeSensor sensor(LEFT_PIN, MIDDLE_PIN, RIGHT_PIN);
// car control
BaseCar car(MOTO1_PIN, MOTO2_PIN, I11_PIN, I12_PIN, I21_PIN, I22_PIN);
// ultrasonic
Ultrasonic us(TRIGGER_PIN, RESPONSE_PIN, C);
// servo
Servo servo;
boolean targetFound = false;
void setup() {
// init servo
servo.attach(DETECT_SERVO_PIN);
changeDetectServoPos(DETECT_SERVO_CENTER_POS);
// log
if (VERBOSE) {
Serial.begin(SERIAL_SPEED);
}
}
void loop() {
int distance = us.getDistance();
int pos = detectBlockPos();
if (VERBOSE) {
Serial.print("pos = ");
Serial.print(pos);
Serial.print(", distance = ");
Serial.println(distance);
}
if (pos == 0) {
if (distance > MAX_DISTANCE) {
Serial.println("target lost, searching...");
car.rotateRight(SPEED_VAL_SLOW, ADJ);
} else {
Serial.println("target found but leaving now, following...");
car.forward(SPEED_VAL_SLOW, ADJ);
}
} else {
switch(pos) {
case 1: // left
Serial.println("target on left, turn left...");
car.rotateLeft(SPEED_VAL, ADJ);
break;
case 3: // right
Serial.println("target on right, turn left...");
car.rotateRight(SPEED_VAL, ADJ);
break;
case 2: // middle
// goal
Serial.println("target caught, haha!");
car.standBy();
break;
}
}
}
int detectBlockPos() {
// get sensor status
SensorStatus s = sensor.getStatus();
if ((!s.left_flag) && (!s.middle_flag) && (!s.right_flag)) {
// 0:no
return 0;
} else if ((s.left_flag) && (!s.middle_flag) && (!s.right_flag)) {
// 1:left
return 1;
} else if ((!s.left_flag) && (s.middle_flag) && (!s.right_flag)) {
// 2:middle
return 2;
} else if ((!s.left_flag) && (!s.middle_flag) && (s.right_flag)) {
// 3:right
return 3;
} else if ((s.left_flag) && (s.middle_flag) && (s.right_flag)) {
// 4:all
return 4;
} else if ((s.left_flag) && (s.middle_flag) && (!s.right_flag)) {
// 5:left & middle
return 5;
} else if ((!s.left_flag) && (s.middle_flag) && (s.right_flag)) {
// 6:right & middle
return 6;
}
}
void changeDetectServoPos(int pos) {
servo.write(pos);
}
复制代码
欢迎光临 中科因仑“3+1”工程特种兵精英论坛 (http://bbs.enlern.com/)
Powered by Discuz! X3.4