搜索
bottom↓
回复: 303

PID算法实现(c 语言)(来自老外)

  [复制链接]

出0入0汤圆

发表于 2013-7-15 22:17:54 | 显示全部楼层 |阅读模式
论坛里讲PID原理的挺多,但是讲算法的实现却比较少,或是比较难懂,今天网上找到一个老外写的PID C语言实现,P ,I ,D 各环节独立实现,还是比较好理解的。
  1. PID算法(c 语言)(来自老外)
  2. (2010-02-17 00:18:24)
  3. 转载
  4. #include <stdio.h>
  5. #include<math.h>
  6. //定义PID 的结构体
  7. struct _pid
  8. {
  9. int pv; //integer that contains the process value 过
  10. 程量
  11. int sp; //*integer that contains the set point   设
  12. 定值
  13. float integral; // 积分值 -- 偏差累计值
  14. float pgain;
  15. float igain;
  16. float dgain;
  17. int deadband;    //死区
  18. int last_error;
  19. };

  20. struct _pid warm,*pid;
  21. int process_point, set_point,dead_band; float p_gain, i_gain, d_gain,
  22. integral_val,new_integ;;

  23. //------------------------
  24. ----------------------
  25. pid_init DESCRIPTION This function initializes the
  26. pointers  in  the  _pid  structure  to  the  process  variable
  27. and the setpoint. *pv and *sp are integer pointers.
  28. //------------------------
  29. ----------------------

  30. void pid_init(struct _pid *warm, int process_point,
  31. int set_point)
  32. {
  33. struct _pid *pid;
  34. pid = warm;
  35. pid->pv = process_point;
  36. pid->sp = set_point;
  37. }

  38. //------------------------
  39. ----------------------pid_tune DESCRIPTION Sets the proportional gain
  40. (p_gain), integral gain (i_gain),
  41. derivitive  gain  (d_gain),  and  the  dead  band  (dead_band)
  42. of a pid control structure _pid.  

  43. 设定PID参数 ---- P,I,D,死区
  44. //------------------------
  45. ----------------------

  46. void pid_tune(struct _pid *pid, float p_gain, float
  47. i_gain, float d_gain, int dead_band)
  48. {
  49. pid->pgain = p_gain;
  50. pid->igain = i_gain;
  51. pid->dgain = d_gain;
  52. pid->deadband = dead_band;
  53. pid->integral= integral_val;
  54. pid->last_error=0;
  55. }

  56. //------------------------
  57. ---------------------- pid_setinteg DESCRIPTION Set a new value for the
  58. integral term of the pid equation.
  59. This is useful for setting the initial output of the
  60. pid controller at start up.

  61. 设定输出初始值
  62. //------------------------
  63. ----------------------

  64. void pid_setinteg(struct _pid *pid,float new_integ)
  65. {
  66. pid->integral = new_integ;
  67. pid->last_error = 0;
  68. }

  69. //------------------------
  70. ----------------------
  71. pid_bumpless DESCRIPTION Bumpless transfer
  72. algorithim.
  73. When suddenly changing setpoints, or when restarting
  74. the PID equation after an extended pause,
  75. the derivative of the equation can cause a bump in the controller output. This function will help smooth out
  76. that bump.
  77. The process value in *pv should be the updated just
  78. before this function is used.

  79. pid_bumpless 实现无扰切换
  80. 当突然改变设定值时,或重新启动后,将引起扰动输出。这
  81. 个函数将能实现平顺扰动, 在调用该函数之前需要先更新 PV值
  82. //------------------------
  83. ----------------------

  84. void pid_bumpless(struct _pid *pid)
  85. {
  86. pid->last_error = (pid->sp)-(pid->pv);  //设定值与反馈值偏差
  87. }

  88. //------------------------
  89. ----------------------
  90. pid_calc  DESCRIPTION  Performs  PID  calculations  for  the
  91. _pid structure *a. This function uses the positional form of the pid
  92. equation, and incorporates an integral windup
  93. prevention algorithim.
  94. Rectangular  integration  is  used,  so  this  function  must
  95. be repeated on a consistent time basis for accurate
  96. control.
  97. RETURN VALUE The new output value for the pid loop.
  98. USAGE #include "control.h"
  99. 本函数使用位置式PID计算方式,并且采取了积分饱和限制运算
  100. PID计算
  101. //------------------------
  102. ----------------------

  103. float pid_calc(struct _pid *pid)

  104. int err;
  105. float pterm, dterm, result, ferror;

  106. // 计算偏差
  107. err = (pid->sp) - (pid->pv);
  108. // 判断是否大于死区
  109. if (abs(err) > pid->deadband)
  110. {
  111. ferror = (float) err;   //do integer to float
  112. conversion only once 数据类型转换

  113. // 比例项
  114. pterm = pid->pgain * ferror;

  115. if (pterm > 100 || pterm < -100)
  116. {
  117. pid->integral = 0.0;
  118. }
  119. else
  120. {
  121. // 积分项
  122. pid->integral += pid->igain * ferror;

  123. // 输出为0--100%
  124. // 如果计算结果大于100,则等于100
  125. if (pid->integral > 100.0)
  126. { pid->integral = 100.0;
  127. }
  128. // 如果计算结果小于0.0,则等于0
  129. else if (pid->integral < 0.0)
  130. pid->integral = 0.0;

  131. }

  132. // 微分项
  133. dterm  =  ((float)(err  -  pid->last_error))  *  pid->dgain;

  134. result = pterm + pid->integral + dterm;
  135. }
  136. else
  137. result = pid->integral; // 在死区范围内,保持现有输出

  138. // 保存上次偏差
  139. pid->last_error = err;

  140. // 输出PID值(0-100)
  141. return (result); }
  142.   
  143. //------------------------
  144. ----------------------
  145. void main(void)
  146. {
  147. float display_value;
  148. int count=0;
  149. pid = &warm;

  150. // printf("Enter the values of Process point, Set
  151. point, P gain, I gain, D gain \n");
  152. // scanf("%d%d%f%f%f", &process_point, &set_point,
  153. &p_gain, &i_gain, &d_gain);

  154. // 初始化参数
  155. process_point = 30;
  156. set_point = 40;
  157. p_gain = (float)(5.2);
  158. i_gain = (float)(0.77);
  159. d_gain = (float)(0.18);
  160. dead_band = 2;  
  161. integral_val =(float)(0.01);

  162. printf("The  values  of  Process  point,  Set  point,  P  gain,
  163. I gain, D gain \n");
  164. printf(" %6d %6d %4f %4f %4f\n", process_point,
  165. set_point, p_gain, i_gain, d_gain);
  166. printf("Enter the values of Process point\n");
  167. while(count<=20)
  168. {
  169. scanf("%d",&process_point);

  170. // 设定PV,SP 值
  171. pid_init(&warm, process_point, set_point);

  172. // 初始化PID 参数值
  173. pid_tune(&warm, p_gain,i_gain,d_gain,dead_band);

  174. // 初始化PID 输出值
  175. pid_setinteg(&warm,0.0);
  176. //pid_setinteg(&warm,30.0);
  177. //Get input value for process point
  178. pid_bumpless(&warm);

  179. // how to display output
  180. display_value = pid_calc(&warm);

  181. printf("%f\n", display_value);
  182. //printf("\n%f%f%f%f",warm.pv,warm.sp,warm.igain,wa
  183. rm.dgain);

  184. count++;
  185. }
  186. }
