在犹豫是做飞机还是小车很久以后,终于选择做一个移动机器人。原因有以下几点:1,飞机消耗太大。2,飞机空机无法DIY,少了乐趣。3,场地有限。4,和我的专业结合不紧密。5,轮式驱动好控制。 生活少了许多自由的时间,所以挤挤晚上睡觉的时间花了大约3周基本实现了机器人的移动控制,视频传输。在以后会加上机械臂,各种传感器,如果有可能还会弄弄视觉识别。 之所以说是移动机器人,是因为本身的定位比较高,我不希望用廉价的材料做出一个试验型的小车。我要做就做实用的,一步到位的。钱倒不是什么问题,每个月的钱就够买材料的。只是很多机械结构没有条件自己做,所以只好用成品。兴趣是最好的老师,重在过程不在结果。 下面介绍我的车,由于做出来没多久还有很多不足的地方,下一步就是要换一个更长的地盘,用6轮驱动,换大轮。
下面是基本完成后的小车:

完成了视频传输的小车,平板电脑里面可以看到小车摄像头拍到的视频。
下面是各个部件:
1,TP-LINK 路由器 刷固件后用来进行图传和数传。淘宝上价格在150左右,已经刷好了固件。

2,S606高清摄像头 USB接头,淘宝价在80左右

3,装好2自由度舵机云台的摄像头
4,装好的小车底盘。85MM轮,37MM电机,20X15CM底盘。

5,小车底盘和37金属电机。金属电机24元一个,轮12元一个。

6,L298电机驱动模块

7,安装好电池和保护板及充电电路。

8,九节18650锂电形成的电池组。3并3串,11.2V

9,控制电路。采用STC89C52单片机。

10,上板前视图。有四个LED大灯

11,RS232电平转换模块

12,整机仰视图

13,上底板三层积木构架

14,继电器和限流降压模块。

15,整机图
下面介绍一下小车的基本原理

