下推式磁悬浮PID调节

 

 关于如何制作,制作的原理,网上已经有一大堆博主大神给与了回答,随便搜一搜就是一把一把,所以我在这里(也不算传授)就说说我调节PID的时候的的调节方法吧。当然最开始需要基础准备的。(大神的话,貌似用不着我这讲解了)

基础准备

1.(针对我这样的渣渣说的)这里有一个很重要的点就是AD采集电路中变阻器的电路连接,基本人人都知道滑动变阻器其实就是接两个脚就行了,但是这里就有一个问题了如图

  这里你按照平常的接法是行不通的,所以必须接三根线(我试过了两根线能测得霍尔传感器的值,但是调节滑动变阻器没有反应,聪明的你肯定知道原因的)。

 2.AD采集,当电路连接好以后,电压很大,或者很小,别先急着下定论,很有可能是因为滑动变阻器值没调好,可以把滑动变阻器的值得到的定压事先调节到2.4v左右。如果电路没问题,调节滑动变阻器,可以改变采集的AD数值。

3.模型的搭建,这个很多都说过了,我也没啥说的(比起大佬,差的远,太远   无奈)

PID调节

      代码部分我就不说了,重要的就是频率问题。直接进入主题,说起PID调节,应该玩过平衡车什么的都很熟悉吧,而对于磁悬浮来说,这个需要调节两个PID,x轴和轴,但是也和你的硬件有关,假如你的硬件做的完美,那么你就用一套PID就行,如果和我一样是个硬件渣渣,那么久老实一个轴,一个轴来调。

      这里又有一个问题,强磁铁是需要浮在空中的,一条轴一条轴来调似乎是不现实的,但是也不是没有可能,我是这么调的

      首先把两个PID的值设置成一样,然后慢慢调节P值(这题目关键就在P值),调节到一种什么情况呢,就是小了完全感受不到线圈的拉力,大一点点就都得剧烈(最好调到最适合的P值),然后课看到浮子,在空中,来回那么两下,这时候就进入的初步阶段的。

      然后我们需要进行分开调试,这时候你得用手充当固定的一个轴的力,但是记住,别卡死,要很松,就是不给它掉下去,然后对另外一轴进行精调,调节D值,如果过程中觉得还是抖的有点剧烈,可以尝试减小P值(到最适合的),继续调节D值,调到什么程度呢,就是你看到浮子不晃动了,或者轻微晃动。然后另外一个轴也是一样的调节方法。当你两个轴都调完的时候,合在一起,恭喜你,可以开始悬浮几秒钟了,想悬浮的久的话,还需要继续调节,这个时候就视情况而调节了。

主函数

while(1)
	{
		x_temp=AD_get(ADC_Channel_1,50,130,150);
		y_temp=AD_get(ADC_Channel_2,50,170,190);
		x_error=X_f-x_temp;
		y_error=Y_f-y_temp;

		if(x_error>=0)	
		{			
			A_po();//A正向输出
			flag = 1;
			printf("  输出正  ");
		}
		else							
		{
			A_ag();
			printf("  输出负  ");
		}
		if(y_error<=0)	
		{			
			B_po();//B正向输出
			printf("  输出正  ");
		}
		else					
		{			
			B_ag();
			printf("  输出负  ");
		}
		x=PID(0,X_f,x_temp);
		y=PID(1,Y_f,y_temp);
		TIM_SetCompare1(TIM3,x);//x轴
		TIM_SetCompare2(TIM3,y);//y轴
		printf("++out1 %f ++\n\n\n",x);
		printf("++out2 %f ++\n\n\n",y);
		//数据上传到上位机观察波形
		USART1_AHRS_Report((short)(x), (short)(y), (short)(x_temp/2), (short)(y_temp/2));

PID部分

#include "pid.h"
#include "pwm.h"
#include "led.h"
#include "usart.h"

#define MAX_PID_OUTPUT  750
//#define P  0.2
//#define D  0.3
u16 flag=0;
float PID(u8 z,u16 x,u16 y)//标志位 当前值 给定值
{
	static float kp  ,ki , kd ,i,control;
	static float X_e[2],Y_e[2];//X轴误差 Y轴误差
	static float X_z_e,Y_z_e;//X轴积分参数 Y轴积分参数
	static float pwnoutput1,pwnoutput2;
	u8 flag;
	if(z==0)
	{

	  kp =0.18;
	  ki =0; 
	  kd =0.36;

		//积分分离
		X_e[0] = y-x;//差值
		if(X_e[0]>=60||X_e[0]<=-60) {flag = 0;}
		else{flag = 1;X_z_e+=X_e[0];}
		//积分限幅
		i = 50000;
		if(X_z_e>i)  X_z_e = i;
		else if(X_z_e<-i)  	X_z_e = -i;
		
		pwnoutput1 = kp*X_e[0]+flag*ki*X_z_e+kd*(X_e[0]-X_e[1]);
		X_e[1] = X_e[0];
	 
   if (pwnoutput1 > MAX_PID_OUTPUT) //限幅
		(pwnoutput1 = MAX_PID_OUTPUT);
	 else if (pwnoutput1 < -MAX_PID_OUTPUT)
		(pwnoutput1 = -MAX_PID_OUTPUT);
	 control=pwnoutput1;
	 if(control<0) control=-control;
	 
	 
	 
	}
	else
	{
		kp =0.194;
	  ki =0; 
	  kd =0.35;

	
		Y_e[0] = y-x;//²îÖµ
		if(Y_e[0]>=60||Y_e[0]<=-60) {flag = 0;}
		else{flag = 1;Y_z_e+=Y_e[0];}
		//»ý·ÖÏÞ·ù
		i = 50000;
		if(Y_z_e>i)	Y_z_e = i;
		else if(Y_z_e<-i)	Y_z_e = -i;
		pwnoutput2 = kp*Y_e[0]+flag*ki*Y_z_e+kd*(Y_e[0]-Y_e[1]);
		Y_e[1] = Y_e[0]; 
		 
	 if (pwnoutput2 > MAX_PID_OUTPUT) //限幅
		(pwnoutput2 = MAX_PID_OUTPUT);
	 else if (pwnoutput2 < -MAX_PID_OUTPUT)
		(pwnoutput2 = -MAX_PID_OUTPUT);
		control=pwnoutput2;
	 if(control<0) control=-control;

	}
	return control;

猜你喜欢

转载自blog.csdn.net/qq_39200996/article/details/81477223
今日推荐