OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 2629|回复: 1

关于pid控制舵机的反应问题

[复制链接]

14

主题

36

帖子

0

精华

初级会员

Rank: 2

积分
194
金钱
194
注册时间
2019-6-18
在线时间
67 小时
发表于 2019-9-8 10:09:27 | 显示全部楼层 |阅读模式
9金钱
  大家好,我在做一个用pid控制MG995舵机的平衡球实验,产生的问题是反应速度太慢。
MG995:根据输入的20ms脉冲中高低电平比例输出0~180度的旋转角度,反应转速约0.17秒/60°
其中设置了300毫秒的采样周期,主函数中是进行初始化之后,就进行{ pid的计算函数和输出舵机PWM }的死循环,但是实际试验时,
舵机几乎每两秒才动一下,反应太慢,现在想让它大概每一次转动的时间不超过500毫秒。
希望大家指点一下,帮帮忙,感谢了



正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

14

主题

36

帖子

0

精华

初级会员

Rank: 2

积分
194
金钱
194
注册时间
2019-6-18
在线时间
67 小时
 楼主| 发表于 2019-9-8 12:47:36 | 显示全部楼层

  1. int main(void)
  2. {       
  3.         delay_init();                                 //延时函数初始化00
  4.         uart_init(9600);                              //串口初始化为9600
  5.         LED_Init();                             //初始化与LED连接的硬件接口
  6.         Timer3_init();
  7.   Isr_Init();                    //这个是中断的初始化
  8.   PID_Init();                    //PID设定初始化
  9.         TIM1_PWM_Init(199,7199);       //不分频
  10.         Adc_Init();                    //ADC初始化
  11.   LED1=0;
  12.         TIM_SetCompare1(TIM1,185);
  13. while(1)
  14.         {
  15.                 PID_Calc();               
  16.                 printf("%d         jiaodu\r\n",pid.OUT);
  17.     TIM_SetCompare1(TIM1,pid.OUT);
  18.         }
  19. }



  20. 这个是定时中断函数

  21. void TIM3_IRQHandler() //10ms 1次
  22. {                                          
  23.   u16 Kms10;
  24.         static u16 tsec; u8 st;
  25.         st=TIM_GetFlagStatus(TIM3, TIM_IT_Update);
  26.         if(st!=0)
  27.         {  
  28.                  TIM_ClearFlag(TIM3, TIM_IT_Update);
  29.            Kms10++;
  30.                  pid.C10ms++;
  31.                  if(tsec++>=30)
  32.                 {
  33.                   tsec=0;
  34.                 }
  35.         }
  36. }



  37. 这个是pid计算的函数,目前先用P
  38. void PID_Calc()
  39. {
  40.         float DelEk;
  41.   float ti;
  42.   float ki;
  43.         float td;
  44.         float kd;
  45.         float Iout;
  46.         float Pout;
  47.         float Dout;
  48.         float out;
  49.         float temp;
  50.        
  51.         if(pid.C10ms<pid.T/10)  //计算周期未到
  52. {
  53.         return ;
  54. }

  55. pid.Pv=Get_Adc_Average(ADC_Channel_1,10);
  56. temp=(float)pid.Pv*(3.3/4096);
  57. pid.Pv=temp;
  58.    
  59. pid.Ek = pid.Sv-pid.Pv;   //得到当前偏差值
  60. Pout = pid.Kp*pid.Ek;    //PID中的P,即比例输出
  61. /*
  62. pid.SEk = pid.Ek+pid.SEk;   //历史偏差总和
  63. DelEk = pid.Ek-pid.Ek_1;    //最近两次偏差之差

  64. ti = pid.T/pid.Ti;
  65. ki = ti*pid.Kp;
  66. Iout = ki*pid.SEk*pid.Kp;   //PID中的I,即积分输出

  67. td = pid.Td/pid.T;
  68. kd = td*pid.Kp;
  69. Dout = kd*DelEk;        //PID中的D,即微分输出
  70. */
  71. //out = Pout+Iout+Dout+pid.OUT0; // 本次的计算结果,由四部分合成
  72. out = Pout+Iout+pid.OUT0;

  73. if(out > pid.pwmcyle)
  74. {
  75.   pid.OUT = pid.pwmcyle;
  76. }

  77. else if(out < pid.pwmmin)
  78. {
  79.   pid.OUT = pid.pwmmin ;
  80. }

  81. else pid.OUT = out;

  82. pid.Ek_1 = pid.Ek;  //更新偏差
  83. pid.C10ms=0;
  84. }

复制代码



回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-11 00:05

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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