复制代码
PDF文档:

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

阿莫论坛20周年了!感谢大家的支持与爱护!!

一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。

出0入0汤圆

 楼主| 发表于 2013-9-28 23:52:34 来自手机 | 显示全部楼层
本帖最后由 summarize 于 2013-9-28 23:53 编辑

老外的是位置式PID,我在网上找了增量式PID公式.如下:

△u=Kp*(e0-e1) + Ki*e0 + Kd*(e0 - 2*e1 + e2);
u += △u

e0为本次偏差; e1是上次偏差; e2是上上次偏差。u为本次输出。

出0入0汤圆

发表于 2013-7-16 08:05:48 来自手机 | 显示全部楼层
标记学习!

出0入0汤圆

发表于 2013-7-16 08:16:07 | 显示全部楼层
好资料啊~收藏了

出0入0汤圆

发表于 2013-7-16 15:42:47 | 显示全部楼层
学习了,谢谢楼主

出0入0汤圆

发表于 2013-7-16 17:58:03 | 显示全部楼层
好资料!

出0入0汤圆

发表于 2013-7-16 18:07:15 | 显示全部楼层
mrk 不错的资料。

出0入0汤圆

发表于 2013-9-7 13:07:30 | 显示全部楼层
学习了,谢谢楼主分享

