我的第一个机器人
以我的视角拍摄的机器人
以机器人自身的视角拍摄的
虽然迟了4年,但是我终于完成了我的第一台机器人的安装和配置。
- 基于Arduino的Duemilanove开发板
- 可以躲开障碍物继续前进(有距离探测器,与障碍物的距离小于20cm时会自动转向)
- 4轮驱动
我回忆了一下,这块板子和外设是我2010年3月在昆明的时候买的,那段时间对硬件突然有了极高的热情,但是买了之后准备开始之际,发现了几点困难:
- 当时航空管制,电池不能空运,因此网购的小车没有电池
- 缺乏基本的硬件常识,四个电机如何接在两个电机端口上
- 不会焊接电机
- 没有买杜邦线,没有测试用的面包板
基于这些困难,又加上我当时在找工作,准备面试之类,机器人的制造就放了下来。结果一放就是4年,中途从昆明搬家回到西安,不过细心的孙曼思将那一大包的零部件都打包好带了回来,多亏她认真负责的态度,才让这个机器人的产生有了可能。
ThoughtWorks西安硬件小组
2013年,在ThoughtWorks的西安Office有了硬件小组,他们研究开源硬件,以及这些小芯片在实际环境中的应用。比如RCA的高亮,做出了一个“半自动”地移动上的story的产品。2014年Hackday的时候,CASA团队又做出了一个看房机器人Dora,dora可以在房间中移动,由于装置了一个摄像头,因此可以实时的看到它看到的东西,而且Dora有安装了无线模块,你可以在远程操控它并得到实时图像。
好了,这么多铺垫事实上是有意义的,如果没有西安Office的硬件小组,我的这个机器人的诞生可能又需要若干年。它给我提供了丰富的资源,比如:
- 有丰富硬件经验的张新宇,高亮,王超,可以让我很容易问问题并得到答案
- 张新宇帮我焊了一个电源的接头
- 王超提供了一个7.2V的电池
- 高亮的百宝箱中有一个9V电池盒
- CASA团队桌子上开发Dora的一些下脚料
- 杜邦线,热缩管,电烙铁,松香,镊子,钳子,各种螺丝刀等等
4年 vs 4天
虽然拖的时间很长(4年),但是事实上加起来搭建它的所有时间差不多是4天。
- 单独测试URM模块
- 单独测试电机驱动L298N模块
我发现,其实硬件开发和软件一样,化分模块,小步前进,测试,持续集成等等概念可以很好的运用其中,而且效果极好,比如我的小车基本上可以划分为这样几个小功能的逐步实现:
- 测距模块的单独启动
- 测距模块控制一个LED(距离小于5cm,点亮一个LED)
- 电机的单独启动(正转,反转)
- 测距模块控制电机(距离小于5cm,转动电机)
- 多个电机联合(如何联线)
- 测距模块控制多个电机
当到达最后一步时,基本上所有要验证的功能都已经就绪了,只需要拼装在小车的底座上,进行集成测试即可。其实,当划分好任务之后,每一个小的任务都不会花费很多时间。
故障
当我兴高采烈的去掉USB线,加上一个7.2V的电池给整个系统时,URM37测距模块伴随着浓郁的电器焦味中烧坏了,就是因为一个跳线的连接不当。这个系统中,电机需要单独加电,但是由于我自己电气知识的匮乏,导致了这个悲剧的发生。
不过,我又在Office的CASA团队的桌子上发现了另外一个测距模块,不过这次只经过了15分钟就完成了替换掉了老板子,换上了新的测距模块。
#include <NewPing.h>
#define TRIGGER_PIN 12 // 12端口
#define ECHO_PIN 11 // 11端口
#define MAX_DISTANCE 400
int ledpin = 13;
NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE);
void setup() {
Serial.begin(9600); // Sets the baud rate to 9600
pinMode(ledpin, OUTPUT); //设置13号口为输出
}
void loop()
{
unsigned int uS = sonar.ping(); // 把扫描时间转化成us
int dis = uS / US_ROUNDTRIP_CM; //转成距离
if (dis <= 20) {
digitalWrite(ledpin, HIGH);
} else {
digitalWrite(ledpin, LOW);
}
Serial.print("Distance = ");
Serial.println(dis);
delay(150);
}
安装过程
测距模块很早之前就已经整理过了,可以看看这里。不过我最后的成品已经没有使用URM37了,取而代之的是HC-SR04。
连接电机与电机驱动模块:
第一次焊接电机,话说这种电机的触头也太粗糙了吧,不自己焊接的话,根本就用不成,完全没有进入模块化世界。
连接之后
装车
最终的代码
#include <NewPing.h>
#define TRIGGER_PIN 12 // 12端口
#define ECHO_PIN 11 // 11端口
#define MAX_DISTANCE 400
int E1 = 6;
int M1 = 7;
int E2 = 5;
int M2 = 4;
int ledpin = 13;
void setup() {
Serial.begin(9600); // Sets the baud rate to 9600
pinMode(ledpin, OUTPUT); //设置13号口为输出
pinMode(M1, OUTPUT);
pinMode(M2, OUTPUT);
digitalWrite(ledpin, LOW); //灭掉LED
delay(200); //Give sensor some time to start up --Added By crystal from Singapo, Thanks Crystal.
}
void advance() {
digitalWrite(M1,HIGH);
digitalWrite(M2,HIGH);
analogWrite(E1, 200);
analogWrite(E2, 200);
}
void backoff() {
digitalWrite(M1,LOW);
digitalWrite(M2,LOW);
analogWrite(E1, 200);
analogWrite(E2, 200);
}
void left() {
digitalWrite(M1,LOW);
digitalWrite(M2,HIGH);
analogWrite(E1, 150);
analogWrite(E2, 150);
delay(1000);
}
void right() {
digitalWrite(M1,HIGH);
digitalWrite(M2,LOW);
analogWrite(E1, 150);
analogWrite(E2, 150);
delay(1000);
}
void stop() {
analogWrite(E1, 0);
analogWrite(E2, 0);
}
NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE);
void loop()
{
unsigned int uS = sonar.ping(); // 把扫描时间转化成us
int dis = uS / US_ROUNDTRIP_CM; //转成距离
if (dis <= 20) {
stop();
left();
delay(30);
digitalWrite(ledpin, HIGH);
} else {
advance();
delay(30);
digitalWrite(ledpin, LOW);
}
Serial.print("Distance = ");
Serial.println(dis);
delay(150);
}
体会
- 和开发软件一样,硬件开发也可以使用“敏捷开发”
- 实用主义,比如bluetip的使用,杜邦线拼接等
- 迭代开发,小步快跑