51红外循迹小车报告(舵机版)最终版

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

简易教程
前言
往届全国大学生电子设计竞赛曾多次出现了集光、机、电于一体的简易智能小车题目,此次,笔者在通过多次论证、比较与实验之后,制作出了简易小车的寻迹电路系统。

整个系统基于普通玩具小车的机械结构,利用小车的底盘、前后轮电机及其自动复原装置,能够平稳跟踪路面黑色轨迹运行。

系统分为检测、控制、驱动三个模块。

首先利用光电对接收管和路面信号进行检测,然后经过比较器处理,对软件控制模块进行实时控制,输出相应的信号给驱动芯片驱动电机转动,从而控制整个小车的运动。

智能小车能在画有黑线的白纸“路面”上行驶,这是由于黑线和白纸对光线的反射系数不同,小车可根据接收到的反射光的强弱来判断“道路”---黑线,最终实现简单的循迹运动。

个人水平有限,有错误不足之处,还望各位前辈同学多多包含,指出修正,完善。

谢谢!
李学云王维
2016年7月27号
目录
前言 (1)
第一部分硬件设计 (1)
1.1 车模选择 (1)
1.2传感器选择 (1)
1.3 控制模块选择 (2)
第二部分软件设计及调试 (3)
2.1 开发环境 (3)
2.2总体框架 (3)
2.3 舵机程序设计与调试 (3)
2.3.1 程序设计 (3)
2.3.2 调试 (3)
2.3.3 程序代码 (4)
2.4 传感器调试 (5)
2.4.1 传感器好坏的检测 (5)
2.4.2 单片机能否识别信号并输出信号 (5)
2.5 综合调试 (7)
附录1 (9)
第一篇舵机(舵机及转向控制原理) (9)
1.1概述 (9)
1.2舵机的组成 (10)
1.3舵机工作原理 (11)
1.4舵机使用中应注意的事项 (12)
1.5如何利用程序实现转向 (12)
1.6舵机测试程序 (13)
附录2 (14)
第二篇光电红外传感器 (14)
2.1传感器的原理 (14)
2.2红外光电传感器ST188 结构图 (15)
2.3传感器的选择 (15)
2.4传感器的安装 (16)
2.5使用方法 (16)
2.7红外传感器输入输出调试程序 (17)
一、课题任务及要求
用360°连续舵机设计一个自动循迹小车,可以自动行驶并检测到地面黑色轨迹,沿着黑色轨迹行驶.
二、小车行驶基本原理
小车在白色地板上循黑线行走,由于黑线和白色地板对光线的反射系数不同,可以根据接收到的反射光的强弱来判断“道路”。

通常采取的方法是红外探测法。

红外探测法,即利用红外线在不同颜色的物体表面具有不同的反射性质的特点,在小车行驶过程中不断地向地面发射红外光,当红外光遇到白色纸质地板时发生漫反射,反射光被装在小车上的接收管接收;如果遇到黑线则红外光被吸收,小车上的接收管接收不到红外光。

单片机就是否收到反射回来的红外光为依据来确定黑线的位置和小车的行走路线。

三、总体设计方案
通过51单片机,在“while(1){}”里面不断扫描外部输入I/O口,若能读到高电平,则输出相应的舵机控制程序。

(要求:51 I/O口TTL门输入电压3.5V以上为高电平,1.2V以下为低电平。

读取引脚时,先置1再读取).
第一部分硬件设计
1.1 车模选择
本教程选择带有两舵机和一万向轮的车模。

舵机型号:SM-S4303R(360°旋转舵机).其原理及详细操作说明,见附录1.车模实物如图1.1.
图1.1
1.2传感器选择
本教程选择ST188 红外对管光电传感器,使用左、前、右分布的三个传感器(前伸为了检测十字路口)。

传感器应用电路图如图1.2。

光电传感器原理详情,请看附录2->传感器篇。