出0入0汤圆

发表于 2013-9-7 13:24:09 | 显示全部楼层
参考下

出0入0汤圆

发表于 2013-9-7 13:24:24 | 显示全部楼层
参考下

出0入0汤圆

发表于 2013-9-7 13:56:51 | 显示全部楼层
多谢楼主分享,之前用过这个程序,好不错

出0入0汤圆

发表于 2013-9-7 15:55:41 | 显示全部楼层
参考下!

出0入0汤圆

发表于 2013-9-7 16:26:56 | 显示全部楼层
学习之。。。

出0入0汤圆

发表于 2013-9-7 21:44:37 | 显示全部楼层
谢谢分享

出0入4汤圆

发表于 2013-9-7 22:03:08 | 显示全部楼层
试试看!!

出0入0汤圆

发表于 2013-9-7 22:03:52 | 显示全部楼层
mark............

出0入0汤圆

发表于 2013-9-8 00:24:01 来自手机 | 显示全部楼层
下来看看

出0入0汤圆

发表于 2013-9-8 00:31:31 | 显示全部楼层
很不错,结合其他书来看,很不错啊

出0入0汤圆

发表于 2013-9-8 06:03:05 | 显示全部楼层
下载看看

出0入0汤圆

发表于 2013-9-8 07:51:18 | 显示全部楼层
markmarkmarkmarkmarkmarkmarkmarkmark

出0入0汤圆

发表于 2013-9-8 09:17:21 | 显示全部楼层
收藏了,谢谢

出0入0汤圆

发表于 2013-9-8 09:26:57 | 显示全部楼层
老外的?难懂了

出0入0汤圆

发表于 2013-9-8 10:13:15 | 显示全部楼层
多谢楼主

出0入0汤圆

发表于 2013-9-8 21:52:29 | 显示全部楼层

好资料啊,学习了先

出0入0汤圆

发表于 2013-9-8 22:31:38 | 显示全部楼层
学习了,谢谢楼主分享

出5入0汤圆

发表于 2013-9-8 23:01:12 | 显示全部楼层
学习                              

出0入0汤圆

发表于 2013-9-8 23:11:59 | 显示全部楼层
仔细地好好学习!

出0入0汤圆

发表于 2013-9-8 23:49:51 | 显示全部楼层
不错,MARK。

出0入0汤圆

发表于 2013-9-9 08:04:36 | 显示全部楼层
谢谢楼主

出0入0汤圆

发表于 2013-9-9 08:19:01 | 显示全部楼层
搞硬件真正懂算法的人并不多,这个得顶。

出0入0汤圆

发表于 2013-9-9 08:28:39 | 显示全部楼层
好用吗????

出0入0汤圆

 楼主| 发表于 2013-9-9 08:33:43 | 显示全部楼层
tangbaiwen 发表于 2013-9-9 08:28
好用吗????

用了都说好.

出0入0汤圆

发表于 2013-9-9 08:52:22 | 显示全部楼层
标记学习一下

出0入0汤圆

发表于 2013-9-9 08:53:26 | 显示全部楼层
学习学习。

