PCB树莓派嘉立创用刚学的 PCB 知识做一个优雅的树莓派风扇控制板
千里之豪
首先我不是EE(电子电路工程师),所以对电路一窍不通,但人就是这样,越菜越爱玩。所以如果你是EE的话,不要被我的电路图蠢到(不要骂我)。
我的家里就好几个树莓派,一些是我大学的时候做小任务的低功耗服务器用,另外一些是工作的时候,自己测试一些硬件用,跑一些边缘服务之类的。
树莓派旧风扇长期通电运行报废
我大学期间给树莓派 3B 配备的风扇在通电时间超过三年之后还是在最近寿终正寝了(作为一个4块钱的风扇而言,已经很抗造了),于是我就在想,为什么不做一个根据 CPU 温度动态控制风扇转速的模块,来延长风扇的寿命呢?说干就干。
众所周知,树莓派最新的 5B 系列已经有了成熟的风扇控制接口了。

图片来自:树莓派官网
网络上风扇开关电路简单明确,但不够优雅简洁
但我手里的好几个 3B 和 4B 这两个系列都没有呀,我也想要一个更加优雅的、模块化的接口,而不是临时的像这种:
基础原理图,来自 shumeipai.nxez.com


图片来自:CSDN 用户 luzze_123

图片来自:CSDN 用户 qq_40251961
PCB 速成,嘉立创启动!
但我不会画电路板,更不了解各种电子电路相关的知识,只好去折磨 AI 了 😄。
但其实每个人都是有一定的电路基础的,正负极、开关。所以我选择了更加速成的方式:
【保姆级】二十分钟零基础PCB绘制打样一条龙教程(立创EDA专业版)
只需要按照这个视频教程,你就可以在半小时左右学会最基础的 PCB 板的绘制技巧,我也是顺利地完成了第一版绘制
第一版电路图



如果你是比较懂电路的话,你肯定已经看到问题所在了,没错,我把三极管放在了 5V 正极了,导致板子到手后风扇的转速非常慢,有时候甚至转不起来,即使已经通过 GPIO 把电路导通了,风扇还是不转或者转的非常慢,我就不瞎分析了,放出 AI 的分析:
把 8050 放在正极(高侧)当“开关”用了 —— 8050 是 NPN 晶体管,做高侧开关时它会工作在发射跟随(emitter-follower)模式,发射极电压 ≈ 基极电压 − 0.7V。GPIO 给的是 3.3V,发射极最多 ~2.6V,风扇的电源是 5V → 风扇只拿到 ~2.6V,自然转得很慢。
我理解下来就是:三极管放正极会对电压电流有较大损耗,导致风扇工作所需功率不足。
第二版电路图
于是重新去嘉立创领券,重新打板,重新焊接电路,重新测试,可以了!!!

再配合 Python 脚本,和亿点点配置,一个全自动的风扇控制模块就做好了!

安装效果图
模块大小示意(对比 Type-C 接口)

总花销:
然而这一趟折腾下来,我发现花销已经足够我买好多小风扇了,好在电烙铁可以反复使用,电子元器件也只消耗了一小部份,以后折腾其他东西也能用~
解除 GPIO 14 的串口占用,用来当做开关信号
当前这个模块占地较小,但也有代价,它使用的是GPIO 14进行电路开关控制,GPIO 14 在树莓派上原本是被串口通信功能占用,如果你跟我一样不使用串口功能,可以这样关闭掉:
sudo raspi-config
Interface Options → Serial Port
完成后退出并选择 Finish,允许它重启。
重启后:
sudo vim /boot/firmware/config.txt
确认或添加以下内容(顺序重要):
1 2 3 4 5
| dtoverlay=disable-bt
enable_uart=0
|
1
| sudo systemctl disable hciuart.service
|
1
| sudo systemctl mask hciuart.service
|
验证 GPIO 14 状态:
pinctrl get 14
应显示:
1
| GPIO 14: level=0 func=INPUT
|
(或类似 function INPUT),没有出现 ALT0 / TXD0 / RXD0。
此时即可用作普通 GPIO。
如果你需要串口功能,则可以使用另一种方案代替
这是另一个版本,它不占用串口功能,使用 GPIO 4 进行开关控制,最终组件也会相对应长一些