图1.2
应用原理:红外探测法
红外探测法,即利用红外线在不同颜色的物理表面具有不同的反射性质的特点。

在小车行驶过程中不断地向地面发射红外光,当红外光遇到白色地面时发生漫发射,反射光被装在小车上的接收管接收;如果遇到黑线则红外光被吸收,则小车上的接收管接收不到信号。

1.3 控制模块选择
因为循迹小车,只需要做简单的输入输出操作,普通51单片机都能实现其功能.本教程选用是51单片机型号为STC89C52RC的最小系统板(有引脚引出的)。

本教程里的程序理论上具有51内核的单片机都可使用。

最小系统原理图,如图1.3.
图1.3 51最小系统原理图
1.4 供电扩展版
为了控制的稳定,舵机直接从电源VCC串个二极管供电。

这里采用简单的电源扩展,将5V电源引入扩展板,再引出供给电机和控制模块。

(这里最好把二极管接上,消除电机感性对单片机的影响)
注意:当舵机与控制板供电电源不同时,两边必须共地,数字信号才能同步。

否则控制信号会发生混乱,导致无法控制。

第二部分软件设计及调试
2.1 开发环境
Keil C51 v9.54a、stc-isp-15xx-v6.85H、USB-TLL 51下载器(烧录程序用)2.2总体框架
2.3 舵机程序设计与调试
2.3.1 程序设计
通过了解,知道89S51单片机自身没有PWM接口,故使用定时器模拟产生PWM波,进行舵机速度调试。

使用51单片机的定时器T0工作在方式1,赋予初值“TH0=(65535-100)/256; TL0=(65535-100)%256;”定时0.1ms(晶振频率12MHz),用count计数200,产生50HZ的脉冲频率(舵机最适频率)。

设全局变量LS、RS来控制占空比,从P1.0 P1.1输出PWM信号,两口外接舵机。

附:1.脉冲产生原理:周期20ms,定时1.2ms为高电平,其他时间为低电平.即可产生占空比为6%(一周期内高电平占比)的脉冲信号.
2.pwm控制舵机原理,可理解为一个高电平舵机一动,给的多动的快,
但有范围。

2.3.2 调试
调试目的:得到正反转占空比范围。

我的调试数据为: 正转范围0.5%~6%(即:LS=1,LS=12)
反转范围6.5%以上(即:LS>=13)
2.3.3 程序代码
/******************************************************
51单片机舵机调试程序
调试参数: 1.定时器定时0.1ms,计数200,定时20ms(50HZ)
. (360°左舵机为例): 频率50HZ
LS=12 (即占空比%6),电机正转最慢
*******************RS=13 (即占空比%6.5),电机正转最慢****************/
/*提示:1.调试舵机时,最好单独供电(控制信号与电源供电分离)
.2.控制信号与供电电源必须共地。

*/
/*****************作者:李学云2016.7.23****************/(......排版好乱)
#include "reg52.h"
#define uchar unsigned char
uchar count=0,LS=2,RS=15; //count: 定时计数LS:左路舵机脉宽调试
sbit pwm_L=P1^0; //左路电机输出
sbit pwm_R=P1^1;
void init()
{
pwm_L=0; //占空比控制变量初始化
pwm_R=0;
//定时器,初始化,定时器T0工作方式1
TMOD=0x01;
TH0=(65535-100)/256; //基准定时时间为0.1ms
TL0=(65535-100)%256;
EA=1;
ET0=1;
TR0=1;
}
void main()
{
init();
while(1)
{ }
}
void timer0() interrupt 1 //定时器T0中断服务函数, 1 为T0中断号,3 为T1中断号{
TH0=(65535-100)/256;
TL0=(65535-100)%256;
count++;
if(count<=LS) {pwm_L=1;} else {pwm_L=0;}
if(count<=RS) {pwm_R=1;} else {pwm_R=0;}
count=count%200; //定时20ms 频率50hz
}
2.4 传感器调试
2.4.1 传感器好坏的检测
给传感器通上电,使传感器高度在0.3mm-10mm,并来回的在黑白线间移动,同时用万用表检测,看在黑线时,电压输出是否大于 3.5V,白线时电压是否低于1.2V。

