找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2460|回复: 0
收起左侧

基于stm32mini版的PID液位控制器设计 附源程序

[复制链接]
ID:649697 发表于 2021-7-5 18:33 | 显示全部楼层 |阅读模式
这是学完微型计算机控制要求制作的一个实验,由几个供学习用的STM32例程拼接而成,能实现简单的液位控制,不足的地方很多,参数也还要根据自身情况调整,第一次发帖,大佬看到多指教。
首先简单介绍一下用到的硬件:
液位传感器:

液位传感器

液位传感器


  • 工作电压:2.0V-5.0V
  • 输出类型        :模拟量输出
  • 检测深度:48mm
  • 产品尺寸:19.0mm*63.0mm
  • 固定孔尺寸:2.0mm
  • 原理:该模块主要是利用三极管的电流放大原理,当液位高度使三极管的基极与电源正极导通的时候,在三极管的基极和发射极之间就会产生一定大小的电流,此时在三极管的集电极和发射极之间就会产生一个一定放大倍数的电流,该电流经过发射极的电阻产生电压供AD转换器采集。 原理:该模块主要是利用三极管的电流放大原理,当液位高度使三极管的基极与电源正极导通的时候,在三极管的基极和发射极之间就会产生一定大小的电流,此时在三极管的集电极和发射极之间就会产生一个一定放大倍数的电流,该电流经过发射极的电阻产生电压供AD转换器采集。

[backcolor=rgb(54, 165, 232) !important]接口说明
引脚号标识描述
1AOUT模拟量输出
2GND电源地
3VCC电源正(3.3V-5.0V)