出0入0汤圆

发表于 2013-9-9 08:56:08 | 显示全部楼层
好东西,收藏了
谢谢分享

出0入0汤圆

发表于 2013-9-9 08:59:31 | 显示全部楼层
学习一下
谢谢

出0入8汤圆

发表于 2013-9-9 09:24:24 | 显示全部楼层
标注,学习,备用,谢谢楼主

出0入0汤圆

发表于 2013-9-9 09:27:07 | 显示全部楼层
试试去。

出0入0汤圆

发表于 2013-9-9 09:37:13 | 显示全部楼层
pid学习,谢谢

出0入0汤圆

发表于 2013-9-17 10:24:07 | 显示全部楼层
东西不错,值得学习

出0入0汤圆

发表于 2013-9-17 10:30:34 | 显示全部楼层
学习学习

出0入0汤圆

发表于 2013-9-17 10:46:59 | 显示全部楼层
学习了,谢谢楼主分享

出0入0汤圆

发表于 2013-9-17 13:05:27 | 显示全部楼层
好资料,谢谢分享 ,可以好好学习学习!

出0入0汤圆

发表于 2013-9-17 13:21:28 | 显示全部楼层
怎么现在无法下载此文档啊??

出0入0汤圆

发表于 2013-9-17 13:30:39 | 显示全部楼层
mark..........

出0入0汤圆

发表于 2013-9-17 13:37:47 | 显示全部楼层
用用看吧

出0入0汤圆

发表于 2013-9-17 15:30:06 | 显示全部楼层
学习一下,PID原理貌似简单,要做好却很难

出0入0汤圆

发表于 2013-9-24 10:01:42 | 显示全部楼层
好东西收藏了.

出0入0汤圆

发表于 2013-9-24 10:25:23 | 显示全部楼层
收藏,谢谢

出0入0汤圆

发表于 2013-9-24 11:33:57 | 显示全部楼层
这个必须要顶...

出0入0汤圆

发表于 2013-9-24 11:41:57 | 显示全部楼层
收藏了
谢谢分享

出0入0汤圆

发表于 2013-9-24 14:32:39 | 显示全部楼层
收藏了,找时间研究研究

出0入0汤圆

发表于 2013-9-24 17:41:00 | 显示全部楼层
很好理解!!!!

出0入0汤圆

发表于 2013-9-24 17:43:18 | 显示全部楼层
感谢楼主,参考下

出0入0汤圆

发表于 2013-9-24 17:44:52 | 显示全部楼层
参考学习了。

出0入0汤圆

发表于 2013-9-24 18:43:53 | 显示全部楼层
好贴,支持,,正想要学pid,真的好难

出0入0汤圆

发表于 2013-9-24 18:51:42 | 显示全部楼层
不管有没有用,先收藏先。谢谢

出0入270汤圆

发表于 2013-9-24 20:31:46 | 显示全部楼层
Mark----               

出0入0汤圆

发表于 2013-9-24 20:32:13 | 显示全部楼层
记号,希望可以看得懂

出0入0汤圆

发表于 2013-9-24 22:16:28 | 显示全部楼层
这个pID以后借鉴

出0入0汤圆

发表于 2013-9-25 09:18:34 来自手机 | 显示全部楼层
学习下            

出0入0汤圆

发表于 2013-9-25 12:50:57 | 显示全部楼层
感谢楼主,准备学四轴呢

出0入0汤圆

发表于 2013-9-25 15:52:34 | 显示全部楼层
mark

出0入0汤圆

发表于 2013-9-25 16:41:10 | 显示全部楼层
MARK.. 马克

出0入0汤圆

发表于 2013-9-25 16:44:19 | 显示全部楼层
收藏了。。

出10入95汤圆

发表于 2013-9-26 10:31:13 | 显示全部楼层
谢谢   

出0入0汤圆

发表于 2013-9-26 10:50:57 | 显示全部楼层
学习了。。谢谢楼主分享。

