基于stm32的pid台灯
全桥整流2022/08/12原创 秋名山最速传说 IP:广东
关键词
PID台灯stm32

背景:

之前虎哥发过一篇文章,关于大幅提高室内照明亮度的设想 - 科创 (XXXXXXXXXXXX)。闲来无事测得书房打开台灯桌面的亮度不过300lux,可以说是昏暗了,看起书来费眼睛,遂萌发出自己搞个台灯,提升下桌面的亮度,使其稳定在一个令人舒适的值。


主要用到的材料:

stm32vct6开发板,电源,led灯带,手机懒人支架(夹持led,当做灯臂),铝散热座(废弃主板拆下),散热风扇,一堆导线,stm32开发板,BH1750光照传感器模块,L298N驱动模块,电源转接板等。

 

台灯制作:

led灯带粘到铝散热座上,灯带正负极用导线连好。焊接技术一般般,散热太快了,锡难融化。本来想先粘到塑料膜上焊接完再挪过去的,发现塑料膜会糊掉,只能在散热座上强行焊接了(不知同志们对于这种情况有没有什么好方法?)。最后用手机支架(原计划3d打印个支架的,后来突然想到可以用手机支架做灯臂,够长(30cm-150cm都有),夹得也够稳)把整个灯头夹住。如下图所示(凌乱的线【笑哭】)

1.jpg

3.jpg


L298N驱动模块的接线:

因为驱动电压是24V所以必须使用外部5V供电,否则会烧坏芯片,拔掉跳线帽,5V端口接5V,还要注意要共地,不然可能会出bug

 

BH1750接线:

按照模块上面标识的字符接线就行。SCLPB6SDAPB7ADDRGND

 

PID控制:

