美丽的校园、灵秀的求索溪,如果小溪里有一条船,荡漾其中,势必会引来路人的目光。我们在一个明媚的午后,相约分别从寝室、教室和图书馆走出来,放下了教科书,拿起榔头、锯子、电烙铁,还有万能胶,打造了一条木质小船,加上Arduino电控,然后放到水中,玩了玩遥控船的游戏。通过这样的科技娱乐活动,或许可以学到一些知识,体验到一种课本以外的实践经历。
因为之前完全没有造船经验、又要求手工制作,而且经费还有限,所以, 遥控船的打造实在是一件不容易的事。用最方便、最原始的工具,以及木块、木皮和万能胶材料,硬是把它做出来了。起初一直担心,船体内的电机与船外的螺旋桨的连接轴孔部分,如果处理不好,容易漏水,后来用黄油填满了轴孔,这样才把防水的问题解决了。但是实际测试时,才发现了新的问题,由于船体制作得比较狭长,就像玩具商店里买的静态航模一样的比例,后来发现小船老是往一个方向打转。原因很简单,由于纯手工活,船的长度方向上的中心线不能居中于船后方的两个螺旋桨。如果当初能把船体做宽些就好了,因为船体宽,布局两个螺旋桨时,它们的中心距可以拉开些,这样产生的扭转力矩会增大,而且船的中心线也容易做到相对居中。好在电控是用Arduino单片机控制,可以通过软件,给两个螺旋桨设置不同的转速来纠偏,我们通过验证,这种方法很奏效。
相对小船机械部分的手工制作,电控部分的添加就容易得多,因为有利器---Arduino,一种易学易用的开源单片机硬件,它还配置了丰富的周边电子积木,根据说明书把它们正确连线,再把我演练过多次的遥控程序,下载到Arduino,接上电源,然后一次就运行成功了。
遥控船视频:

美丽的校园和灵秀的求索溪:


国外乐高大牛的遥控船:
(这个船用的是全套乐高设备,是早期“明轮船”的方案,设计得有创意,是否可以按照这样的思路也做个Arduino遥控船呢。)
这次依然是全套的DFRobot公司的Arduino电子积木,小船上的电控由Arduino UNO控制板、XBee传感器扩展板V5、APC220无线数传和 2A大功率H桥 L298N双路直流电机驱动板组成,遥控器由Arduino UNO控制板、PS2游戏杆扩展板、APC220无线数传组成。对于PS2游戏杆扩展板的使用,可以参看我的博客文章,网址:http://blog.chinaaet.com/detail/28854.html。APC220使用参见网址:http://blog.chinaaet.com/detail/25849.html。这篇文章新出现的电控积木是 2A大功率H桥 L298N双路直流电机驱动板(DF-MD V1.3),所以下面重点讲讲。
这个直流电机驱动板是为了做ROBOT而开发的东东。当然,如果你有更好的想法,比如用于驱动步进电机也行。这个DF-MD V1.3大功率直流电机驱动板增加了散热器,可以承受更大的电流;控制端口为4个,这样可以节约控制器端口,而且控制方式也更为简单。采用LGS公司优秀大功率电机专用驱动芯片L298N,可直接驱动直流电机,驱动电流达2A。
驱动板产品说明书网址:http://goo.gl/QTfxO。
DF-MD V1.3功能图:(双击图片,可以放大观看。)

Arduino控制板与直流电机驱动板的硬件连线与电源供给:

