使用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。

  • 38
    点赞
  • 391
    收藏
    觉得还不错? 一键收藏
  • 17
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 17
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值