在过程控制中,按偏差的比例(P)、积分(I)和微分(D)进行控制的PID控制器(亦称PID调节器)是应用最为广泛的一种自动控制器。它具有原理简单,易于实现,适用面广,控制参数相互独立,参数的选定比较简单等优点;而且在理论上可以证明,对于过程控制的典型对象──“一阶滞后+纯滞后二阶滞后+纯滞后的控制对象,PID控制器是一种最优控制。PID调节规律是连续系统动态品质校正的一种有效方法,它的参数整定方式简便,结构改变灵活(PIPD[1]。总而言之,PID控制算法是一种相对简单易用的控制算法。

pid算法的公式:u(k)=Kp*error +Ki*error +Kd*[error-last_error]

这个公式我们可以转换成下面的几条式子。

pvalue = Kp*error;                //(这里有点奇怪,不知为什么英文字体调不了大小,只能加粗了)
ivalue +=Ki*error;                  //(这个+=很关键,当时我想了一段时间才想出来)
dvalue = (error-last_error)*Kd;
pwmvalue += (int)(Kpvalue+ivalue+dvalue);  //(这里用+=是为了符合实际情况)

error显然就是设定值和当前值之间的差(set_value-now_value)

我们直接以实际例子来解释这三个参数的作用。设定台灯的亮度为1000lux。下面我用我的理解来分别解释参数PID的作用。

参数P也称为比例常数。下图只有参数p起作用(ki=0,kd=0)时的图(如没有特殊说明,下文图表的纵轴代表亮度(单位:lux),横轴代表时间(单位:20ms),没有对ivalue进行限幅):

4.png

kp=0.005时亮度永远也无法到1000lux,这是因为pwmvalue int类型的值,而pvalue 是浮点型的值,当error过小时即pvalue小于1,于取整为0pwmvalue就无法再增大。

所以,我们需要把Kp调大,随着kp的增大,亮度变为1000lux的时间越短,但是,如果kp过大,系统便会震荡。

如下图(kp=5,ki=0,kd=0),可以看出系统刚开始的时候震荡很剧烈。

5.png

当然,台灯如果亮度变化过快,感觉不舒服,我个人觉得kp=0.1时的体验比较好。这里就有个问题了,明明Kp(取0.05-1之间的值)就能很好解决台灯亮度的问题,还要其他两个参数干嘛。其实在我的这个pid台灯里面确实只用Kp就能解决问题了,系统的稳态误差可以忽略不计(影响很小),毕竟亮度提升太快肉眼也不舒服,亮度提升太慢体验也不好,不需要用(可以不用)到ID这两个参数。当初申请基金的时候,还没有开始搞STM32,也没有接触PID,导致存在立项失误,这里要道个歉。

下面我们来看看ivalue += Ki*error;ki也称为积分时间常数。当kp过小(如kp=0.005ki=0,kd=0)时,需要不断积分(ki=0.000001),最终使得对pwmvalue增大,趋于光强为1000luxpwm值。如下图,蓝色线(Kp=0.005,Ki=0.000001,Kd=0)橙色线(Kp=0.005,Ki=0,Kd=0)。

6.png

ivalue会使系统更快达到所需的值,但会使系统震荡。在1000lux附近波动,最终趋于1000luxKi越大,波动越剧烈,最后趋于1000lux(稳定)的时间也越久。如图,ki越大,系统震荡越剧烈,稳定所需的时间越长,蓝线(Kp=0.1,Ki=0.1,Kd=0),橙色线(Kp=0.1,Ki=0.01,Kd=0)。

7.png

我们有两个办法能使系统震荡减弱,一个是积分限幅,另一个是微分抑制。我们先来说说积分限幅,如下图中橙色线(Kp=0.1,Ki=0.1,Kd=0)震荡很剧烈,在系统开始运行时,ivalue不断变大使得曲线十分陡峭,到达了设定值之后,由于ivalue是累加的,没有办法立刻等于0,所以pwmvalue仍然在不断增加,如下图,增加到1700lux附近才下降,然后就反复震荡,最终趋于设定值下图。我们可以对ivalue进行限幅,让ivalue只能在一个固定的范围内变动,如下图蓝线(Kp=0.1,Ki=0.1,Kd=0,ivalue限幅±100)。

限幅代码:

#define imax   100              //限幅
#define imin  -100               //限幅
if(ivalue>imax) ivalue=imax;     //如果ivalue>imax,使ivalue=imax   
if(ivalue<imin) ivalue=imin;      //如果ivalue<imin,使ivalue=imin

在对ivalue限幅之后,系统震荡明显减弱,如下图蓝线。

8.png

Kd是时间微分常数,用于减缓pwmvalue的增速(阻尼),当亮度不断增加趋于设定亮度时,errort-1>error(t)dvalue = (error-last_error)*Kd,式子中括号里面的项就是负值,乘上Kd微分时间常数,得到dvaluedvalue能使pwmvalue的变化更平缓。如下图橙色线(kp=0.1,ki=0.1,kd=0)蓝色线(kp=0.1,ki=0.1,kd=1

9.png

但是,当pwmvalue的增速很快(亮度不断增加并趋于设定亮度)时,|error-last_error|会很大导致|dvalue|也很大,如果Kd也偏大,显然在系统刚开始运行时,会震荡(pvalue+ivalue+dvalue<0,使得pwmvalue值变小,以至于亮度突然上升后突然下降,对外表现为闪烁,顿挫感,亮度变化不缓和),如下图(kp=0.1,ki=0,kd=4)。

10.png

最后我们应该把这个pid运算放在程序的中断里面(固定周期执行一次就行),假如放在while循环,pwmvalue 的值增速极快(每while一次,只要暂时没有读取到新的光照强度的新值(20ms读取一次)pvaluedvalue 不变,ivalue快速增大(或许可以通过调小Kp,Ki,Kd(实测不太行,要调的很小,很难调节)来解决这个问题,毕竟while循环也算是一个周期)导致pwmvalue快速增加,最后导致系统震荡)

 

蓝牙控制:

使用CH-08蓝牙模块,手机连接上蓝牙模块,发送所需的亮度就能自动调节,不需要每次调整亮度都要重新烧录。也可以做到无线开灯,无线关灯的效果。

  11.png


整个pid调光台灯的全貌如下图:

12.png


程序:

attachment icon 基于stm32的pid台灯.zip 4.58MB ZIP 13次下载


结语:

感谢kc基金的支持,感谢kc论坛。在制作这个台灯的时候,遇到了不少困难,感谢同志们提出的建议,不过我觉得这个项目并没有真正完成(或许这个帖子还存在一些技术性的问题),还能加入更多的功能。希望这个帖子能给后面的同志们一点帮助。今后我还会继续完善这个项目,如果有问题和建议欢迎在下面留言。

[1] 刘教瑜,舒军主编;甘月红,谢长君副主编.单片机原理及应用(第2版):武汉理工大学出版社,2014.08


[修改于 3个月9天前 - 2024/09/14 09:34:03]

来自:电子信息 / 电子技术动手实践:实验报导
6
 
6
已屏蔽 原因:{{ notice.reason }}已屏蔽
{{notice.noticeContent}}
~~空空如也
qwe
2年4个月前 IP:内蒙古
906784

pwm调光伤眼,都自己做了,何不做纯直流?

引用
评论(1)
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
虎哥
2年4个月前 IP:四川
906785
引用qwe发表于1楼的内容
pwm调光伤眼,都自己做了,何不做纯直流?

您所说的PWM调光伤眼,可有证据支持?

引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
古法造轮
2年4个月前 IP:福建
906787

请教个有点儿低级的问题,没太看明白。。。。这里用 PID 来调光主要目的是啥?PID 相比于直接按设定光强和实测光强的差值做个线性或非线性的单调调光有啥特别的优点么?

引用
评论(5)
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
BG5JFV
2年4个月前 IP:江西
906796

楼主可以用加热台(或者酒精灯)来预热铝基板,注意控制好温度,这样会好焊些。

jlc可以免费打样铝基板PCB,可以试试。这样焊线,看着就累,也比较丑。还有,松香要用洗板水洗掉。

电路里面地的相互连接问题好好注意,我现在是被这个教训乖了,以前在这上面栽好几次。

华为台灯也有亮度反馈控制,哪天拆开看看(不过怕被打)。

引用
评论(2)
1
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
谁叫小明
2年4个月前 IP:广东
906799
引用古法造轮发表于3楼的内容
请教个有点儿低级的问题,没太看明白。。。。这里用 PID 来调光主要目的是啥?PID 相比于直接按设...

在实际应用中使用设定光强和实测光强的差值做个非线性调光确实是个直接的开环控制方式,但在为了学习PID为驱使的项目中这确实是个很好的项目,两者最直接的就是开环控制和闭环控制的区别,至于评论区说到扫描的方式在该项目的实际应用中完全是一个很方便的控制方法,但使用PID的控制可以在控制过程中达到快速收敛作用,也比扫描方式会更高级

引用
评论
2
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
谁叫小明
2年4个月前 IP:广东
906800

像调光这样的项目因为不像无人机那样有重力的作用与kp*err抵消导致的无法收敛现象,所以在这个项目中的ki实际上起到的作用更多是配合err引起负面影响更多,所以会有ki越大震荡越大的现象,不是说所有项目都适合套用pid的算法,更重要的是考虑现实的物理模型去分析,个人见解是这个案例中使用pd算法是更为合适的.

引用
评论(2)
5
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论

想参与大家的讨论?现在就 登录 或者 注册

所属专业
所属分类
上级专业
同级专业
全桥整流
进士 学者 机友 笔友
文章
27
回复
283
学术分
1
2020/01/26注册,16分29秒前活动

秋名山最速传说!

主体类型:个人
所属领域:无
认证方式:身份证号
IP归属地:广东
插入公式
评论控制
加载中...
文号:{{pid}}
投诉或举报
加载中...
{{tip}}
请选择违规类型:
{{reason.type}}

空空如也

加载中...
详情
详情
推送到专栏从专栏移除
设为匿名取消匿名
查看作者
回复
只看作者
加入收藏取消收藏
收藏
取消收藏
折叠回复
置顶取消置顶
评学术分
鼓励
设为精选取消精选
管理提醒
编辑
通过审核
评论控制
退修或删除
历史版本
违规记录
投诉或举报
加入黑名单移除黑名单
查看IP
{{format('YYYY/MM/DD HH:mm:ss', toc)}}