2.4.2 单片机能否识别信号并输出信号
三路传感器分别接到单片机P1.5 P1.6 P1.7口,P0口接8个LED灯。

下好程序,接好线,通电并移动传感器在黑白之间(高度0.5mm左右),观察P0.5 P06 P0.7口LED是否有闪烁,有则单片机能识别信号并输出信号。

/******三路红外光电传感器测试程序*********/
/*****P0口接上一排LED灯做指示用*********/
/****现象:单片机能识别到传感器信号,则对应P0.5 P06 P0.7口LED闪烁,否则只有P0.1 P02 P0.3闪烁。

***********/
#include "reg52.h"
#define uchar unsigned char
uchar count=0,LS=0,RS=0;
sbit pwm_L=P1^0; //左路电机输出
sbit pwm_R=P1^1;
sbit k1=P1^5;
sbit k2=P1^6;
sbit k3=P1^7;
sbit led1=P0^1;
sbit led2=P0^2;
sbit led3=P0^3;
sbit led4=P0^5;
sbit led5=P0^6;
sbit led6=P0^7;
void delay(uchar k)
{
uchar i;
for(;k>0;k--)
for(i=0;i<=128;i++);
}
void init()
{
pwm_L=0;
pwm_R=0;
P1=0xff;
TMOD=0x01;
TH0=(65535-100)/256;
TL0=(65535-100)%256;
EA=1;
ET0=1;
TR0=1;
}
void main()
{
init();
while(1)
{
if(k1==1) {LS=0; RS=5;led1=0;delay(100);led1=1;} if(k2==1) {LS=16;RS=0;led2=0;delay(100);led2=1;} if(k3==1) {LS=0; RS=5;led3=0;delay(100);led3=1;}
if(k1==0) {LS=16;RS=0;led4=0;delay(100);led6=1;} if(k2==0) {LS=0; RS=5;led5=0;delay(100);led5=1;} if(k3==0) {LS=16;RS=0;led6=0;delay(100);led6=1;} }
}
void timer0() interrupt 1
{
TH0=(65535-100)/256;
TL0=(65535-100)%256;
count++;
if(count<=LS) {pwm_L=1;} else {pwm_L=0;}
if(count<=RS) {pwm_R=1;} else {pwm_R=0;}
count=count%200;
}
第三部分综合调试
3.1综合调试
3.1.1接线
3.1.2 调试程序
接线:P2.0 P2.1分别接舵机pwm输入线。

P1.5 P1.6 P1.7接红外传感器三路输入。

此程序只是简单的测试程序。

#include "reg52.h"
#define uchar unsigned char
uchar count=0,LS=0,RS=0;
sbit pwm_L=P2^0;
sbit pwm_R=P2^1;
sbit k1=P1^5;
sbit k2=P1^6;
sbit k3=P1^7;
uchar L2,M3,R4;
void init()
{
pwm_L=0;
pwm_R=0;
P1=0xff;
TMOD=0x01;
TH0=(65535-100)/256;
TL0=(65535-100)%256;
EA=1;
ET0=1;
TR0=1;
}
void Straight()
{
LS=1,RS=25;
}
void line_left()
{
LS=11;
RS=25;
}
void line_right()
{
LS=1;
RS=12;
}
void detect_infrared() //循迹,红外检测
{
if(k1==1){line_right();}
else
if(k3==1){line_left();}
else
Straight();
}
void main()
{
init();
while(1)
{
detect_infrared();
}
}
void timer0() interrupt 1
{
TH0=(65535-100)/256;
TL0=(65535-100)%256;
count++;
if(count<=LS) {pwm_L=1;} else {pwm_L=0;} if(count<=RS) {pwm_R=1;} else {pwm_R=0;} count=count%200;
}
附录1
第一篇舵机(舵机及转向控制原理)
1.1概述
什么是舵机?舵机也叫伺服电机,它最早用于船舶转向,通过程序可以连续控制转动的角度,因而被广泛应用。