风扇控制脚本
Python 脚本:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78
| import RPi.GPIO as GPIO import time import signal import sys
FAN_GPIO = 14
HIGH_TEMP = 45.0 LOW_TEMP = 42.0
CHECK_INTERVAL = 5
GPIO.setmode(GPIO.BCM) GPIO.setup(FAN_GPIO, GPIO.OUT)
GPIO.output(FAN_GPIO, GPIO.HIGH) fan_status = False
def get_cpu_temperature(): try: with open('/sys/class/thermal/thermal_zone0/temp', 'r') as f: temp = float(f.read()) / 1000.0 return temp except Exception as e: print(f"无法读取CPU温度: {e}") return None
def control_fan(temperature): global fan_status
if temperature >= HIGH_TEMP and not fan_status: GPIO.output(FAN_GPIO, GPIO.HIGH) fan_status = True print(f"温度: {temperature}°C - 风扇开启") elif temperature <= LOW_TEMP and fan_status: GPIO.output(FAN_GPIO, GPIO.LOW) fan_status = False print(f"温度: {temperature}°C - 风扇关闭") else: status = "开启" if fan_status else "关闭" print(f"温度: {temperature}°C - 风扇保持{status}")
def signal_handler(sig, frame): print("\n正在关闭程序...") GPIO.output(FAN_GPIO, GPIO.LOW) GPIO.cleanup() print("风扇已关闭,程序退出") sys.exit(0)
signal.signal(signal.SIGINT, signal_handler) signal.signal(signal.SIGTERM, signal_handler)
print("开始监控CPU温度并控制风扇...") print(f"温度阈值: 高于{HIGH_TEMP}°C开启, 低于{LOW_TEMP}°C关闭") print("按 Ctrl+C 退出程序")
try: while True: temperature = get_cpu_temperature() if temperature is not None: control_fan(temperature) time.sleep(CHECK_INTERVAL) except KeyboardInterrupt: signal_handler(None, None) except Exception as e: print(f"程序运行出错: {e}") GPIO.output(FAN_GPIO, GPIO.LOW) GPIO.cleanup()
|
Python
自动化服务配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| [Unit]
Description=Fan control Service
After=network.target
[Service]
Type=simple
WorkingDirectory=
ExecStart=/usr/bin/python3
Restart=always
RestartSec=10
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=fan-control
Environment=PYTHONUNBUFFERED=1
[Install]
WantedBy=multi-user.target
|
Makefile
把上边这个脚本保存到
/etc/systemd/system/fan-control.service
然后依次执行:
重新加载服务文件
sudo systemctl daemon-reload
启动风扇控制脚本服务
sudo systemctl start fan-control.service
检查运行状态
sudo systemctl status fan-control.service
设置服务开机自启动
sudo systemctl enable fan-control.service
如果发现服务启动异常,可以通过这个命令来查看异常原因
sudo journalctl -u fan-control.service -n 50
效果
1 2 3 4 5 6 7 8 9 10 11 12
| Oct 16 13:23:42 raspberrypi fan-control[2004]: 温度: 44.008°C - 风扇保持关闭 Oct 16 13:23:47 raspberrypi fan-control[2004]: 温度: 44.546°C - 风扇保持关闭 Oct 16 13:23:52 raspberrypi fan-control[2004]: 温度: 45.084°C - 风扇开启 Oct 16 13:23:57 raspberrypi fan-control[2004]: 温度: 45.084°C - 风扇保持开启 Oct 16 13:24:02 raspberrypi fan-control[2004]: 温度: 44.008°C - 风扇保持开启 Oct 16 13:24:07 raspberrypi fan-control[2004]: 温度: 43.47°C - 风扇保持开启 Oct 16 13:24:12 raspberrypi fan-control[2004]: 温度: 43.47°C - 风扇保持开启 Oct 16 13:24:17 raspberrypi fan-control[2004]: 温度: 42.932°C - 风扇保持开启 Oct 16 13:24:22 raspberrypi fan-control[2004]: 温度: 41.856°C - 风扇关闭 Oct 16 13:24:27 raspberrypi fan-control[2004]: 温度: 41.856°C - 风扇保持关闭 Oct 16 13:24:32 raspberrypi fan-control[2004]: 温度: 41.856°C - 风扇保持关闭 Oct 16 13:24:37 raspberrypi fan-control[2004]: 温度: 41.318°C - 风扇保持关闭
|
备注