蓝牙遥控船存记

费时三天的蓝牙遥控船基本告一段落了。原本想做个小车,无奈风力不足,万向轮不合适的原因,加之自己不想耗费太多时间在机械结构的处理上,所以决定到此为止。

Markdown

设计耗材

  • 89C51最小系统板一个
  • HC-05蓝牙模块一个
  • 712空心杯电机两个
  • S9013三极管四个
  • USB-TO-TTL模块一个
  • 杜邦线若干
  • 万能板9cm 15cm、5cm 9cm各一块
  • 空纯牛奶盒三个
  • (小的移动电源一个)

实现功能

  • 数字0:停止
  • 数字1:启动
  • 数字2:加速
  • 数字3:减速
  • 数字4:左转
  • 数字5:右转
  • 数字6:加大转向幅度
  • 数字7:降低转向幅度

整体设计思路

手机通过蓝牙发送不同数字(01234567),蓝牙模块接收到数据后分析并对应不同动作指令使51单片机P1.0和P1.1两端口产生模拟PWM信号(采用简单延时解决)控制三极管开关从而控制电机转动,通过同时对两端口PWM占空比的调整来改变小船直行的速度;通过对两端口占空比分别调整,采用差速法实现左转右转;另外,左转右转的幅度调节单独由发送数字决定。
硬件设计上,通过在大的万能板底部粘贴空牛奶盒实现基本船体搭建;船板上放置各模块,小万能板竖直粘贴在船尾,电机旋桨平行小的万能板垂直大的万能板。(本设计采用旋桨悬空的方式避免直接与水体接触,这也是为何开头处提到风力不足的原因)
另外,硬件上一大难点为三极管电路。因为51单片机输出电流极其微弱,高电平输出仅不到10mA,所以必须用到三极管放大以满足电机电流需要;该处各采用两个NPN三极管搭建电流放大电路(此处说的电流放大实际上是三极管的开关状态)。

三极管电流放大电路

另外,采用双H桥电路可以实现电机反转,图中分别对AD和BC分别控制开关,实现电机反向。感兴趣可以尝试。

双H桥三极管电路

(因为博主电路设计能力极其薄弱,在这个三极管放大电路设计上,博主花了整个设计的一半时间,深为惭愧)
软件设计上,对蓝牙接受到的数据进行简单的switch判断,对应不同动作,其中直行、左转、右转都使用一个函数,但以函数的第二个参数决定。

具体代码实现

#include<reg51.h>
//全局变量及子函数声明****************************
void UsartConfiguration();
void delay1ms(unsigned int x);
void moving(unsigned int bili,unsigned int fangxiang);
unsigned int value=0,extra=1,FLAG=1;
//端口定义**************************************
sbit L1=P1^0;
sbit L2=P1^1;
//主函数*****************************************
void main()
{ unsigned int T=50;
L1=0;L2=0;
UsartConfiguration();
while(1)
{
FLAG=1;
switch(value)
{
case 0:L1=0;L2=0;T=50;break;
case 1:while(FLAG){moving(T,2);}break;
case 2:T=T+5;while(FLAG){moving(T,2);}break;
case 3:T=T-5;while(FLAG){moving(T,2);}break;
case 4:while(FLAG){moving(T,0);}break;
case 5:while(FLAG){moving(T,1);}break;
default: break;
}
}
}
//小船移动函数**************************************
void moving(unsigned int bili,unsigned int fangxiang)
{
L1=1;
L2=1;
delay1ms(bili);
if(fangxiang == 0)
{
L1=1;
L2=0;
delay1ms(extra*10);
L1=0;
L2=0;
delay1ms(100-extra*10-bili);
}
else if(fangxiang == 1)
{
L1=0;
L2=1;
delay1ms(extra*10);
L1=0;
L2=0;
delay1ms(100-extra*10-bili);
}
else
{
L1=0;
L2=0;
delay1ms(100-bili);
}
}
//延时函数**************************************
void delay1ms(unsigned int x)
{
unsigned int i,j;
for(i=0;i<x;i++)
for(j=0;j<120;j++);
}
//串口配置**************************************
void UsartConfiguration()
{
SCON=0X50; //设置为工作方式1
TMOD=0X20; //设置计数器工作方式2
TH1=0XFD; //9600
TL1=0XFD;
ES=1; //打开接收中断
EA=1; //打开总中断
TR1=1; //打开计数器
}
//串口中断*****************************************
void Usart() interrupt 4
{
unsigned char Data;
Data=SBUF; //出去接收到的数据
RI = 0; //清除接收中断标志位
FLAG=0;
switch(Data)
{
case 0x00: value=0;break;//停止
case 0x01: value=1;break;//启动
case 0x02: value=2;break;//加速
case 0x03: value=3;break;//减速
case 0x04: value=4;break;//左转
case 0x05: value=5;break;//右转
case 0x06: extra++;break;//幅度加
case 0x07: extra--;break;//幅度减
default: break;
}
}

以上。写于2017年2月24日