出0入0汤圆

发表于 2013-9-26 10:58:34 | 显示全部楼层
好资料。收藏学习了,谢谢分享

出0入0汤圆

发表于 2013-9-26 11:10:22 | 显示全部楼层
PID只用过最简单的方式

出0入0汤圆

发表于 2013-9-26 11:10:47 | 显示全部楼层
其中的精美还没有仔细体会到

出0入0汤圆

发表于 2013-9-26 11:11:06 | 显示全部楼层
有待学习加强

出0入0汤圆

发表于 2013-9-26 11:29:38 | 显示全部楼层
帅气,先收着学习了

出0入0汤圆

发表于 2013-9-29 06:34:13 来自手机 | 显示全部楼层
不錯,1可以参考

出0入0汤圆

发表于 2013-9-29 08:14:14 | 显示全部楼层
正准备研究呢,感谢楼主了

出0入0汤圆

发表于 2013-9-30 13:49:05 | 显示全部楼层
有空学习下

出0入0汤圆

发表于 2013-9-30 15:47:33 | 显示全部楼层
学习了,谢谢!

出0入0汤圆

发表于 2013-9-30 20:43:17 | 显示全部楼层
mark,先收藏了,慢慢研究

出0入0汤圆

发表于 2013-9-30 21:38:07 | 显示全部楼层
分享了,顶

出0入0汤圆

发表于 2013-11-25 10:33:15 | 显示全部楼层
看看看不知道能用在照度上吗

出0入0汤圆

发表于 2013-11-25 11:14:13 | 显示全部楼层
谢谢,正好需要用,来学习学习。。。。

出0入4汤圆

发表于 2013-11-25 11:25:41 | 显示全部楼层

学习学习

出0入0汤圆

发表于 2013-11-25 12:21:48 | 显示全部楼层
好资料,学习一下

出0入0汤圆

发表于 2013-11-25 13:00:43 | 显示全部楼层
mark,现在真开始限制字数了。。

出0入0汤圆

发表于 2013-11-25 14:58:02 | 显示全部楼层

谢谢,正好需要用

出0入0汤圆

发表于 2013-11-25 15:41:19 来自手机 | 显示全部楼层
不错的PID资料,收了

出0入0汤圆

发表于 2013-11-26 10:23:20 | 显示全部楼层
标记先

出0入0汤圆

发表于 2013-11-26 10:45:47 | 显示全部楼层
非常不错!学习了

出0入0汤圆

发表于 2013-11-26 11:05:54 | 显示全部楼层
不错,舍得参考。

出0入0汤圆

发表于 2013-12-11 16:21:11 | 显示全部楼层
标记先

出0入0汤圆

发表于 2013-12-12 08:16:53 | 显示全部楼层
标记了 以后慢慢看那

出0入0汤圆

发表于 2013-12-13 04:53:38 | 显示全部楼层
mark 做东西用         

出0入0汤圆

发表于 2013-12-13 12:30:00 | 显示全部楼层
好东西啊,谢谢楼主...

出0入4汤圆

发表于 2013-12-13 22:33:33 | 显示全部楼层
必须收藏!!

出0入0汤圆

发表于 2013-12-14 15:59:04 | 显示全部楼层
标记学习!

出0入0汤圆

发表于 2013-12-14 16:05:51 | 显示全部楼层
文档下载后就不是PDF文件了 ,也打开不了

出0入0汤圆

发表于 2013-12-14 16:06:30 | 显示全部楼层
文档下载后就不是PDF文档了,也打开不了

出0入0汤圆

发表于 2013-12-14 19:09:39 | 显示全部楼层
很好,喜欢!

出0入0汤圆

发表于 2013-12-14 21:02:28 | 显示全部楼层
mark .学习

出0入0汤圆

发表于 2013-12-14 21:21:48 | 显示全部楼层

出0入0汤圆

发表于 2013-12-14 21:38:31 | 显示全部楼层
学习下                 
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-3-29 22:32

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表