OpenEdv-开源电子网

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

带电位器的直流电机控制位置

[复制链接]

5

主题

30

帖子

0

精华

初级会员

Rank: 2

积分
106
金钱
106
注册时间
2018-3-15
在线时间
54 小时
发表于 2018-9-3 17:26:16 | 显示全部楼层 |阅读模式
现有一个带电位器的电机,将采集到的AD值经过PID计算后更新PWM,想要实现精准控制位置(转过的角度),但是调试时一直正反来回转,不像PID控制电机转速那样可以监测到收敛的速度曲线,而是一直震荡的AD值曲线,调了很久PID都不行。请问下大家是怎么调试的,求助,为谢!
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

109

主题

5564

帖子

0

精华

资深版主

Rank: 8Rank: 8

积分
10572
金钱
10572
注册时间
2017-2-18
在线时间
1914 小时
发表于 2018-9-3 22:32:21 | 显示全部楼层
回复 支持 反对

使用道具 举报

3

主题

1907

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4106
金钱
4106
注册时间
2018-8-14
在线时间
696 小时
发表于 2018-9-3 23:19:13 | 显示全部楼层
把你处理PID的那段代码贴出来吧
回复 支持 反对

使用道具 举报

5

主题

30

帖子

0

精华

初级会员

Rank: 2

积分
106
金钱
106
注册时间
2018-3-15
在线时间
54 小时
 楼主| 发表于 2018-9-4 09:55:23 | 显示全部楼层
//PID3初始化参数       
        pid3.errorSumDownLim = -200;                //偏差和下限
        pid3.errorSumUpLim = 200;                        //偏差和上限
        pid3.PIDoutDownLim = -80;                        //PID输出下限(即PWM占空比)
        pid3.PIDoutUpLim = 80;                                //PID输出上限
        pid3.errorUpLim = 200;                                //偏差上限
        pid3.errorDownLim = -200;                        //偏差下限
        pid3.delErrorUpLim = 300;                        //偏差之差上限
        pid3.delErrorDownLim = -300;                        //偏差之差下限
       
        pid3.TargetVal=2000;       
       
        pid3.kp=0.2;                                                        //先开始调P参数,所以将Ki  Kd都置0了
        pid3.ki=0;
        pid3.kd=0;       

void PID3_Calc(void)
{
        pid3.error = pid3.TargetVal - pid3.NowVal;                        //偏差 = 设定 - 当前       
       
        if(pid3.error > pid3.errorUpLim)                                        //误差限幅
                pid3.error = pid3.errorUpLim;
        else if(pid3.error < pid3.errorDownLim)
                pid3.error = pid3.errorDownLim;
       
        pid3.errorSum += pid3.error;                                                //偏差求和
       
        if(pid3.errorSum > pid3.errorSumUpLim)                        //偏差和限幅
                pid3.errorSum = pid3.errorSumUpLim;
        else if(pid3.errorSum < pid3.errorSumDownLim)
                pid3.errorSum = pid3.errorSumDownLim;
       
        pid3.delError = pid3.error - pid3.error1;                        //偏差微分
        pid3.error1 = pid3.error;                                                       
       
        if(pid3.delError > pid3.delErrorUpLim)                                //偏差微分限幅
                pid3.delError = pid3.delErrorUpLim;
        else if(pid3.delError < pid3.delErrorDownLim)
                pid3.delError = pid3.delErrorDownLim;
       
        pid3.Pout = pid3.kp * pid3.error;                                        //比例输出
        pid3.Iout = pid3.ki * pid3.errorSum;                                //积分输出
        pid3.Dout = pid3.kd * pid3.delError;                                //微分输出
       
        pid3.PIDout = pid3.Pout + pid3.Iout+ pid3.Dout;        // PID输出
       
        if(pid3.PIDout > pid3.PIDoutUpLim)                                //PID输出限幅
                pid3.PIDout = pid3.PIDoutUpLim;
        else if(pid3.PIDout < pid3.PIDoutDownLim)
                pid3.PIDout = pid3.PIDoutDownLim;

}

