Randy 发表于 2012-4-18 08:54:55

Arduino一个简单的小车(实现测距和避障功能—可以自行DIY)

本帖最后由 Randy 于 2012-4-18 08:57 编辑

       首先申明,这个帖子是转别人的,仅供大家一起学习用。这个小车很简单,超声波测量前方距离,Arduino 根据超声波模块接受的距离控制小车前进、后退或者左转右转。也就是说它有自己的“思维”方式,只要打开电源在没有人干预的情况下可以独自在房间里闲逛而不会碰到任何东西。


先上一些整体图片:








如果你也对这个有兴趣那么可以和我一起来制作这样一个ROBOT。

材料准备:



1、arduino 板子一个,我使用的是 arduino duemilanove 2009 - ATMega328P,因为我觉得这个性价比最高。Arduino UNO 也可以。




2、 超声波测距模块一个


3、 直流电机 + 轮胎




4、 L298N电机驱动模块 一个 电机驱动最好带光耦的,否则可能会对超声波信号产生干扰





5、万向轮 + 小车底盘 + 杜邦线 + 螺丝、螺母 + 烙铁 + 螺丝刀 + 剪刀等

      万向轮可以去淘宝购买

      小车底盘是用来固定电机和电路板的,可以选用PVC板自己动手制作也可以买现成的



    材料都有了就可以将它们链接起来。接线方式可以从程序的注释中看出来,本来准备用舵机控制超声波模块转向的,后来觉得舵机固定比较麻烦就没用,android程序如下:#define DEBUG 0    // set to 1 to print to serial monitor, 0 to disable
#include <Servo.h>

Servo headservo;// 头部舵机对象

// Constants
const int EchoPin = 2; //超声波信号输入
const int TrigPin = 3; //超声波控制信号输出

const int leftmotorpin1 = 4; // 直流电机信号输出
const int leftmotorpin2 = 5;
const int rightmotorpin1 = 6;
const int rightmotorpin2 = 7;

const int HeadServopin = 9; // 舵机信号输出 只有9或10接口可利用
const int Sharppin = 11; // 红外输入

const int maxStart = 800;//run dec time

// Variables
int isStart = maxStart;    //启动
int currDist = 0;    // 距离
boolean running = false;

void setup() {

Serial.begin(9600); // 开始串行监测

//信号输入接口
pinMode(EchoPin, INPUT);
pinMode(Sharppin, INPUT);

//信号输出接口
for (int pinindex = 3; pinindex < 11; pinindex++) {
    pinMode(pinindex, OUTPUT); // set pins 3 to 10 as outputs
}

//舵机接口
headservo.attach(HeadServopin);

//启动缓冲活动头部
headservo.write(70);
delay(2000);
headservo.write(20);
delay(2000);
}

void loop() {

if(DEBUG){
    Serial.print("running:");
    if(running){
      Serial.println("true");
    }
    else{
      Serial.println("false");
    }
}

if (isStart <= 0) {
    if(running){
      totalhalt();    // stop!
    }
    int findsomebody = digitalRead(Sharppin);
    if(DEBUG){
      Serial.print("findsomebody:");   
      Serial.println(findsomebody);   
    }   
    if(findsomebody > 0) {
      isStart = maxStart;
    }
    delay(4000);
    return;
}
isStart--;
delay(100);

if(DEBUG){
    Serial.print("isStart: ");
    Serial.println(isStart);
}

currDist = MeasuringDistance(); //读取前端距离

if(DEBUG){
    Serial.print("Current Distance: ");
    Serial.println(currDist);
}

if(currDist > 30) {
    nodanger();
}
else if(currDist < 15){
    backup();
    randTrun();
}
else {
    //whichway();
    randTrun();
}
}

//测量距离 单位厘米
long MeasuringDistance() {
long duration;
//pinMode(TrigPin, OUTPUT);
digitalWrite(TrigPin, LOW);
delayMicroseconds(2);
digitalWrite(TrigPin, HIGH);
delayMicroseconds(5);
digitalWrite(TrigPin, LOW);

//pinMode(EchoPin, INPUT);
duration = pulseIn(EchoPin, HIGH);

return duration / 29 / 2;
}

// 前进
void nodanger() {
running = true;
digitalWrite(leftmotorpin1, LOW);
digitalWrite(leftmotorpin2, HIGH);
digitalWrite(rightmotorpin1, LOW);
digitalWrite(rightmotorpin2, HIGH);
return;
}

//后退
void backup() {
running = true;
digitalWrite(leftmotorpin1, HIGH);
digitalWrite(leftmotorpin2, LOW);
digitalWrite(rightmotorpin1, HIGH);
digitalWrite(rightmotorpin2, LOW);
delay(1000);
}

