最近一直在尝试用舵机带动超声波传感器寻找目标,但由于扫描的角度和小车的转向精度不够,结果总是不尽人意。
来看段视频: 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元那种)
来看小车的图片:
再来看视频: 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);
- }
复制代码
|