一,小车的图传和数传原理: 本小车采用开源的无线路由器进行图传和数传。图传主要是将摄像头视频通过路由器传输到上位机上。数传主要是用上位机软件进行小车的控制,如行走,转弯。 关于路由器的固件刷机,参照网址:http://www.wifi-robots.com/。 二,小车的下位机控制部分: 本着DIY的目的,采用了51单片机加L298电机驱动。具体采用了STC89C52单片机。具体C源程序在后面,已通过测试。 三,小车的底盘部分: 采用6061铝,37MM金属减速电机,85MM轮。采用四轮驱动。 四,小车电源部分: 采用9节18650锂电。通过实际运行动力强劲,续航强。电池采用3X3连接,共11V输出。电源部分设计了充电保护板和输出保险设计。 五,大灯电路; 采用四个大功率LED,继电器模块和限流模块。 六, 设计了对讲机电路 七,还未设计红外避障,超声波测距等
附51单片机源程序: - #include<reg52.h>
- #include<math.h>
- #include<intrins.h>
- #define uchar unsigned char
- #define uint unsigned int
- uchar Buffer =0; //从串口接收的数据
- uint URTAReceivedCount=0,n=1;
- uchar data Tempdatatable[5],CommandDatatable[5];//数据包
- uchar serVal[2];
- uint pwm[]={1120,1190,1382,1382,1382,1382,1382,1382}; //初始90度,(实际是1382.4,取整得1382)
- uchar pwm_flag=0;
- uint code ms0_5Con=461; //0.5ms计数 (实际是460.8,取整得461)
- uint code ms2_5Con=2304; //2.5ms计数
-
-
- bit key_stime_ok;
- sbit StatusLight=P3^6; //状态灯
- sbit MainLight=P3^7; //主大灯
- sbit servo0=P0^0; //舵机控制
- sbit servo1=P0^1;
- sbit servo2=P0^2;
- sbit servo3=P0^3;
- sbit servo4=P0^4;
- sbit servo5=P0^5;
- sbit servo6=P0^6;
- sbit servo7=P0^7;
- /********************************************************************
- * 名称 : Delay_1ms()
- * 功能 : 延时子程序,延时时间为 1ms * x
- * 输入 : x (延时一毫秒的个数)
- * 输出 : 无
- ***********************************************************************/
- void Delay_1ms(uint i)//1ms延时
- {
- uchar x,j;
- for(j=0;j<i;j++)
- for(x=0;x<=148;x++);
- }
-
- void TurnOnStatusLight()
- {
- StatusLight=0;
- }
- /********************************************************************
- * 名称 : Send_Data()
- * 功能 : 向上位机传送字符
- * 输入 : 无
- * 输出 : 无
- ***********************************************************************/
- void Send_Data(uchar type,uchar cmd,uchar dat)
- {
- uchar data Buffer[5];//构建数据包
- uchar *p;
- uint Send_Count=0;
- p = Buffer;
- Buffer[0]=0XFF;
- Buffer[1]=type;
- Buffer[2]=cmd;
- Buffer[3]=dat;
- Buffer[4]=0XFF;
- while(1)
- {
- if(*p==0XFF)
- {
- Send_Count++; //0XFF标志统计位
- }
- SBUF = *p; //发送
- while(!TI) //如果发送完毕,硬件会置位TI,等待发送完毕
- {
- _nop_();
- }
- p++;
- TI = 0;
- if(Send_Count == 2) //当统计到两次出现0XFF,则认为一个数据包发送完毕,跳出循环
- {
- TI = 0;
- break;
- }
- }
- }
- /********************************************************************
- 协议规定:
- 包头 类型位 数据位 数据位 结束位
- 0XFF 0X** OX** 0X** 0XFF
- 各命令说明:
- 类型位 数据位 数据位 功能
-
- 0X00 0X02 0X00 前进
- 0X00 0X01 0X00 后退
- 0X00 0X03 0X00 左转
- 0X00 0X04 0X00 右转
- 0X00 0X00 0X00 停止
-
- 0X01 0X01 角度 舵机1
- 0X01 0X02 . 舵机2
- 0X01 0X01 . 舵机3
- 0X01 0X02 . 舵机4
- 0X01 0X01 . 舵机5
- 0X01 0X02 . 舵机6
- 0X01 0X01 . 舵机7
- 0X01 0X02 数据 舵机8
-
- 0X02 0X01 车灯亮
- 0X02 0X02 车灯灭
-
- 0X03 雷达数据 发送雷达数据
- ***********************************************************************/
- /********************************************************************
- * 名称 : Com_Int()
- * 功能 : 串口中断子函数
- ***********************************************************************/
- void Com_Int(void) interrupt 4
- {
- uchar temp;
- ES=0; //关串口中断
- RI=0; //软件清除接收中断
- temp=SBUF;
- if(temp==0XFF && URTAReceivedCount<3)
- {
- Tempdatatable[0]==0XFF; //包头
- URTAReceivedCount++;
- }
- else
- {
- Tempdatatable[n]=temp;
- n++;
- if(URTAReceivedCount==0&&n==2)
- n=1;
- }
-
- if(URTAReceivedCount==2)//包尾
- {
- Tempdatatable[0]=0XFF;
- Tempdatatable[4]=0XFF;
- n=1;
- URTAReceivedCount=0; //组包完毕
- temp="";
- // Send_Data(Tempdatatable[1],Tempdatatable[2],Tempdatatable[3]); //发送组成的数据包回去
- }
-
- CommandDatatable[0]=Tempdatatable[0];
- CommandDatatable[1]=Tempdatatable[1];
- CommandDatatable[2]=Tempdatatable[2];
- CommandDatatable[3]=Tempdatatable[3];
- CommandDatatable[4]=Tempdatatable[4];
-
- ES=1;//开串口中断
-
-
- }
-
- /********************************************************************
- * 名称 : Com_Init()
- * 功能 : 串口初始化,晶振11.0592,波特率9600,使能了串口中断
- ***********************************************************************/
- void Com_Init(void)
- {
- TMOD = 0x21;
- PCON = 0x00;
- SCON = 0x50;
- TH1 = 0xFd; //设置波特率 9600
- TL1 = 0xFd;
- TR1 = 1; //启动定时器1
- ES = 1; //开串口中断
- EA = 1; //开总中断
- IT0=0;
- EX0=1;
- }
-
- /********************************************************************
- * 名称 :Moto_Forward()
- * 功能 : 电机1、2启动,都是前进,整车表现为前进。
- ***********************************************************************/
- void Moto_Forward()
- {
- P2= 0x55;
- Delay_1ms(100);
- }
- /********************************************************************
- * 名称 :Moto_Backward()
- * 功能 : 电机1、2启动,都是后退,整车表现为后退。
- ***********************************************************************/
- void Moto_Backward()
- {
-
- P2= 0xaa;
- Delay_1ms(100);
- }
-
- /********************************************************************
- * 名称 :Moto_TurnLeft()
- * 功能 : 电机1后退,电机2前进,整车表现为左转。
- ***********************************************************************/
- void Moto_TurnLeft()
- {
- P2= 0x69;
- Delay_1ms(100);
- }
- /********************************************************************
- * 名称 :Moto_TurnRight()
- * 功能 : 电机1前进,电机2后退,整车表现为右转。
- ***********************************************************************/
- void Moto_TurnRight()
- {
- P2= 0x96;
- Delay_1ms(100);
- }
- /********************************************************************
- * 名称 :Moto_Stop()
- * 功能 : 电机1停止,电机2停止,整车表现为停止。
- ***********************************************************************/
- void Moto_Stop()
- {
-
- P2= 0x00;
- Delay_1ms(100);
- }
- /********************************************************************
- * 功能 : 舵机PWM中断初始化
- ***********************************************************************/
- void Timer0Init()
- {
- /*0度=0.5ms, 45度=1ms, 90度=1.5ms, 135度=2ms, 180度=2.5ms
- /.5 ms初始值 F700, (12n/11059200=2.5/1000, n=2304, X=65536-2304=63232 > F700)*/
- TMOD |= 0x01; //使用模式1,16位定时器,使用"|"符号可以在使用多个定时器时不受影响
- TH0=-ms2_5Con>>8; //给定初值,17ms中断
- TL0=-ms2_5Con;
- EA=1; //总中断打开
- ET0=1; //定时器0中断打开
- TR0=1; //定时器0开关打开
- }
- /********************************************************************
- * 功能 : 舵机PWM中断, //舵机控制函数 周期为20ms 一个循环20MS = 8*2.5ms
- ***********************************************************************/
- void SteeringGear() interrupt 1
- {
- switch(pwm_flag)
- {
- case 1: servo0=1; TH0=-pwm[0]>>8; TL0=-pwm[0]; break;
- case 2: servo0=0; TH0=-(ms2_5Con-pwm[0])>>8; TL0=-(ms2_5Con-pwm[0]); break;
- case 3: servo1=1; TH0=-pwm[1]>>8; TL0=-pwm[1]; break;
- case 4: servo1=0; TH0=-(ms2_5Con-pwm[1])>>8; TL0=-(ms2_5Con-pwm[1]); break;
- case 5: servo2=1; TH0=-pwm[2]>>8; TL0=-pwm[2]; break;
- case 6: servo2=0; TH0=-(ms2_5Con-pwm[2])>>8; TL0=-(ms2_5Con-pwm[2]); break;
- case 7: servo3=1; TH0=-pwm[3]>>8; TL0=-pwm[3]; break;
- case 8: servo3=0; TH0=-(ms2_5Con-pwm[3])>>8; TL0=-(ms2_5Con-pwm[3]); break;
- case 9: servo4=1; TH0=-pwm[4]>>8; TL0=-pwm[4]; break;
- case 10: servo4=0; TH0=-(ms2_5Con-pwm[4])>>8; TL0=-(ms2_5Con-pwm[4]); break;
- case 11: servo5=1; TH0=-pwm[5]>>8; TL0=-pwm[5]; break;
- case 12: servo5=0; TH0=-(ms2_5Con-pwm[5])>>8; TL0=-(ms2_5Con-pwm[5]); break;
- case 13: servo6=1;TH0=-pwm[6]>>8; TL0=-pwm[6]; break;
- case 14: servo6=0;TH0=-(ms2_5Con-pwm[6])>>8; TL0=-(ms2_5Con-pwm[6]); break;
- case 15: servo7=1;TH0=-pwm[7]>>8; TL0=-pwm[7]; break;
- case 16: servo7=0;TH0=-(ms2_5Con-pwm[7])>>8; TL0=-(ms2_5Con-pwm[7]); break;
- default: TH0=0xff; TL0=0x80; pwm_flag=0;
- }
- pwm_flag++;
- }
-
- void SetSteeringGear(uchar i, uchar val)
- {
- uint a = (val+46)*10;
- if(a<ms0_5Con)
- a=ms0_5Con;
- if(a>ms2_5Con)
- a=ms2_5Con;
- pwm[ i]=a;
- CommandDatatable[2]=0xff; //清除缓存
- }
-
- /********************************************************************
- * 功能 : 串口中断接收数据
- ***********************************************************************/
- /*********************************************************************************
- ** 函数功能 : 主函数
- *********************************************************************************/
- void main()
- {
- MainLight=0;
- Delay_1ms(200);
- Com_Init();//串口初始化
- Timer0Init();//舵机PWM中断初始化
- while(1)
- {
- if(CommandDatatable[0]==0XFF && CommandDatatable[4]==0XFF)
- {
- switch (CommandDatatable[1]) //根据键值不同,执行不同的内容
- {
- case 0X00: //类型位0X00,表明是控制数据包,进入控制数据case
- switch(CommandDatatable[2]) //根据数据位的值来进行选择执行不同的动作
- {
- case 0X00:Moto_Stop();break;
- case 0X01:Moto_Forward();break;
- case 0X02:Moto_Backward();break;
- case 0X03:Moto_TurnLeft();break;
- case 0X04:Moto_TurnRight();break;
- default : break;
- }
- break;
- case 0X01: //类型位0X01,表明是舵机数据包,进入舵机case
- switch(CommandDatatable[2])
- {
- case 0x01:SetSteeringGear(0,CommandDatatable[3]);break;
- case 0x02:SetSteeringGear(1,CommandDatatable[3]);break;
- case 0x03:SetSteeringGear(2,CommandDatatable[3]);break;
- case 0x04:SetSteeringGear(3,CommandDatatable[3]);break;
- case 0x05:SetSteeringGear(4,CommandDatatable[3]);break;
- case 0x06:SetSteeringGear(5,CommandDatatable[3]);break;
- case 0x07:SetSteeringGear(6,CommandDatatable[3]);break;
- case 0x08:SetSteeringGear(7,CommandDatatable[3]);break;
- default : break;
- }
- break;
- case 0X02: //类型位0X02,表明是大灯数据包,进入大灯case
- switch(CommandDatatable[2])
- {
- case 0X01:MainLight=1;break;
- case 0X02:MainLight=0;break;
- default : break;
- }
- break;
- default : break;
- }
- }
- }
- }
复制代码
|