实例4,循迹模块的使用和循迹小车的实现

1、循迹模块介绍;

2、循迹原理;

3、硬件接线;

4、循迹编程思路流程图;

5、循迹程序第一稿(后面再写几篇文章加计时、测距、蓝牙等模块)。

一、循迹模块

目前大一新生,多数用的是数字式的循迹模块,当碰到黑线,发出一个1信号,碰到白线发出0信号。这个1和0是根据实际模块电路决定的,有些碰到黑线是0,有些是1,这个可以用万用表测试下,如果是信号引脚碰到黑线的时候,是5v电,那么就是黑线是1,如果碰到白线是5v,那么白线是1。有一个按钮调节灵敏度的,根据实际情况调节好。
后面熟练之后,可以用ADC模块进行黑白线检测。这个后面再了解。

实例4,循迹模块的使用和循迹小车的实现_第1张图片
实例4,循迹模块的使用和循迹小车的实现_第2张图片
外观不一样,注意看引脚的标识。
以这个为例。
实例4,循迹模块的使用和循迹小车的实现_第3张图片

G接GND,V+接5V,S是信号线,接输出到单片机的IO口,当碰到黑线白线会发生跳变。 滑动变阻器是调节灵敏度的旋钮,高度不一样,旋转到合适的数值,碰到黑线和白线有信号的变化就可以,一般放和底面高度8-15mm。

其他模块也一样。

2、循迹模块的布置。

一般需要3-5个循迹模块。
布局很重要,可以设置中间三个距离近一点,边角远一点。
这个关系到循迹条件的判断。
实例4,循迹模块的使用和循迹小车的实现_第4张图片

*3、循迹模块的条件

从做到右叫做LS1,LS0,MS,RS0,RS1,这个名字自己起就可以了。

循迹的几种情况。(注意判断情况条件自己根据自己情况,适当修改,不能太死板哦。)
第一种,直线行走。两个轮子速度一样
1代表黑线,0代表直线。
MS黑线的时候;
00100
第二种,往左小偏转,右轮比左轮的速度快一点。
LS0
黑线
01000
第三种,左大转。
右轮速度更加快一点,左轮干脆停止了。
LS11(黑线)
10000
大转弯到MS碰到黑线,就停止大转弯。
第四种,右边小转
RS0
1
00010
第五种,右边大转
00001
大转弯到中碰到黑线,就停止大转弯。

第六种,直角左转弯
11x00。
中间的那个x代表是0或者1都可以。
转弯到RS0碰到黑线,就停止转弯。

实例4,循迹模块的使用和循迹小车的实现_第5张图片

第七种,直角右转弯。
只需要最右边的两个是黑线就行。
00x11
转弯到LS0碰到黑线,就停止转弯。

实例4,循迹模块的使用和循迹小车的实现_第6张图片

第八种,调头

四个或者5个都是1,碰到黑线,都调头
01111
11110
11111
前进1秒,
然后左轮后退,右轮前进,旋转调头,直到之间的MS碰到黑线停止调头。

实例4,循迹模块的使用和循迹小车的实现_第7张图片

第九种,检测不到线,就原地打圈,极端情况。
00000

3、接线。

由于使用几个模块,几个循迹模块都需要VCC和GND,都接杜邦线到控制板,会比较乱。
因此,最好用洞洞板焊接一个转接板。
实物看实验室的小车。

电机接线看上一个文章。

4、编程流程图
定义引脚,循迹,电机,按键。
写前进,停止子函数;
初始化。pwm初始化,端口初始化。
while(1)
{
1,按键按下吗?
,是
设置标记flag=1

2、标记flag==1吗?
是,开始循迹
{
	第一种情况
	。。。
	第二种
	。。。
	第n中
	。。。。。
	
}

}


