
PID定速定距演示器
简介
项目用于学习PID算法,使用此算法实现快速达到设定电机速度和快速让达到规定电机旋转次数的功能,通过显示屏将PID曲线实时显示出来,更加方便我们观察变化。
简介:项目用于学习PID算法,使用此算法实现快速达到设定电机速度和快速让达到规定电机旋转次数的功能,通过显示屏将PID曲线实时显示出来,更加方便我们观察变化。开源协议
:CC BY-NC-SA 3.0
描述
项目简介
项目用于学习PID算法,使用此算法实现快速达到设定电机速度和快速让达到规定电机旋转角度的功能,通过显示屏将PID曲线实时显示出来,更加方便我们观察变化。
项目功能
提前设置一个电机要到达的速度和角度,几个按键就实现了页面切换,数值加减,电机旋转。设定好目标值,电机就会快速达到目标速度或者角度,体现PID在控制类算法方面还是很不错的。
硬件说明
硬件组成较为简单,只有电机,电机驱动,滤波,开发板和显示屏几个部分,这里就不过多阐述。
软件说明
我觉得这次比较大的收获是软件架构,还有PID相关的知识。
常用的软件架构有,轮询、中断、状态机还有实时操作系统。
在实际开发中,单一的结构通常满足不了要求,因此经常会将几种结构混在一起使用。例如,本项目就使用的 轮询 + 中断 + 状态机 结构。
项目中涉及到的界面切换:
typedef enum {
DEFAULT_PAGE=0, // 首页(默认)
PID_PAGE, // 定速页
DISTANCE_PAGE, // 定距页
SET_PAGE, // 设置页
PARAMETER_PAGE // 调参页
} SystemPageShow;
首页状态机

定速状态机

调参状态机

像这样把操作逻辑给用这种形式写出来,有助于我们理解。
PID算法,即比例P-积分I-微分D控制器,它通过控制系统的偏差(目标值与实际值之间的差)来调节控制变量,使得系统达到或维持在一个预定的状态。
PID__OUT = (Kp x P)+ (Ki x I)+(Kd x D)
公式拆分为静态参数和动态参数:
静态参数
Kp 是比例增益
Ki 是积分增益
Kd 是微分增益
动态参数
P = 设定值与实际值之间的误差e
I = 误差e的累加
D = 当前误差e - 之前的误差last_e
将公式转换为代码,如下:
{
float kp, ki, kd; // 三个静态系数
float change_p, change_i, change_d; // 三个动态参数
float error, last_error; // 误差、之前误差
float max_change_i; // 积分限幅
float output, max_output; // 输出、输出限幅
int target; // 目标
}PID;
/****************************************************
功能:PID计算
参数:pid = pid的参数输入
target = 目标值
current = 当前值
返回:PID计算后的结果
****************************************************/
float pid_calc(PID *pid, float target, float current)
{
//用上一次的误差值更新 之前误差last_error
pid->last_error = pid->error;
//获取新的误差 = 目标值 - 当前值
pid->error = target - current;
//计算比例P = 目标值与实际值之间的误差e
float pout = pid->error;
//计算积分I = 误差e的累加
pid->change_i += pid->error;
//计算微分D = 当前误差e - 之前的误差last_e
float dout = pid->error - pid->last_error;
//积分I 限制不能超过正负最大值
if(pid->change_i > pid->max_change_i)
{
pid->change_i = pid->max_change_i;
}
else if(pid->change_i < -pid->max_change_i)
{
pid->change_i = -pid->max_change_i;
}
//计算输出PID_OUT = (Kp x P)+ (Ki x I)+(Kd x D)
pid->output = (pid->kp * pout) + (pid->ki * pid->change_i) + (pid->kd * dout);
//输出 限制不能超过正负最大值
if(pid->output > pid->max_output) pid->output = pid->max_output;
else if(pid->output < -pid->max_output) pid->output = -pid->max_output;
//返回PID计算的结果
return pid->output;
}
实物图

设计图
未生成预览图,请在编辑器重新保存一次BOM
暂无BOM
克隆工程知识产权声明&复刻说明
本项目为开源硬件项目,其相关的知识产权归创作者所有。创作者在本平台上传该硬件项目仅供平台用户用于学习交流及研究,不包括任何商业性使用,请勿用于商业售卖或其他盈利性的用途;如您认为本项目涉嫌侵犯了您的相关权益,请点击上方“侵权投诉”按钮,我们将按照嘉立创《侵权投诉与申诉规则》进行处理。
请在进行项目复刻时自行验证电路的可行性,并自行辨别该项目是否对您适用。您对复刻项目的任何后果负责,无论何种情况,本平台将不对您在复刻项目时,遇到的任何因开源项目电路设计问题所导致的直接、间接等损害负责。