例如,智能小车的弯道行驶以及机器人的各类关节运动。

图1 舵机用于机器人图2 舵机用于智能小车中舵机是小车转向的控制机构,它体积小、力矩大、外部机械设计简单、稳定性高,不论在硬件设计还是在软件设计中,都是小车控制单元的重要组成部分,如图3为舵机的外形图。

图3 舵机外形图
1.2舵机的组成
一般来讲,舵机主要由舵盘、减速齿轮组、位置反馈电位计、直流电机、控制电路等几个部分组成,如图4、图5所示。

图4 舵机组成
图5 舵机的组成示意图
舵机有三条输入线,如图6,红色的是电源线,黑色的为地线,这两根线是舵机最基本的能源保证,承担着电机的转动消耗。

此外,还有一条控制信号线,
Futaba的一般为白色,JR的一般为桔黄色。

另外要注意一点,SANWA的某些型号的电源线并不是在中间,所以在使用之前,我们一定要先辨认清楚:红为电,黑为地,其他是信号。

图6
1.3舵机工作原理
电机与齿轮组相连。

在舵机工作时,控制电路板通过接收来自信号线的控制信号,来控制电机转动,进而控制齿轮的转动,齿轮减速后将传动至输出舵盘。

舵机的输出轴和位置反馈电位计是相连的,舵盘转动的同时,带动位置反馈电位计,电位计将输出一个电压信号到控制电路板,进行反馈,然后控制电路板根据所在位置决定电机转动的方向和速度,从而达到目标停止。

其工作流程为:控制信号→控制电路板→电机转动→齿轮组减速→舵盘转动→位置反馈电位计→控制电路板反馈。

舵机的控制信号周期一般为20MS的脉宽调制(PWM)信号,其中脉冲宽度从0.5-2.5MS,相对应的舵盘位置为0-180度,呈线性变化。

也就是说,给它提供一定的脉宽,它的输出轴就会保持一定对应角度上,无论外界转矩怎么改变,直到给它提供一个另外宽度的脉冲信号,它才会改变输出角度到新的对应位置上。

如图7所求。

舵机内部有一个基准电路,产生周期为20MS,宽度1.5MS的基准信号,有一个比出较器,将外加信号与基准信号相比较,判断出方向和大小,从而生产电机的转动信号。

由此可见,舵机是一种位置伺服驱动器,转动范围不能超过180度,适用于那些需要不断变化并可以保持的驱动器中,比如说机器人的关节、飞机的舵面等。

(在我们平时所用的电源中,大致分为两种规格,一4.8V,一是6.0V,它们分别对应不同的转矩标准,即输出力矩不同,6.0V对应的要大一些,具体看应用条件)
图7
1.4舵机使用中应注意的事项
1.常用舵机的额定工作电压一般为6V,我们可以使用LM1117等芯片来提供电压。

如果直接使用5V的供电来简化硬件上的设计,影响也不会很大,但最好将舵机与单片机分开供电,否则很有可能会造成单片机无法正常工作。

2.一般来说,想要控制舵机,我们要将信号线连接至单片机的任意引脚,还需通过51单片机定时器模块的PWM才能进行控制。

但是如果是像飞思卡尔之类的芯片,我们将信号线连到专用的PWM输出引脚上即可,因为飞思卡尔内部自带有PWM模块,可以直接输出PWM信号。

1.5如何利用程序实现转向
在舵机信号端输入一个50HZ的方波信号,然后控制信号周期的高电平脉冲持续的时间,进而就可以控制舵机的速度、正反转方向及是否停转。