//***************************************************************************下面是接线定义
//左电机
sbit LPWM=P2^0;//电机调节速度的信号
sbit LA2=P0^4;
sbit LA1=P0^5;
//右电机
sbit RPWM=P2^1;
sbit RA2=P0^6;
sbit RA1=P0^7;
//接传感器
sbit L1S=P1^0;
sbit L0S=P1^1;
sbit MS=P1^2;
sbit R0S=P1^3;
sbit R1S=P1^4;
sbit key=P3^4;//接按键,启动按键
void trackline0();
//这个是定义,不声明,后面main函数可以直接用,
//小车前进,根据速度两个轮子速度差,进行前进,转弯等
void qianjin(float vleft,float vright)
{
     
  HPWM_Set(0,8000,vleft);
	LA2=1;
  LA1=0;
	
	HPWM_Set(1,8000,vright);
	RA2=1;
  RA1=0;
	
}
//小车调头程序,左轮反转,右轮正转
void turnback(float vleft,float vright)
{
     
  HPWM_Set(0,8000,vleft);
	LA2=0;
  LA1=1;
	
	HPWM_Set(1,8000,vright);
	RA2=1;
  RA1=0;
	
}
//****************************************************************子函数3:void stop()
//小车停止
void stop()
{
      
	LA2=0;
  LA1=0;
	
	RA2=0;
  RA1=0;
}
//*******************************************主函数
void main()
{
     
	bit startflag=0; //按键控制的启动标记
	bit startflag2=0; //蓝牙控制的启动标记
	
	//每个外设,比如按键,屏幕,PWM等内部资源的初始化,配置一下环境
	//设置准双向口,和普通的51单片机一样
	P0M1=0x00;P0M0=0x00;
	P1M1=0x00;P1M0=0x00;
	P2M1=0x00;P2M0=0x00;
	P3M1=0x00;P3M0=0x00;
	P4M1=0x00;P4M0=0x00;
	P5M1=0x00;P5M0=0x00;
	P6M1=0x00;P6M0=0x00;
	delay_tms(200);
	//屏幕初始化
	OLED_Init();
	//PWM模块初始化
	HPWM_Init();
//*****************************************************************
	//*********************************************正式执行程序
  while(1)
	{
     		

  //**************************************************************************按键来控制的
		//*****************************
		//检测按键是不是按下,开始启动
		if(key==0)
		{
     
			delay_tms(10);//延时去抖动
			if(key==0)
			{
     	
				startflag=1;
				stop();
	 		  delay_tms(1000);//延时,按下两秒之后,小车开始启动进行循迹
			//	delay_tms(2000);
		}
			
	 }	
	 //**********************如果开始标记等于1,说明按下启动键key,这时候小车才开始跑
		if(startflag==1)
		{
     
			//开始循迹,请看这部分代码,太长了,单独拉出来写,方便看主程序逻辑	
       trackline0();	
		}
// //**************************************************************//函数定义trackline0();
// //**************************************************************功能:按键循迹;
void trackline0()
{
     
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++第1种情况
	if(L1S==blackline &&L0S==whiteline  && MS==whiteline && R0S==whiteline&& R1S==whiteline)//1 0 0 0 0 
	{
     
		qianjin(vturnsmallM,vturnbigM);//左da转弯,转到碰到中线停止
		while(1)
		{
     			
			if(MS==blackline)break;
		}	

//+++++++++++++++++++++++++++++++++++++++++++++++++++++++第2种情况
	else if(L1S==whiteline &&L0S==blackline  && MS==whiteline && R0S==whiteline&& R1S==whiteline)//0 1 0 0 0 
	{
     
		qianjin(vturnsmall,vturnbig);//左xiao转弯
	}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++第3种情况
	else if(L1S==whiteline &&L0S==whiteline  && MS==blackline && R0S==whiteline&& R1S==whiteline)//00 1 0 0 
	{
     
		qianjin(vleftmove,vrightmove);//直走
	}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++第4种情况	
	else if(L1S==whiteline &&L0S==whiteline  && MS==whiteline && R0S==blackline&& R1S==whiteline)//0 0 0 1 0 
	{
     
		qianjin(vturnbig,vturnsmall);//左xiao转弯vturnbig vturnsmall
	}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++第5种情况
	else	if(L1S==whiteline &&L0S==whiteline  && MS==whiteline && R0S==whiteline&& R1S==blackline)//0 0 0 0 1
	{
     
		qianjin(vturnbigM ,vturnsmallM);//左da转弯vturnbigM  vturnsmallM,碰到黑线,不然一直大转弯,

		while(1)
		{
     			
			if(MS==blackline)break;
		}

		
		
	}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++第6种情况	
	else 	if(L1S==blackline && L0S==blackline && R1S==whiteline )//11xx0 判断是左转90度
	{
     
		 
		qianjin(vturnsmall,vturnbig);//左转弯
		while(1)	 
		{
      
				if(R0S==blackline)break;
		}
	
	}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++第7种情况
	else 	if( L1S==whiteline  &&R0S==blackline && R1S==blackline)//0xx11 判断是右转90度
	{
     
	
  	qianjin(vturnbig,vturnsmall);//

		while(1)	 
		{
      
				if(L0S==blackline)break;
		}

	}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++第8种情况
		else 	if(L1S==blackline &&L0S==blackline&& MS==blackline && R0S==blackline && R1S==whiteline)//1111x 判断是终点,调头,左轮反转,右轮正转,左转调头
	{
     
			
		
			stop();
		  delay_tms(1000);
		
		  qianjin(vleftmove,vrightmove);
		  delay_tms(1000);
		
	  	stop();
		  delay_tms(1000);
		
	  	turnback(vleftmove,vrightmove);
	//		delay_tms(1000);

			while(1)	 
			{
      
					if(MS==blackline)break;
			}

	}
	
	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++第8种情况
		else 	if(L1S==whiteline &&L0S==blackline&& MS==blackline && R0S==blackline && R1S==blackline)//1111x 判断是终点,调头,左轮反转,右轮正转,左转调头
	{
     
		
			stop();
		  delay_tms(1000);
		
		  qianjin(vleftmove,vrightmove);
		  delay_tms(1000);
		
	  	stop();
		  delay_tms(1000);
		
	  	turnback(vleftmove,vrightmove);
	//		delay_tms(1000);


			while(1)	 
			{
      
					if(MS==blackline)break;
			}
	
	}
		//+++++++++++++++++++++++++++++++++++++++++++++++++++++++第8种情况
		else 	if(L1S==blackline &&L0S==blackline&& MS==blackline && R0S==blackline && R1S==blackline)//1111x 判断是终点,调头,左轮反转,右轮正转,左转调头
	{
     
			
		
			stop();
		  delay_tms(1000);
		
		  qianjin(vleftmove,vrightmove);
		  delay_tms(1000);
		
	  	stop();
		  delay_tms(1000);
		
	  	turnback(vleftmove,vrightmove);

			while(1)	 
			{
      
					if(MS==blackline)break;
			}
	
	}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++第9种情况	这是极端情况,放在最后面判断
		//000找不到直线,如果前面是直走,就转360度,如果是之前右边,就左转,之前左偏,就右转
	else 	if(L1S==whiteline &&L0S==whiteline && MS==whiteline && R0S==whiteline && R1S==whiteline)	
	{
     
    qianjin(vturnbig,vturnsmall);//
	}
				
}

下载,测试一下程序。

你可能感兴趣的:(单片机)