树莓派实现自动控制风扇散热

折腾了一段时间树莓派3B+。后来发现一个问题,那就是树莓派上面的散热小风扇,只要一通电,就开始转起来了,不管你开没开机。这是真的坑啊,我不想它一直转啊,就不说费不费电了,安静时风扇一直嗡嗡嗡的转,听着就烦躁。我就想弄一个东西控制一下,超过设定温度就开风扇,低于设定温度就停止。

硬件准备

硬件方面,需要如下几样东西:

首先,你需要有几根杜邦线(主要是杜邦线上的插头,需要三个),如下图所示

一个pnp类型的三极管,我用的型号是ss8550

散热小风扇,这个必须要有哈

两根导线,经过实验,杜邦线不沾焊锡,鬼知道是什么材质啊,所以必须要另外准备导线

软件准备

我们需要在树莓派上安装一个软件 wiringPi,因为我们需要用这个软件来控制树莓派的引脚信号,这个软件有好几种安装方法,我就说一下我用的方法。

首先进这个网站:https://git.drogon.net/?p=wiringPi;a=summary

进去后点击 snapshot 按钮下载 wiringPi ,下载最新的一个就行了。

需要注意的是,因为一些大家都懂的原因,你可能没法下载,你需要进行魔法上网,或者用 Git 来进行安装,具体教程自行百度。

下载完成后,得到 wiringPi-36fb7f1.tar.gz 压缩包(注意,压缩包的 36fb7f1 是版本号,你下载时可能已经不是这个版本了,下载最新的就行,这个不用管),将压缩包上传到树莓派中,我放在了 /home/pi 目录。然后将压缩包解压

1
pi@fyypll:~ $ tar -zxvf wiringPi-36fb7f1.tar.gz

解压后得到 wiringPi-36fb7f1 文件夹,进入这个文件夹,进行编译安装

1
2
pi@fyypll:~ $ cd wiringPi-36fb7f1
pi@fyypll:~ $ ./build

几秒钟后 wiringPi 将会自动安装完毕,输入 sudo gpio -v 命令测试一下。

1
2
3
4
5
6
7
8
9
10
11
pi@fyypll:~ $ sudo gpio -v
gpio version: 2.50
Copyright (c) 2012-2018 Gordon Henderson
This is free software with ABSOLUTELY NO WARRANTY.
For details type: gpio -warranty

Raspberry Pi Details:
Type: Pi 3B+, Revision: 03, Memory: 1024MB, Maker: Sony
* Device tree is enabled.
*--> Raspberry Pi 3 Model B Plus Rev 1.3
* This Raspberry Pi supports user-level GPIO access.

若输出以上类似信息,证明软件安装成功。

焊接风扇

三极管平的一面对着自己,三个脚从左到右分别为E(发射极)、B(基极)、C(集电极)。

将准备的两根导线分别焊在发射极和基极,将小风扇负极(黑线)焊在集电极。然后将从杜邦线上拆下来的三个插头分别安装在连接发射极的导线、连接基极的导线、小风扇正极(红线)。至此,小风扇焊接完成了。

风扇安装

经过焊接改装的小风扇将会有三个插头,应该如何安装?

我们首先需要确定引脚位置,将树莓派有网线接口的那面朝下,然后引脚的那面对着自己,从左往右数,引脚编号分别为:

1
2
3
4
5
1	2
3 4
5 6
7 8
.....

我们需要将风扇的红线(正极)插在4号脚,发射极插在6号脚,基极插在8号脚,如下图所示。

至此,风扇的安装也完成了。

wiringPi引脚编码