一个高电平脉冲持续的时间对应一个速度。

高电平为1-1.5毫秒时,舵机正转(1毫秒时正转速度最快,越接近1.5毫秒越慢,1.5毫秒时舵机停转),高电平为1.5毫秒-2毫秒时舵机反转(1.5毫秒时舵机停转,越接近2毫秒反转的速度越快,2毫秒时以最快速度反转)
而对于不同类型的舵机,它们的特点也各不相同:
1.180度的舵机,需脉宽1500-2500us,可以达到165-180度,有略微误差。

2.300度可控的类型,舵机机械角度360度,可控角度270-300度。

3.360度连续旋转的舵机,是PWM控制它的旋转速度和旋转方向,
500-1500us的PWM是控制它正转,值越小,旋转速度越大;
1500-2500us的PWM是它反转,值越大,旋转速度越大。

1500us的PWM是控制它停止。

(由于每一个舵机的中位可能会不一样,所以有些舵机可能是1520us的PWM,舵机才会停下来,所以需要自己实际测试出舵机的中位)只能连续旋转,不能定位.
1.6舵机测试程序
#include "reg52.h"
#define uchar unsigned char
uchar count=0,LS=12,RS=1; //LS:
sbit pwm_L=P2^0; //左右舵机
sbit pwm_R=P2^1;
void init()
{
pwm_L=0;
pwm_R=0;
TMOD=0x01;
TH0=(65535-50)/256;
TL0=(65535-50)%256;
EA=1;
ET0=1;
TR0=1;
}
main()
{
init();
while(1)
{
}
}
void timer0() interrupt 1
{
TH0=(65535-50)/256;
TL0=(65535-50)%256; //
count++;
附录2
第二篇光电红外传感器
红外探测法,即利用红外线在不同颜色的物理表面具有不同的反射性质的特点进行探测。

在行驶过程中,小车不断地向地面发射红外光,当红外光遇到白色地面发生漫射,反射光被装在小车上的接收管接收;如果遇到黑线,则红外光被吸收,小车上接收不到信号。

2.1传感器的原理
R1限制发射二极管的电流,发射管的电流和发射功率成正比,但受其极限输入正向电流50mA的影响,用R1=150的电阻作为限流电阻,Vcc=5V作为电源电压,测试发现发射功率完全能满足检测需要;可变电阻R2可限制接收电路的电流,一方面保护接收红外管;另一方面可调节检测电路的灵敏度。

因为传感器输出端得到的是模拟电压信号,所以在输出端增加了比较器,先将ST168输出电压与2.5V进行比较,再送给单片机处理和控制。

ce端电阻比较灵活,它将用来输出高低电平,在此,我们可以接一个5K的电阻。

(电路图中的滑动变阻器只是为了测试方便,调整阈值电压,可以不用)当没有物体反射红外线时,ce之间无电流流过,输出电压为电源电压,高电平。

当有物体反射红外线时,be饱和导通,ce导通,输出端相当于接地,输出
电压为低电平。

(详见附件ST188.pdf)
ST188.pdf
2.2红外光电传感器ST188 结构图
2.3传感器的选择
在红外探测法中,传感器的选择是非常重要的。

市场上用于红外探测法的器件较多,可以利用反射式传感器外接简单电路自制探头,也可以使用结构简单、工作性能可靠的集成式红外探头。

ST系列集成红外探头价格便宜、体积小、使用方便、性能可靠、用途广泛,所以该系统中最终选择了ST168反射传感器作为红外光的发射和接收器件,其内部结构和外接电路均较为简单。

2.4传感器的安装
ST168采用高发射功率红外光、电二极管和高灵敏光电晶体管组成,采用非接触式检测方式。

ST168的检测距离很小,一般为8~15毫米,因为8毫米以下是它的检测盲区,而大于15毫米则很容易受干扰。

笔者经过多次测试、比较,发现把传感器安装在距离检测物表面10毫米时,检测效果最好。

2.5使用方法
根据光电特性,选取发射管的静态电流为20mA。

典型的压降为0.01.25v,如果供电电压为5V,那么,此时在发射管上需要串联电阻,电阻大小为R=(5-1.25)/0.02;即:R=187.5欧姆。

取标称电阻,R=200,那么此时的电流小于20mA,但是不影响结果。

2.6如何提高循迹的可靠性
传感器的安装,正确选择检测方法和传感器件是决定循迹效果的重要因素,而正确的器件安装方法也是循迹电路好坏的一个重要因素。

从简单、方便、可靠等角度出发,我门可以同时在底盘装设4个红外探测头,进行两级方向纠正控制,这将大大提高其循迹的可靠性。

循迹传感器一般在一条直线上。

其中X1与Y1为第一级方向控制传感器,X2与Y2为第二级方向控制传感器,并且黑线同一边的两个传感器之间的宽度不
得大于黑线的宽度。

小车前进时,始终保持(如图3中所示的行走轨迹黑线)在X1和Y1这两个第一级传感器之间,当小车偏离黑线时,第一级传感器就能检测到黑线,把检测的信号送给小车的处理、控制系统,控制系统发出信号对小车轨迹予以纠正。

第二级方向探测器实际是第一级的后备保护,它的存在是考虑到小车由于惯性过大会依旧偏离轨道,再次对小车的运动进行纠正,从而提高了小车循迹的可靠性。

2.7红外传感器输入输出调试程序
/*****P0口接上一排LED灯做指示用*********/
/****现象:单片机能识别到传感器信号,则对应P0.5 P06 P0.7口LED闪烁,否则只有P0.1 P02 P0.3闪烁。

***********/
#include "reg52.h"
#define uchar unsigned char
uchar count=0,LS=0,RS=0;
sbit pwm_L=P1^0;
sbit pwm_R=P1^1;
sbit k1=P1^5;
sbit k2=P1^6;
sbit k3=P1^7;
uchar L2,M3,R4;
sbit led1=P0^1;
sbit led2=P0^2;
sbit led3=P0^3;
sbit led4=P0^5;
sbit led5=P0^6;
sbit led6=P0^7;
void delay(uchar k)
{
uchar i;
for(;k>0;k--)
for(i=0;i<=128;i++);
}
void init()
{
pwm_L=0;
pwm_R=0;
P1=0xff;
TMOD=0x01;
TH0=(65535-100)/256;
TL0=(65535-100)%256;
EA=1;
ET0=1;
TR0=1;
}
void Strainght()
{
LS=25,RS=1;
}
void line_left()
{
LS=12;
RS=16;
}
void line_right()
{
LS=10;
RS=14;
}
void Run()
{
if(L2&M3&R4)
{
Strainght();
}
else
{
if(L2) line_left();
if(M3) Strainght();
if(R4) line_right();
}
}
void main()
{
init();
while(1)
{
if(k1==1) L2=1;
if(k2==1) M3=1;
if(k3==1) R4=1;
// Run();
if(k1==1) {LS=0; RS=5;led1=0;delay(100);led1=1;} if(k2==1) {LS=16;RS=0;led2=0;delay(100);led2=1;} if(k3==1) {LS=0; RS=5;led3=0;delay(100);led3=1;} \
if(k1==0) {LS=16;RS=0;led4=0;delay(100);led6=1;} if(k2==0) {LS=0; RS=5;led5=0;delay(100);led5=1;} if(k3==0) {LS=16;RS=0;led6=0;delay(100);led6=1;}
Strainght();
}
}
void timer0() interrupt 1
{
TH0=(65535-100)/256;
TL0=(65535-100)%256;
count++;
if(count<=LS) {pwm_L=1;} else {pwm_L=0;}
if(count<=RS) {pwm_R=1;} else {pwm_R=0;}
count=count%200;
}。

相关文档
最新文档