I2%YR68A2`BCY_O8MU7@@GS.png
资料官网:www点waveshare点net/wiki/Liquid_Level_Sensor

官网自带的传感器插入水深和输出电压的关系本人并没有验证过,输出的电压和采样值的转换关系是可以自己写的,这里做了简单的深度和采样值转换,不过后面感觉作用不大,实验只要求能控制在不同水位即可,即改变一下采样值。想要准确的控制在某一个高度,确定一下该高度和采样值的对应关系就行!

大致如下:
float trans(float a)
{
        float b=a,c=0;
        if(b<=0.5)
                c=b*(1450.0/0.5);
        if(b>0.5&&b<=1)
                c=(b-0.5)*((1700.0-1450)/0.5)+1450.0;
        if(b>1&&b<=1.5)
                c=(b-1.0)*((2000.0-1700)/0.5)+1700.0;
        if(b>1.5&&b<=2.0)
                c=(b-1.5)*((2150.0-2000.0)/0.5)+2000.0;
        if(b>2.0&&b<=2.5)
                c=(b-2.0)*((2240.0-2150.0)/2.5)+2150.0;
        if(b>2.5&&b<=3.0)
                c=(b-2.5)*((2310.0-2240.0)/3.0)+2240.0;
        if(b>3.0&&b<=3.5)
                c=(b-3.0)*((2360.0-2310)/0.5)+2310;
        if(b>3.5&&b<=4.0)
                c=(b-3.5)*((2420.0-2360.0)/0.5)+2360.0;
        if(b>4.0&&b<=5)
                c=(b-4.0)*((2500.0-2420.0)/1.0)+2420.0;
        
        LCD_ShowxNum(156,150,b*10,4,16,0);//显示一下目标深度,单位毫米
        
        return c;
        
}
本来想输入深度然后到达目标深度的,但是发现采样波动大,效果不是很好,这就是一个简单的分段线性转换,测的分段越多越准


传感器官网中有教学,利用正点原子的ADC实验例程也能够查看采样值和转换电压值,这为了方便直接移植,没有改变它的采样端口,用的还是PA1作为模拟输入端口,电源接STM32的3V电源,

驱动模块是L298N,简单的资料如下,知道基本的驱动方法就能用,想知道更详细的网上资料很容易找给多一张原理图:
C[I@F[G]@MST[[%UG78)RL0.png
实物如下:

管脚作用图

管脚作用图
模块参数

1.驱动芯片:L298N双H桥直流电机驱动芯片

2.驱动部分端子供电范围Vs:+5V~+35V ; 如需要板内取电,则供电范围Vs:+7V~+35V

3.驱动部分峰值电流Io:2A

4.逻辑部分端子供电范围Vss:+5V~+7V(可板内取电+5V)

5.逻辑部分工作电流范围:0~36mA

6.控制信号输入电压范围:
   低电平:-0.3V≤Vin≤1.5V
   高电平:2.3V≤Vin≤Vss
7.使能信号输入电压范围:

   低电平:-0.3≤Vin≤1.5V(控制信号无效)
   高电平:2.3V≤Vin≤Vss(控制信号有效)
8.最大功耗:20W(温度T=75℃时)

输入逻辑图如下:
OINAQY$N_DRF%G~Z$KTPFVR.png

抽水泵用到的是输出A,由使能端口A控制,其正反转由旁边的两个输出的IN1和IN2电平高低决定,具体关系看表,要用到输出B的话,原理类似

驱动电源用的是STM32模块上的5V电源,一开始接的5V供电接口,但是电机最高速度有点慢,后面接到了12供电接口,马上就猛起来了,真是让人摸不着头脑
使能端口即PWM输出控制速度由pin8控制,电机的启动则由pin11和pin12控制,想换的改一改就行

说一说这个PID的吧,经常用到的控制方法之一,大部分代码都是用现成的,所以整个实验做下来要写的也就一个PID和梯度线性转换
PID控制又称偏差控制,当实际值与目标值有差异时,偏差控制就起作用,这里是使用增量型PID算法,由位置型推导而出
PID的分别基本含义找到一个比较好的解释:

P - 比例部分

比例环节的作用是对偏差瞬间作出反应。偏差一旦产生控制器立即产生控制作用, 使控制量向减少偏差的方向变化。 控制作用的强弱取决于比例系数Kp, 比例系数Kp越大,控制作用越强, 则过渡过程越快, 控制过程的静态偏差也就越小; 但是Kp越大,也越容易产生振荡, 破坏系统的稳定性。 故而, 比例系数Kp选择必须恰当, 才能过渡时间少, 静差小而又稳定的效果。

I  - 积分部分

从积分部分的数学表达式可以知道, 只要存在偏差, 则它的控制作用就不断的增加; 只有在偏差e(t)=0时, 它的积分才能是一个常数,控制作用才是一个不会增加的常数。 可见,积分部分可以消除系统的偏差。

积分环节的调节作用虽然会消除静态误差,但也会降低系统的响应速度,增加系统的超调量。积分常数Ti越大,积分的积累作用越弱,这时系统在过渡时不会产生振荡; 但是增大积分常数Ti会减慢静态误差的消除过程,消除偏差所需的时间也较长, 但可以减少超调量,提高系统的稳定性。

当 Ti 较小时, 则积分的作用较强,这时系统过渡时间中有可能产生振荡,不过消除偏差所需的时间较短。所以必须根据实际控制的具体要求来确定Ti

D - 微分部分

实际的控制系统除了希望消除静态误差外,还要求加快调节过程。在偏差出现的瞬间,或在偏差变化的瞬间, 不但要对偏差量做出立即响应(比例环节的作用), 而且要根据偏差的变化趋势预先给出适当的纠正。为了实现这一作用,可在 PI 控制器的基础上加入微分环节,形成 PID 控制器。

微分环节的作用使阻止偏差的变化。它是根据偏差的变化趋势(变化速度)进行控制。偏差变化的越快,微分控制器的输出就越大,并能在偏差值变大之前进行修正。微分作用的引入, 将有助于减小超调量, 克服振荡, 使系统趋于稳定, 特别对髙阶系统非常有利, 它加快了系统的跟踪速度。但微分的作用对输入信号的噪声很敏感,对那些噪声较大的系统一般不用微分, 或在微分起作用之前先对输入信号进行滤波。


这里利用  目标值-采样值  得出一个反作用误差
增量利用这个误差进行计算
                                           增量型.png
把增量叠加到速度控制的PWM输出值上

代码如下:
   void PIDcontrol(float a)
{
        float p=13;  
  float i=2;   
  float d=1;
  float adduk=0;
        float expvalue=trans(a);    //设置水深和采样值的转化

        e=expvalue-Adcvalue;      //偏差计算
        adduk=p*(e-e1)+i*e+d*(e-2*e1+e2);   //增量计算
        e2=e1;                            //刷新一下
        e1=e;

        vt+=adduk;                   //更新转速
        if(vt>900) vt=900;         //防止越出
        if(vt<0)   vt=0;


        TIM_SetCompare1(TIM1,900-vt);

        LCD_ShowxNum(156,70,Adcvalue,4,16,0);//显示采样值
        LCD_ShowxNum(156,90,expvalue,4,16,0);//显示目标值

        LCD_ShowxNum(156,170,vt,4,16,0);//显示转速情况

        LCD_ShowxNum(156,190,e,4,16,0);//误差显示


}
在PWM输出中,分频是7200,但是经过测试到了3千多电机就停止转动了(pwm设置原因,数值越高越慢,这就是为什么要900-vt控制转速 ),之所以设置最低900,是因为电机停止转动后出水太快液位降得太快导致液面波动剧烈,调这个数值可以令最低速时液面下降慢点,视具体情况而定,
归根结底算法细节没处理好,比较粗糙,可以考虑PID放进定时器中、增加按键控制目标数值等,反复下载麻烦



这是开始时的一张图片,目标水位是没过传感器13毫米,转换成采样值是1880,现在误差是1880,转速达到最快900,写的时候实物不在手上。对应最后稳定阶段没了,装水的也没拍,这样另外一张的稳定状态
实物1.png


这个是一个达到稳定的,10毫米对应采样值1700,此时ADC采样是1720,误差因为延迟没显示出来,但是超过目标值电机转速达到最慢0
实物2.png

想把手册也上传上来,结果超过20M,看来需要的自行下载吧
链接:https://pan.baidu.com/s/1O5qqnvEDdLQAIcO_-Yh3GA             提取码:pk1x
关于STM32mini的更多资料例程等:www点openedv点com/docs/boards/stm32/zdyz_stm32f103_mini.html

写着玩意原来还有些麻烦,和写文档似的= =,唉,看来自己着实没耐心,感谢哪些写出长篇大论的大佬给我带来过的帮助,自己写的乱糟糟的

程序可从51hei下载附件: ADC实验.7z (229.12 KB, 下载次数: 39)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

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

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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