上面我们说方法判断的是物理引脚编号,在 wiringPi 中引脚编码可是不一样的了。我们可以通过命令查看物理引脚编码和wiringPi编码的对应关系:

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
pi@fyypll:~ $ sudo gpio readall
+-----+-----+---------+------+---+---Pi 3B+-+---+------+---------+-----+-----+
| BCM | wPi | Name | Mode | V | Physical | V | Mode | Name | wPi | BCM |
+-----+-----+---------+------+---+----++----+---+------+---------+-----+-----+
| | | 3.3v | | | 1 || 2 | | | 5v | | |
| 2 | 8 | SDA.1 | IN | 1 | 3 || 4 | | | 5v | | |
| 3 | 9 | SCL.1 | IN | 1 | 5 || 6 | | | 0v | | |
| 4 | 7 | GPIO. 7 | IN | 1 | 7 || 8 | 1 | OUT | TxD | 15 | 14 |
| | | 0v | | | 9 || 10 | 1 | IN | RxD | 16 | 15 |
| 17 | 0 | GPIO. 0 | IN | 0 | 11 || 12 | 0 | IN | GPIO. 1 | 1 | 18 |
| 27 | 2 | GPIO. 2 | IN | 0 | 13 || 14 | | | 0v | | |
| 22 | 3 | GPIO. 3 | IN | 0 | 15 || 16 | 0 | IN | GPIO. 4 | 4 | 23 |
| | | 3.3v | | | 17 || 18 | 0 | IN | GPIO. 5 | 5 | 24 |
| 10 | 12 | MOSI | IN | 0 | 19 || 20 | | | 0v | | |
| 9 | 13 | MISO | IN | 0 | 21 || 22 | 0 | IN | GPIO. 6 | 6 | 25 |
| 11 | 14 | SCLK | IN | 0 | 23 || 24 | 1 | IN | CE0 | 10 | 8 |
| | | 0v | | | 25 || 26 | 1 | IN | CE1 | 11 | 7 |
| 0 | 30 | SDA.0 | IN | 1 | 27 || 28 | 1 | IN | SCL.0 | 31 | 1 |
| 5 | 21 | GPIO.21 | IN | 1 | 29 || 30 | | | 0v | | |
| 6 | 22 | GPIO.22 | IN | 1 | 31 || 32 | 0 | IN | GPIO.26 | 26 | 12 |
| 13 | 23 | GPIO.23 | IN | 0 | 33 || 34 | | | 0v | | |
| 19 | 24 | GPIO.24 | IN | 0 | 35 || 36 | 0 | IN | GPIO.27 | 27 | 16 |
| 26 | 25 | GPIO.25 | IN | 0 | 37 || 38 | 0 | IN | GPIO.28 | 28 | 20 |
| | | 0v | | | 39 || 40 | 0 | IN | GPIO.29 | 29 | 21 |
+-----+-----+---------+------+---+----++----+---+------+---------+-----+-----+
| BCM | wPi | Name | Mode | V | Physical | V | Mode | Name | wPi | BCM |
+-----+-----+---------+------+---+---Pi 3B+-+---+------+---------+-----+-----+
pi@fyypll:~ $

要是上面这个你看着懵比的话,那我用一张别人做好的图吧:

我们可以看到,4号和6号物理引脚没有 wiringPi 编码,但是8号物理引脚有,对应 wiringPi 编码是15。

记住这个编码,因为我们下面的代码要通过这个8号引脚控制风扇转还是停,就需要这个编码来控制。

编写脚本

因为我们要通过8号物理引脚控制风扇,在编写程序时,就要用它对应的 wiringPi 编码15来控制。

我的控制代码是用 shell 脚本写的,我看网上有的用C有的用Python,完全没必要啊,直接用 shell 脚本多简单啊。

建个 fengshan.sh 文件,写入如下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#!/bin/bash
#设置8号物理I/O口为输出状态
sudo gpio mode 15 'OUTPUT'
#设置为死循环,一直监控设备状态
while :
do
temp=`cat /sys/class/thermal/thermal_zone0/temp`
#获取cpu的温度
cpu_temp=`expr $temp / 1000`
#如果cpu温度大于45度
if [ $cpu_temp -gt 45 ]
then
#开启风扇
sudo gpio write 15 0
fi
#如果cpu温度小于37度
if [ $cpu_temp -lt 37 ]
then
#关闭风扇
sudo gpio write 15 1
fi
#每隔10秒执行一次循环
sleep 10
done

脚本写好后,我直接将脚本放到 /usr 目录下,给脚本执行权限。

设置开机启动

脚本弄好了,将脚本加入开机启动,这样每次开机都不需要我们手动执行脚本了。

sudo vim /etc/rc.local 命令打开 /etc/rc.local 文件,你会看到如下内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#!/bin/sh -e
#
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.

# Print the IP address
_IP=$(hostname -I) || true
if [ "$_IP" ]; then
printf "My IP address is %s\n" "$_IP"
fi
exit 0

将代码

1
nohup /usr/fengshan.sh

加入 fiexit 0 中间,然后保存即可。