最近天气比较热,树莓派也挺热的,虽然原来的散热扇平常压到30度,但非常吵,正好手里有一套笔记本的散热模块,就想着硬改一个散热器,于是就有了这个轮子
![图片[1]-树莓派PWM控制散热风扇调速-光影流云](https://www.nouzen.top/wp-content/uploads/2022/07/PXL_20220713_172500591-1024x576.jpg)
物料清单:
- S8050三极管一个
- 杜邦线若干
- 电洛铁及焊接工具
- 电阻一个(根据情况)
软件环境:
Debian arm64
原理
原理之类就不说了,想要了解的可以去看大佬原文
硬件制作
电路图
![图片[2]-树莓派PWM控制散热风扇调速-光影流云](https://www.nouzen.top/wp-content/uploads/2022/07/截图_20220713210653.png)
电路接线
S8050三极管基极(b)串联1K电阻接树莓派GPIO12号引脚(硬件pwm引脚)
风扇正极接树莓派GPIO4号引脚(5V)
风扇负极接三极管集电极(c)
三极管发射极(e)接GPIO6号引脚(地GND)
实物图
![图片[3]-树莓派PWM控制散热风扇调速-光影流云](https://www.nouzen.top/wp-content/uploads/2022/07/PXL_20220713_111842136-576x1024.jpg)
我这张图接上电阻测试一下,后来拆掉了,因为风扇本来声音就基本听不到
驱动代码(此部分转载)
驱动库的选择–wiringpi
由于我只是业余人士,虽然以前学过一点C语言,但已基本忘记了,现在会写一点python,因此风扇驱动代码采用的python来编写。
树莓派常用操作GPIO库有RPI.GPIO,pigpio,wiringpi这三个库,三个库均支持pwm输出控制,其中只有wiringpi支持硬件PWM。三个库的详情网上颇多,此处不表。
RPI.GPIO库使用人群最广,也最通用。
Pigpio库输出PWM波形比RPI.GPIO库更稳定可靠,每次开机需要用sudo pigpio命令开启一个守护进程才能运行。
Wiringpi支持硬件PWM控制,能完美稳定的设置PWM频率至20Khz以上,使风扇运行更平衡,有效解决风扇震动及低高频噪音问题。
关于风扇噪音问题
在使用RPI.GPIO,pigpio库的软件pwm时,经测试在使用pwm低频率时,风扇在低转速时会发出哒哒声或间歇式的嗡嗡声,运行明显不线性,总是一顿一顿的。
在使用pwm高频率时,风扇高速运转会发出类似蜂鸣器啸叫的高频噪音。经过多次尝试后,无论如何调整pwm控制频率噪音问题均无明显改善。
最终找到了此大神的文章,总算拨云见日了。遂学习采用wiringpi的硬件PWM方式控制风扇,至此,完美解决风扇噪音问题。
详见:https://talk.quwj.com/topic/1714
库安装
RPI.GPIO和pigpio库在Raspberry Pi OS中已集成,无需另行安装。
树莓派python安装wiringpi库只需要以下命令即可:
sudo pip3 install wiringpi
Tips:如果不使用sudo而直接使用pip3 install wiringpi安装库wiringpi库,python会出现import找不到模块的错误:importError: No module named ‘wiringpi’。
驱动代码
由于本人水平有限,主要参考了大神们的代码,也改得比较随性,冗余代码较多。
此代码仅适用于NPN型三极管驱动的树莓派风扇。
PNP型三极管驱动的要适当修改,最终代码如下:
#!/usr/bin/python3
# -*- coding: utf-8 -*-
#
# fancontrl.py
#
# 代码修改来源于:https://talk.quwj.com/topic/1714
#
# 使用wiringpi库
import wiringpi as PI
# 风扇控制针脚,编号为:物理12号,BCM18号,wiringpi针脚为1号
PIN_FAN = 1
# 风扇最小转速比例
speed_base = 20
# 最小控制温度,低于它就停转
min_temp = 37
# 最大控制温度,高于它就全速运转
max_temp = 55
# 风扇启动温度
sta_temp = 40
PI.wiringPiSetup()
PI.pinMode(PIN_FAN,PI.PWM_OUTPUT)
#pwm_mode_ms为一个时钟周期内电平为连续高电平和低电平模式。
PI.pwmSetMode(PI.PWM_MODE_MS)
#分频数值,bcm2835的默认晶振频率为19.2mhz,19.2mhz/8=2.4mhz
PI.pwmSetClock(8)
#设置脉冲宽度为100us,即pwm时钟周期为100us,此时对应的pwm输出频率为2.4mhz/100=24khz。
PI.pwmSetRange(100)
#初始化引脚为电平(即停转风扇)
PI.pwmWrite(PIN_FAN,0)
PI.delay(50)
# 获取CPU温度,单位为千分之一度
def get_cpu_temp():
temp_file = open( "/sys/class/thermal/thermal_zone0/temp" )
cpu_temp = temp_file.read()
temp_file.close()
return float(cpu_temp) / 1000
# 获取CPU时钟频率,Mhz
def get_scaling_cur_freq():
temp_file = open( "/sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq" )
scaling_cur_freq = temp_file.read()
temp_file.close()
return int(float(scaling_cur_freq) / 1000)
# 获取CPU最大时钟频率,Mhz
def get_scaling_max_freq():
temp_file = open( "/sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq" )
scaling_max_freq = temp_file.read()
temp_file.close()
return int(float(scaling_max_freq)/ 1000)
scaling_max_freq = get_scaling_max_freq() #调用获取最大频率函数
if __name__ == "__main__":
speed = 0 # pwm驱动的占空比初始化
old_speed = 0 # 设置上一次转速变量
is_work = 0 # 风扇工作状态开关
'''
# 缓慢启动至最大,speed即是占空比
for i in range(speed,10,100):
PI.pwmWrite(PIN_FAN, i)
PI.delay(250)
'''
try:
while True:
current_temp = get_cpu_temp() #获取cpu温度
scaling_cur_freq = get_scaling_cur_freq() #获取CPU频率
if current_temp >= sta_temp:
is_work = 1
if is_work == 1:
# 当前温度小于最小温度,转速为零
if (current_temp <= min_temp):
speed = 0
# 当前温度大于最大温度,转速全开
elif (current_temp > max_temp):
speed = 100
print("full speed!\n",end ='')
else:
# 在低温阈值和高温阈值之间时 根据温度线性使用PWM控制风扇转速
# 转速=基础转速+(当前温度-最小温度/最大温度-最小温度)*(100-基础转速)
speed =speed_base+(current_temp - min_temp) /(max_temp-min_temp) *(100-speed_base)
# 四舍六入取整。
speed = round(speed)
'''
循环线性变换速度 避免急启急停
'''
if (0 < speed <=100):
if (old_speed < speed):
for i in range(old_speed,speed,1):
PI.pwmWrite(PIN_FAN, i)
PI.delay(100)
else:
for i in range(old_speed,speed,-1):
PI.pwmWrite(PIN_FAN, i)
PI.delay(100)
old_speed = speed
is_work =1
print(f"current temp: {current_temp:.2f}\u2103,frequency: {scaling_cur_freq:4}/{scaling_max_freq}Mhz,fan speed: {speed:3}%")
else:
print("fan stop!\n",end ='')
# (speed=0)风扇停转,设置工作状态
if(old_speed <= 100):
i = old_speed
while (i >= speed):
PI.pwmWrite(PIN_FAN, i)
i -=1
PI.delay(100)
old_speed = 0
is_work = 0
else:
PI.delay(5000)
print("Waiting for fan to start!")
# 控制频率延时
PI.delay(3000)
except KeyboardInterrupt:
#风扇停转
PI.pwmWrite(PIN_FAN,0)
print("quit sucess!")
使用supervisor实现开机启动
把上述代码保存为:fan.py
放在/home/pi目录下
supervisor安装
sudo apt-get install supervisor
主配置文件
supervisor主配置文件:
sudo vi /etc/supervisord.conf
添加子配置文件
新建子进程配置文件,路径:
sudo nano /etc/supervisor/conf.d/fan.conf
在子配置文件添加内容如下:
[program:fan]
command = python3 /home/pi/Downloads/fan.py
autostart=true
supervisor管理命令
sudo systemctl restart supervisor //重启服务
sudo supervisorctl status //查看所有进程的状态
sudo supervisorctl stop fan //停止fan
sudo supervisorctl start fan//启动fan
sudo supervisorctl restart fan //重启fan
sudo supervisorctl update //配置文件修改后使用该命令加载新的配置
sudo supervisorctl reload //重新启动配置中的所有程序
原文链接:https://blog.csdn.net/luzze__123/article/details/118641526
暂无评论内容