在MAIN()函数中
                if(pid3_flag==1)                                                                //PID控制标志位 ,每0.1S进定时器中断将pid3_flag置1
                {
                                ADCVAL=Get_Adc_Average(ADC_Channel_1,5);
                                pid3.NowVal=ADCVAL;       
                                PID3_Calc();
                                PwmValue3=pid3.PIDout;                                                       
                       
                                pid3_flag=0;
                }
回复 支持 反对

使用道具 举报

5

主题

30

帖子

0

精华

初级会员

Rank: 2

积分
106
金钱
106
注册时间
2018-3-15
在线时间
54 小时
 楼主| 发表于 2018-9-4 09:57:13 | 显示全部楼层
StayHungry123 发表于 2018-9-4 09:55
//PID3初始化参数       
        pid3.errorSumDownLim = -200;                //偏差和下限
        pid3.errorSumUpLim = 200;                        //偏差 ...

AD采样值很准确,电机带动电位器转一圈串口打印出的AD值是均匀的0~4096
回复 支持 反对

使用道具 举报

5

主题

30

帖子

0

精华

初级会员

Rank: 2

积分
106
金钱
106
注册时间
2018-3-15
在线时间
54 小时
 楼主| 发表于 2018-9-4 09:57:43 | 显示全部楼层
edmund1234 发表于 2018-9-3 23:19
把你处理PID的那段代码贴出来吧

贴出来了
回复 支持 反对

使用道具 举报

3

主题

1907

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4106
金钱
4106
注册时间
2018-8-14
在线时间
696 小时
发表于 2018-9-4 10:19:07 | 显示全部楼层
本帖最后由 edmund1234 于 2018-9-4 10:43 编辑

pid3.kp=0.2; 还是太大, 把它调小至输出不会上下摆动为止
你的PWM设置的时钟及ARR值是多少?
回复 支持 反对

使用道具 举报

3

主题

1907

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4106
金钱
4106
注册时间
2018-8-14
在线时间
696 小时
发表于 2018-9-4 10:43:35 | 显示全部楼层
本帖最后由 edmund1234 于 2018-9-4 11:37 编辑

pid3.kp, 是这样调的
    一) 让糸统处于开环状态, 设PID的值让输出为电机最高速度的一半, 记录PID的输出值为V1, 记录偏差值为E1
    二) 设PID的输出为电机最高速度的一半+10%, 记录PID的输出值为V2, 记录偏差值为E2
   
    因而得出开环增益为G =(V2-V1)/(E2-E1)
    而pid3.kp 需要比 1/G小
    你可以先从pid3.kp = 0.8/G 开始调

  当pid3.kp 接近 或 >= 1/G 的时候, 糸统就会象你描述的现象, 上下摆动

I & D 就靠你自己了, 提示是 pid3.ki >> pid3.kp
回复 支持 反对

使用道具 举报

3

主题

1907

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4106
金钱
4106
注册时间
2018-8-14
在线时间
696 小时
发表于 2018-9-4 12:45:53 | 显示全部楼层
如果你的答案是调不到最大输出的一半+10%, 要不就是+8%, 要不就+12%, 那就是你的PWM解析度不够, 之所以我之前问你PWM的时钟及ARR的值的原因
回复 支持 反对

使用道具 举报

5

主题

30

帖子

0

精华

初级会员

Rank: 2

积分
106
金钱
106
注册时间
2018-3-15
在线时间
54 小时
 楼主| 发表于 2018-9-5 16:12:39 | 显示全部楼层
edmund1234 发表于 2018-9-4 12:45
如果你的答案是调不到最大输出的一半+10%, 要不就是+8%, 要不就+12%, 那就是你的PWM解析度不够, 之所以我 ...

感谢提供思路,谢谢。
回复 支持 反对

使用道具 举报

2

主题

23

帖子

0

精华

初级会员

Rank: 2

积分
145
金钱
145
注册时间
2017-12-4
在线时间
56 小时
发表于 2019-6-4 08:24:16 | 显示全部楼层
楼主这个问题解决了吗?我也买了一个带电机的电位器,也是控制位置不准确,可以教一下怎么做吗?
回复 支持 反对

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-6-26 06:23

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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