当前位置:   article > 正文

STM32——灰度PID的使用_灰度传感器检测黑白原理代码

灰度传感器检测黑白原理代码

灰度PID

一、灰度传感器背景

世界正处在科技革命和产业革命的交汇点上,科学技术在广泛交叉和深度融合中不断创新,以信息、生命、纳米、材料等科技为基础的系统集成创新,以前所未有的力量驱动着经济社会发展。而且,随着信息化、工业化不断融合,以机器人科技为代表的智能产业蓬勃兴起,成为现代科技创新的一个重要标志。机器人运行时需要不断地循迹,即需要借助传感器探测地面色调迥异的两种色彩以修正其运动轨迹。目前,市场上广泛使用的传感器有颜色传感器、光敏电阻灰度传感器和激光传感器,其中,颜色传感器容易受外界光线影响,需要在黑暗环境下使用,而且颜色传感器获得的信号是反应 RGB 三色的复杂数据信号,因此,颜色传感器的通信过程非常复杂,更重要的是价格昂贵。光敏电阻灰度传感器同样易受外界光源的干扰,而且稳定性差,采集的灰度对比值偏差较大,机器人循迹时容易出错。由于激光传感器的接收器是接收激光的散射光,当多个激光传感器在同一空间循迹时,激光传感器会相互干扰,导致机器人循迹失败。

二、原理介绍

灰度传感器有数字传感器和模拟传感器两种,其原理大致相同。原理:一只发光二极管和一只光敏二极管,安装在同一面上。灰度传感器利用不同颜色的检测面对光的反射程度不同的原理进行颜色深浅检测。在有效的检测距离内(理论上距离可以无限远,实际受外界光源的影响,最佳距离为 15mm 至 50mm,如果距离过高的话,需要进行遮光),发光二极管发出的光,照射在检测面上,检测面反射部分光线,光敏二极管检测此光线的强度并将其转换为单片机可以识别的电信号。这个电信号是一个模拟值,单片机可以根据模拟值的大小进行二值化处理,也就是给一个电平分界线,当电压大于一个值的时候给一个高电平(或低电平),当电压小于一个值的时候给一个低电平(或高电平)。当然这里可以用电压比较器作为电平的参考电压。这就是我们用的数字量灰度传感器。数字量的灰度传感器如果加入的是单片机处理数据,那么可以把得到的原始数据加入滤波算法、数据混合算法得到一个波动小、适应环境强的数字传感器。如果对采集的原始的数据不做处理,那么就是模拟值输出。也就是我们的模拟量灰度传感器。因为每路传感器相互之间都是有误差的,所以同样的条件下模拟值肯定不是一样。在数字量和模拟量外,我们又创新出一种新的数据形式——偏移量。偏移量又称误差,所谓的偏移量就是输出传感器在循线所处的位置的值。其实偏移量是源自我们经常用到的PID 算法,P 值是误差值的系数,I 值是误差值的积分系数,D 是误差值的微分系数。所以 PID实际就是对误差的处理,我们通过单片机把这种误差通过运算直接可以通过串口输出,省去了我们测量模拟值然后再进行误差计算的过程。我们可以把得到的偏移量直接用于 PID 算法,PID 算法和速度结合,也就成了 PID 循线。如果要减小外界光线对数据的影响,可以传感器上加遮光罩。
在这里插入图片描述

三、通信协议

要想得到偏移量就必须使用串口传输的形式
在这里插入图片描述
下面来看偏移量是如何采集的
在这里插入图片描述
在这里插入图片描述
可以看到数据示例

下面看pid的代码

/*************************************
*函数名称:track_PID
*函数功能:直线循迹,用串口线连接,只输出偏移值
*参数:pwm:最大速度值,P:比例系数
*说明:根据位置式离散PID公式 
pwm=Kp*e(k)+Ki*∑e(k)+Kd[e(k)-e(k-1)]
e(k)代表本次偏差 
e(k-1)代表上一次的偏差  
∑e(k)代表e(k)以及之前的偏差的累积和;其中k为1,2,,k;
*			
**************************************/
void track_PID(int pwm,float P)
{
	static float Integral_error,Last_error;
	u16 temp_data[2] = { 0 };       //数据缓存区
	int error = 0;         //偏差值
	int L_Pwm,R_Pwm;			 //左右轮速度
	float I = 0,D = 0.8;		 //积分系数,微分系数
	
	Read_Data(temp_data);
	if(temp_data[0]==0)
	{
		error = -temp_data[1];
	}
	else
	{
		error = temp_data[1];
	}
	Integral_error += error;
	
	R_Pwm = (pwm-(error*P+Integral_error*I+(error-Last_error)*D));
	L_Pwm = (pwm+(error*P+Integral_error*I+(error-Last_error)*D));
	
	Last_error = error;
	
	if(pwm > 0)
	{
		if(L_Pwm > (pwm+10))
			L_Pwm = (pwm+10);
		if(R_Pwm > (pwm+10))
			R_Pwm = (pwm+10);
		if(L_Pwm <= 15)
			L_Pwm = 15;
		if(R_Pwm <= 15)
			R_Pwm = 15;
	}
	
	Set_Pwm(R_Pwm,L_Pwm);
	printf("error=%d\r\n",error);
	printf("RPWM=%d\r\n",L_Pwm);
	printf("LPWM=%d\r\n",R_Pwm);
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53

四、传感器的调试方法

在这里插入图片描述

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小小林熬夜学编程/article/detail/500057
推荐阅读
相关标签
  

闽ICP备14008679号