//选择路线
void whichway() {
running = true;
totalhalt();    // first stop!

headservo.write(20);
delay(1000);
int lDist = MeasuringDistance();   // check left distance
totalhalt();      // 恢复探测头

headservo.write(120);// turn the servo right
delay(1000);
int rDist = MeasuringDistance();   // check right distance
totalhalt();      // 恢复探测头

if(lDist < rDist) {
    body_lturn();
}
else{
    body_rturn();
}
return;
}

//重新机械调整到初始状态
void totalhalt() {
digitalWrite(leftmotorpin1, HIGH);
digitalWrite(leftmotorpin2, HIGH);
digitalWrite(rightmotorpin1, HIGH);
digitalWrite(rightmotorpin2, HIGH);
headservo.write(70);//set servo to face forward
running = false;
return;
delay(1000);
}

//左转
void body_lturn() {
running = true;
digitalWrite(leftmotorpin1, LOW);
digitalWrite(leftmotorpin2, HIGH);
digitalWrite(rightmotorpin1, HIGH);
digitalWrite(rightmotorpin2, LOW);
delay(1500);
totalhalt();
}

//右转
void body_rturn() {
running = true;
digitalWrite(leftmotorpin1, HIGH);
digitalWrite(leftmotorpin2, LOW);
digitalWrite(rightmotorpin1, LOW);
digitalWrite(rightmotorpin2, HIGH);
delay(1500);
totalhalt();
}

void randTrun(){
long randNumber;
randomSeed(analogRead(0));
randNumber = random(0, 10);
if(randNumber > 5) {
    body_rturn();
}
else
{
    body_lturn();
}
}
我一直想拥有自己的一辆小车,也正准备动手去组装,调试了,我们论坛的三水、奈何他们已经早玩了,我还是第一次去接触,有时间去向三水妹纸学习学习!

vigiles 发表于 2012-4-18 23:42:24

小车很可爱啊

幻生幻灭 发表于 2012-7-6 17:04:41

电机是扎带固定?

Randy 发表于 2012-7-6 17:48:30

幻生幻灭 发表于 2012-7-6 17:04 static/image/common/back.gif
电机是扎带固定?

是的,工程用的那种扎带!蛮好用的!

幻生幻灭 发表于 2012-7-6 19:09:02

Randy 发表于 2012-7-6 17:48 static/image/common/back.gif
是的,工程用的那种扎带!蛮好用的!

个人认为 扎带不靠谱,呵呵
受外力作用会导致电机移位

Randy 发表于 2012-7-6 23:03:31

幻生幻灭 发表于 2012-7-6 19:09 static/image/common/back.gif
个人认为 扎带不靠谱,呵呵
受外力作用会导致电机移位

是的,那你用啥呢?推荐一下,我现在玩的小车就两辆,到时候我弄个酷一点的。哈哈!

风轻云淡 发表于 2012-7-7 08:39:22

不错真吊:D

幻生幻灭 发表于 2012-7-7 08:41:21

最好还是L型的铝合金支架,当然如果纯娱乐,可以采用我们盒仔的结构,都比扎带简单
图纸在Github上免费下载

Randy 发表于 2012-7-7 09:12:52

风轻云淡 发表于 2012-7-7 08:39 static/image/common/back.gif
不错真吊

呵呵,看起来还算是比较清秀的哪一种,没有很复杂!可以试试!

风轻云淡 发表于 2012-7-8 18:13:41

Randy 发表于 2012-7-7 09:12 static/image/common/back.gif
呵呵,看起来还算是比较清秀的哪一种,没有很复杂!可以试试!

是啊你有电路不我也试试

Randy 发表于 2012-7-9 09:02:03

风轻云淡 发表于 2012-7-8 18:13 static/image/common/back.gif
是啊你有电路不我也试试

我都是有现成的模块了,搭建一下就好了!

夏异 发表于 2012-7-14 19:59:45

我也打算做一个蔽障小车,只不过才刚接触Arduino,不懂的地方还希望楼主多多指教。

Randy 发表于 2012-7-14 23:57:10

夏异 发表于 2012-7-14 19:59 static/image/common/back.gif
我也打算做一个蔽障小车,只不过才刚接触Arduino,不懂的地方还希望楼主多多指教。

呵呵,一起学习,我也不是很厉害,一起参与交流会懂得越多!

piaozhiling 发表于 2012-7-15 02:39:29

朋友,厉害,没有录制一个视频啊

Randy 发表于 2012-7-15 07:47:50

piaozhiling 发表于 2012-7-15 02:39 static/image/common/back.gif
朋友,厉害,没有录制一个视频啊

不好意思,没有视频哦!只要有现有的模块,拼在一起就不难了!
页: [1] 2 3 4 5
查看完整版本: Arduino一个简单的小车(实现测距和避障功能—可以自行DIY)