使用VOFA+工具用于调试PID算法

继上一篇介绍如何使用VOFA+之后,本文介绍使用VOFA+工具用于调试PID算法(重点是实现使用此工具用于调试,而非介绍算法,我也不确定以下算法的正确性,大家参考即可)。

一、首先验证发的数据正确性。

当我配置发送“0”和“0”数据时,上位机收到数据如图。00 00 80 7F为帧尾。

当我配置发送“1”和“2”数据时,上位机收到数据如图。00 00 80 7F为帧尾。

如果收到数据不是以上情况,则说明串口发送数据的格式不正确。

定时器中断中调用,控制算法和发送函数均在一个函数中实现。

//定时器中,1Ms调用一次,固定时间调用
void AppAlgDeal(void)
{
	static int32_t TimeCnt;
	static float tempFloat[2];
	static uint8_t tempData[12] = {0,0,0,0,0,0,0,0,0,0,0x80,0x7F};
	int32_t speed;
	TimeCnt++;
	if(TimeCnt >= 10)
	{
		TimeCnt = 0;
		
		//1. 速度计算(固定时间中,所走的路程,这里简化计算,按照固定实际所走的脉冲)
		speed = SpeedCalc.CntCurt - SpeedCalc.CntRecd;
		SpeedCalc.CntRecd = SpeedCalc.CntCurt;
		//计算速度平均值(因速度计算波动大,所以采用求和进行滤波,但这样带来的结果是响应变慢)
		SpeedCalc.SpeedSum = SpeedCalc.SpeedSum + speed - SpeedCalc.CntRecord[SpeedCalc.Cnt];
		SpeedCalc.CntRecord[SpeedCalc.Cnt] = speed;
		SpeedCalc.Cnt++;
		SpeedCalc.Cnt&=3;
		
		//2. PID算法(位置式PID)
		pwmVal += PID_Contrl(&PID_Para, SpeedCalc.SpeedSum);
		
		//3. PWM限幅,最大为500,最小为0
		if(pwmVal > 500)
			pwmVal = 500;
		else if(pwmVal < 0)
			pwmVal = 0;
		__HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_3, pwmVal);	//送出到PWM输出

		//4. 串口发送
		tempFloat[0] = PID_Para.TitelVal;
		tempFloat[1] = (float)SpeedCalc.SpeedSum;
		memcpy(tempData, (uint8_t *)&tempFloat, sizeof(tempFloat));
		HAL_UART_Transmit_IT(&huart6, (uint8_t *)tempData, 12);
	}
}

 二、PID介绍。PID在离散领域实现时分为位置式和增量式。

以下介绍中使用位置式。(不过我也不确定我使用的对不对)

位置式PID算法。

/*************************************************
 *函数名称:float PID_Contrl(sPID_Reg* sPt,float RealVal)
 *功    能:PID控制                                   
 *参    数:sPt PID参数,RealVal 当前实际值
 *返 回 值:void                                       
*************************************************/
float PID_Contrl(sPID_Reg* sPt,float RealVal)
{
	float error,add;
	
	error = sPt->TitelVal - RealVal;	//当前误差  设定的目标值和实际值的偏差
	
	add = sPt->Kp * error				//增量计算
			  - sPt->Ki * sPt->LastError
			  + sPt->Kd * sPt->PrevError;
	
	/*存储误差  用于下次计算*/
	sPt->PrevError = sPt->LastError;
	sPt->LastError = error;
	
	return add;							//返回增量值
}

参数初始化


typedef struct{
	float TitelVal;		//目标值
	float SumError;		//累计误差
	float Kp;					//比例项
	float Ki;					//积分项
	float Kd;					//微分项
	float LastError;	//上次偏差
	float PrevError;	//上上次偏差值
}sPID_Reg;

sPID_Reg PID_Para;		//定义PID参数

void PID_Arg_Init(sPID_Reg* sPt)
{
	memset(sPt, 0, sizeof(sPID_Reg));
	sPt->Kp = 0.5;
	sPt->Ki = 0.1;
	sPt->Kd = 0.01;
	sPt->TitelVal = 100;
}

三、配置发送2个数据。分别为目标速度和实际速度。

 以下图片中,红色为目标速度,绿色为实际速度。右边框中分别为Kp,Ki,Kd数据。

Kp,Ki,Kd分别为1.5,0,0。

Kp,Ki,Kd分别为1,0,0。

Kp,Ki,Kd 分别为0.5,0,0。

Kp,Ki,Kd 分别为1,0.2,0。

 Kp,Ki,Kd 分别为1,0.4,0。

 Kp,Ki,Kd 分别为0.5,0.1,0.01。 

以上工程我放在此链接下,供下载参考。(Stm32CubeMx工程也在附件中)

https://download.csdn.net/download/weixin_42316458/79692273

我使用的是STM32F401RCT6芯片。

以上完结。

本人新建了个QQ群,如想进一步沟通可添加:947187213。

版权声明:本文为CSDN博主「一个做底层的码农」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_42316458/article/details/121502912

生成海报
点赞 0

一个做底层的码农

我还没有学会写个人说明!

暂无评论

发表评论

相关推荐

使用VOFA+工具用于调试PID算法

继上一篇介绍如何使用VOFA之后,本文介绍使用VOFA工具用于调试PID算法(重点是实现使用此工具用于调试,而非介绍算法,我也不确定以下算法的正确性,大家参考即可&#xff0

三相电机相电感,相电阻和极对数的测量

相电阻测量: 方法一:可使用万用表电阻档直接测量其中两端 方法二:可使用LCR数字电桥仪器测量 万用表操作: 将万用表旋转到电阻档的适当量程内 将万用表上的两表笔接触在电机的其中任意

DDR3基础详解

DDR3基础详解最近在IMX6平台下做DDR3的测试接口开发,以前在学习嵌入式时,用的是官方源码,没有做过多的研究。此时需要仔细研究DDR3的引脚与时序,此篇是我在学习DDR3做的归纳与总