树莓派4B温度自动控制(PID)
前言:树莓派4B原装风扇按照官方教程安装后,其一直全速运转,非常影响学习的心情。于是引入了PID控制,让风扇转速随着CPU温度的变化自动变化。
关键字
树莓派、PID控制、PWM、温度控制
在翻阅很多资料后发现,大部分控制方法都是采用0(不转)和1(全速)的方式进行控制,此种方式简单但是也会带来更大的突变噪音。参考链接:树莓派4B系列教程四 :CPU智能温度闭环控制
某些博主也引入了PWM(脉冲宽度调制)的概念进行控制,但是风扇转速不能随着温度的变化自动调节。参考链接:树莓派控制PWM风扇
作为控制专业出生,这种bang-bang控制实在不能忍,来个简单的PID控制即可实现风扇转速无级自动调速。具体PID控制相关知识可以参考链接:一文搞懂PID控制算法
思路如下
- 读取当前CPU温度数据
with open('/sys/class/thermal/thermal_zone0/temp') as f:
cpu_temp = int(f.read())
-
采用P调节(试验发现CPU温度波动较大,精度要求不高,不需要引入I和D)对目标温度和当前温度差进行控制
-
输出PWM波控制风扇转速,参考链接:硬件控制入门之树莓派PWM波生成----树莓派硬件控制学习笔记(二)
风扇接线
风扇电源电源正、负极分别接入4、6端口,控制线接入8端口(对应GPIO的14口)
#引用树莓派外置IO库
import RPi.GPIO as GPIO
import time
#风扇GPIO控制通道
FAN_GPIO = 14
#采用速度,单位为秒
SAMPLING = 1
#设定目标温度
SP_TEMP = 60
#PID参数值,只采用P控制
PID_Kp = 0.01
#PID输出控制量,为0~100的占空比,对应0%到100%的转速
PID_OUTPUT = 0
#读取CPU的温度值
def get_cpu_temp():
with open('/sys/class/thermal/thermal_zone0/temp') as f:
cpu_temp = int(f.read())
return cpu_temp
def main():
#设定GPIO的基本参数
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
GPIO.setup(FAN_GPIO,GPIO.OUT)
GPIO.output(FAN_GPIO,GPIO.LOW)
#100Hz PWM
pwm=GPIO.PWM(FAN_GPIO,100)
#默认启动转速为10%
pwm.start(10)
time.sleep(1)
try:
while 1:
temp = get_cpu_temp()
print('CPU Temperature:',temp)
#比例控制算法
PID_OUTPUT = (temp - SP_TEMP*1000)*PID_Kp
print('PID_OUTPUT:',PID_OUTPUT)
#控制器输出限幅
if PID_OUTPUT>100:
PID_OUTPUT = 100
if PID_OUTPUT<0:
PID_OUTPUT = 0
#通过控制PWM的占空比来控制转速
pwm.ChangeDutyCycle(PID_OUTPUT)
time.sleep(SAMPLING)
except KeyboardInterrupt:
pass
GPIO.cleanup()
if __name__=='__main__':
main()
代码运行结果
设定目标温度为60摄氏度,如果温度低于60摄氏度则不运转,高于60则随着温度的升高风扇转速线性增加,CPU温度大于等于70度时,风扇全速运转。
尾巴
PID控制算法是一个神奇的算法,简单可靠,可用于大部分闭环控制系统。
如遇到强非线性系统,可考虑采用模糊控制进行替代。