玄学的胜利–记Botball中国区域赛(第一天)

开学初学校老师通知我们有这样一个比赛,当时我们的社团刚组建了一个学期多一点,一直苦于没有好的项目去做,都是处于自娱自乐做些小东西的情况(之前想过做探空气球,全自动四轴飞行器之类的,不过这样的项目一方面需要耗费大把的时间和精力,另一方面也需要学校的支持,但问题是我们那时已经高二了没有那么多的时间,而且在我们学校学生社团一向不受待见…..)现在终于有机会能和小伙伴们一起完成一个完整的工程。

虽然这样的比赛对于我们的知识储备来说并不成问题,但实际操作起来还是困难得多….从拿到规则和任务起历经近三个月时间,我们逃了各种午自习体育课合唱比赛来准备,终于把这两个机器人给做出来了。而且由于全自主机器人的特性,整个比赛过程更是一波三折,充满了各种各样的冷门及灵异事件(这也就是为什么我们把它叫做玄学比赛)。

P.S.这个比赛今年第一次引入中国,似乎还不是很普及,如果想要了解请访问:

国际组委会:botball.org

中国组委会:botball.itccc.org.cn

Continue reading “玄学的胜利–记Botball中国区域赛(第一天)”

基于arduino的遥控机械臂机器人的设计方案|完成度:85%

基于arduino的遥控机械臂机器人的设计方案|完成度:85%

完成度:85%

原理图:

成品图:

 

这个项目分为以下几个部分来实施:

已解决:

使用L298N扩展板驱动直流电机:这个之前已经研究过了,详见:https://blog.nyan.imposts/301.html

驱动舵机控制机械臂:舵机可以直接插在我准备使用的sensor shield v6 上,并且通过arduino的舵机库servo.h来驱动。

无线数传:我之前考虑过通过wifi、蓝牙、fm、2.4g和红外遥控等方式来进行控制。本来已经确定使用wifi来进行控制,这样的话一种选择是自己改装openwrt路由器,引出串口,另一种是买wifi扩展板,但是tb上的wifi扩展版价格贵得离谱……于是放弃了这一方案,最后选定了apc220无线数传模块,虽然贵了点,但是跟xbee的模块比已经很良心了…最重要的是很多代码都是现成的,而且传感器扩展上都有现成的接口。

待解决:

串口通讯:在这个项目中我需要从上位机通过串口给arduino发送指令。arduino ide中内置有进行串口通讯的函数,这个很好解决。但是为了方便操作,我可能需要编写一个上位机控制程序,捕捉键盘的输入,然后将按照预先的设置将指令通过串口发送给arduino。

无线摄像头:我找了一圈发现不管2.4g还是wifi摄像头的驱动要么不支持win8,要么根本不支持64位…>< 这不是作死嘛…难道让我一边开着虚拟机一边调试么..果断放弃…后来又考虑过把摄像头模块接在arduino上然后通过串口回传,但是uno的性能对于处理视频有些吃力….于是干脆不要摄像头了,等找到合适的方案了后期再加上就是了..

需要使用的配件:
arduino uno
apc220 无线数传模块
Xbee传感器扩展板V6
电池组x3
5自由度机械臂套装
995舵机x4
996舵机x1
杜邦跳线
机器人底盘
L298N直流电机驱动板

 

——————————————————————————————————————–

09.17

arduino的io扩展板v7和apc220无线模块收到了,赶紧插上测试了一遍….io扩展板使用很方便,舵机的3个引脚可以直接插在上面,这样就不用在面包板上连各种乱七八糟的线了。但是有一个问题,就是每次从电脑向arduino上传代码的时候都必须把扩展板拿掉,不然会提示串口被占用….

(后来我弄明白了在io扩展板上有一个 RUN/PROG的小开关,用于切换运行和编程 模式。在下载代码或进行串口通讯的时候需要把开关拨到PROG位置,不然扩展板会占用Rx和Tx从而导致下载或通讯失败。)

APC220的无线模块让我很怨念….我在买的时候看这个模块很流行(很多教程和文章中都提到或使用了这个模块),就没问兼容性的问题。拿到之后才发现装驱动虽然能装上,但是设备管理器中始终显示问号……问了卖家之后才知道这货的驱动不兼容win8…..于是我就只能苦逼地在xp虚拟机下操作了…..

——————————————————————————————————————–

09.18

我把机械臂的套件按照卖家给的安装图安装上了,装完之后才发现我买的5自由度的版本的爪子不能在平面内转动…..早知道就买6自由度的版本了…

装完之后做了些简单的测试,比如用一个for循环让角度从0-180 度依次叠加,然后用servo库将角度值写入舵机。

servo库使用很简单,例如:

#include <Servo.h>     //导入舵机库

Servo servo1;    //定义一个舵机对象

void setup(){

servo1.attach(3);          //将这个舵机对象链接到引脚3(必须pwm引脚)

}

void loop(){

servo1.write(90);          //写入90度角度值

}

我本来想把安装机械爪的舵机安装成水平转动的(像图中那样),但是这种结构实在是太不稳定了,所以我就只好老老实实按照安装图来装了.

图

 

09.28

组装好了之后我要想办法把机械臂装到底盘上去…..但我实在不想吐槽底盘上的螺丝孔设计得实在是太猎奇了…..我试了半天总算找到了两个能对上的孔….

然后我就发现了一个更严重的问题….底盘太小,机械臂太重,舵机随便动一下整个装置就倒了….于是我就华丽丽地放了两个哑铃片上去…

(注意:不要把arduino以及任何电路板直接放在导体上,否则底部的引脚短路了就神作了)

09.29

机械部分组装好之后按照上面的原理图把各个模块连起来…然后将【这个文件】中的代码写入Arduino。(代码尚不完善,仅供参考)

我使用的引脚是:

servo1:3

servo2:5

servo3:6

servo4:9

servo5:10

ENA:11

I1:7

I2:8

ENB:12

I3:2

I4:4

为了省事我直接使用了Serial.read()函数,这样每个指令只需要通过串口读入一个字节,就不需要折腾缓冲区什么的了..如果谁知道怎么让arduino读取一段字符串,请告诉我,万分感谢。

现在我有一个想法,就是使用c/c++编写一个上位机的程序,每当键盘按下一个键,就把这个字符发送到串口,但是目前还没有找到合适的解决方案。

【教程】制作基于Arduino的避障小车

项目简介:

在这个项目中我们使用一个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度掉头并向前行驶,机器人在运行过程中会遇到各种异常情况,所以在代码中一定要考虑到异常情况的处理;