看上图,我的标注部分,值得注意,“9V电池扣”电池单独为Arduino控制板供电,“电机驱动电源”只给298N驱动板供电,“VD=VS”跳线帽插上,“电机驱动电源”同时为驱动板的逻辑部分和电机部分供电。Arduino控制板与298N驱动板接成“共地”。
硬件端口按照上图连接好后,再把下面的Arduino程序下载到硬件控制板上,遥控船电控系统就打点妥当了。
遥控器程序:
/*主机遥控器程序任务:采集游戏杆扩展板上的PS摇杆和按键信息,处理后,
通过APC220无线数传串口,向从机遥控船发送单字符命令,这些命令分别控制
船的前后左右行走、以及调节船行驶的速度。*/
int JoyStick_X = 1; //游戏杆扩展板的PS摇杆X轴连在模拟端口1
int JoyStick_Y = 0; //游戏杆扩展板的PS摇杆Y轴连在模拟端口0
int button_Grab =3; //红色B按键连在数字端口3
int button_Release =4; //蓝色C按键连在数字端口4
//B按键控制遥控船为高速
//C按键控制遥控船为低速
int B,C;//存储游戏杆扩展板的开关量按键的当前读取值
int x,y; //存储游戏杆扩展板的模拟量PS摇杆X,Y轴的当前读取值
char flag;//存储主机向从机发送的单“字符”命令
//初始化
void setup()
{
//把游戏杆扩展板上两个按键设置为开关量输入模式
pinMode(button_Grab, INPUT);
pinMode(button_Release, INPUT);
//启动串行通信
Serial.begin(9600);//设置串行通信的波特率
}
//主程序
void loop()
{
x=analogRead(JoyStick_X);//读取PS摇杆X轴的模拟量信息
y=analogRead(JoyStick_Y);//读取PS摇杆Y轴的模拟量信息
//读取游戏杆扩展板上三个按键“是否按下”的状态
B= digitalRead(button_Grab);
C= digitalRead(button_Release);
//如果PS摇杆Y轴向前摇动
if(y>812)
{
//向从机遥控船发送前进命令
flag='a';
Serial.print(flag);
}
//如果PS摇杆Y轴向后摇动
else if(y<212)
{
//向从机遥控船发送后退命令
flag='b';
Serial.print(flag);
}
//如果PS摇杆X轴向左摇动
else if(x>812)
{
//向从机遥控船发送左转命令
flag='c';
Serial.print(flag);
}
//如果PS摇杆X轴向右摇动
else if(x<212)
{
//向从机遥控船发送右转命令
flag='d';
Serial.print(flag);
}
//如果B按键为按下状态,同时C按键为松开状态
else if((B ==LOW)&&(C==HIGH))
{
//向从机遥控船发送“高速”行驶命令
flag='e';
Serial.print(flag);
}
//如果C按键为按下状态,同时B按键为松开状态
else if((C==LOW)&&(B==HIGH))
{
//向从机遥控船发送“低速”行驶命令
flag='f';
Serial.print(flag);
}
else
{flag='n';
Serial.print(flag);//向从机遥控船发送停止命令
}
delay(20);//延时,等待数据发送成功
}
遥控船程序:
//L298N直流电机驱动板与Arduino控制板的端口连接设置
int E_right =5; //连接电机1的使能端口到数字接口5
int M_right =4; //连接电机1的转向端口到数字接口4
int E_left =6;//连接电机2的使能端口到数字接口6
int M_left=7; //连接电机2的转向端口到数字接口7
int val;//存储遥控器主机向遥控车上的从机发送数据
/*由于船的机械结构是纯手工打造,而且船体狭长,船的中心线不与
船后方的两个螺旋桨居中,所以如果驱动螺旋桨的两个电机转速一样,
会使船偏转打转,于是把两个电机的转速设置得不同,用来纠偏。
左右螺旋桨电机的具体值应该实验来确定。*/
float velocity1=250;//右螺旋桨电机速度调节
float velocity2=200;//左螺旋桨电机速度调节
float velocity=250;//转弯时船速调节
void setup() //初始化
{
//给各数字接口设置输入输出状态
pinMode(M_right, OUTPUT);
pinMode(E_right, OUTPUT);
pinMode(M_left, OUTPUT);
pinMode(E_left, OUTPUT);
//启动串行通信
Serial.begin(9600);//设置串行通信的波特率
}
void advance()//船前进
{
digitalWrite(M_right,HIGH);
analogWrite(E_right,int(velocity1));
digitalWrite(M_left,HIGH);
analogWrite(E_left,int(velocity2));
}
void back()//船后退
{
digitalWrite(M_right,LOW);
analogWrite(E_right,int(velocity1));
digitalWrite(M_left,LOW);
analogWrite(E_left,int(velocity2));
}
void left()//船左转
{
digitalWrite(M_right,HIGH);
analogWrite(E_right,int(velocity));
digitalWrite(M_left,LOW);
analogWrite(E_left,int(velocity));
}
void right()//船右转
{
digitalWrite(M_right,LOW);
analogWrite(E_right,int(velocity));
digitalWrite(M_left,HIGH);
analogWrite(E_left,int(velocity));
}
void Stop()//船停止
{
digitalWrite(E_right, LOW); //右电机停
digitalWrite(E_left, LOW); //左电机停
}
//主程序
void loop()
{
if(Serial.available()>0) //查询串口有无数据
{
val=Serial.read();//读取遥控器主机发送的数据
if(val=='a')//如果主机发送字符'a',
{
advance();//前进
}
if(val=='b')//如果主机发送字符'b',
{
back();//后退
}
if(val=='c')//如果主机发送字符'c',
{
left();//左转
}
if(val=='d')//如果主机发送字符'd',
{
right();//右转
}
if(val=='n')//如果主机发送字符'n',
{
Stop();//停止
}
if(val=='e')//如果主机发送字符'e',
{
velocity1=250;//船速度设置为高速
velocity2=200;
}
if(val=='f')//如果主机发送字符'f',
{
velocity1=200;////船速度设置为低速
velocity2=150;
}
}
}
同样的硬件配置,同样的程序设计,既可以用在遥控船上,也可以控制遥控车,下面就是采用慧鱼积木作为车体的遥控车图片和视频。