树莓派4B系列教程四 :CPU智能闭环温控
写在前面
在上一节提到通过散热片和散热风扇实现CPU的智能温度控制问题,但是没有深入展开。本节主要来讲讲这个智能温控闭环控制的思路,动手来实现这个想法。
温控闭环的思路
温控闭环的思路是根据树莓派的CPU温度,实现风扇的启停控制。
当CPU温度超过给定温度T1,则开启风扇。
当CPU温度降低到给定温度T2,则关闭风扇。
同时为了避免风扇的频繁启停,可以控制程序5s做一次判断,保持风扇启停惯性。
智能温控电路
下图为树莓派4B的GPIO接口图。
智能闭环温控的软件实现
(1)安装wiringPi库
底层GPIO控制的库采用wiringPi
pi@raspberrypi:~ $ sudo apt search wiringpi
正在排序... 完成
全文搜索... 完成
wiringpi/testing,now 2.50 armhf [已安装]
The wiringPi libraries, headers and gpio command
搜索一下,发现系统中已经安装了wiringpi这个库了。
如果没有安装,请用下列命名安装下:
pi@raspberrypi:~ $ sudo apt-get install wiringpi
不过从上面可知,wiringPi默认版本是2.50,是不满足完全映射树莓派4B。
wget https://project-downloads.drogon.net/wiringpi-latest.deb
pi@raspberrypi:~ $ sudo dpkg -i wiringpi-latest.deb
(正在读取数据库 ... 系统当前共安装有 100251 个文件和目录。)
准备解压 wiringpi-latest.deb ...
正在解压 wiringpi (2.52) 并覆盖 (2.50) ...
正在设置 wiringpi (2.52) ...
正在处理用于 man-db (2.8.5-2) 的触发器 ...
pi@raspberrypi:~ $ gpio -v
gpio version: 2.52
Copyright (c) 2012-2018 Gordon Henderson
This is free software with ABSOLUTELY NO WARRANTY.
For details type: gpio -warranty
Raspberry Pi Details:
Type: Pi 4B, Revision: 02, Memory: 4096MB, Maker: Sony
* Device tree is enabled.
*--> Raspberry Pi 4 Model B Rev 1.2
* This Raspberry Pi supports user-level GPIO access.
pi@raspberrypi:~ $ gpio readall
+-----+-----+---------+------+---+---Pi 4B--+---+------+---------+-----+-----+
| 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 | IN | TxD | 15 | 14 |
| | | 0v | | | 9 || 10 | 1 | IN | RxD | 16 | 15 |
| 17 | 0 | GPIO. 0 | OUT | 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 4B--+---+------+---------+-----+-----+
从GPIO映射图可知,我们选择排针(物理硬件接口)上的GPIO11对应wiringPi软件库中的GPIO0,所以下面软件代码中,我们会用GPIO0控制风扇的启停。
(2)编写代码(此处我采用C代码)
pi@raspberrypi:~ $ vim fan_ctrl.c
pi@raspberrypi:~ $ cat fan_ctrl.c
#include <stdio.h>
#include <stdlib.h>
#include <wiringPi.h>
//导入文件控制函数库
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#define TEMP_PATH "/sys/class/thermal/thermal_zone0/temp"
#define MAX_SIZE 20
#define GPIO_FAN 0
int main(void)
{
int fd;
double temp = 0;
char buf[MAX_SIZE];
wiringPiSetup();
pinMode(GPIO_FAN,OUTPUT);
while(1)
{
// 以只读方式打开/sys/class/thermal/thermal_zone0/temp
fd = open(TEMP_PATH, O_RDONLY);
//判断文件是否正常被打开
if (fd < 0)
{
//fprintf(stderr, "failed to open thermal_zone0/temp\n");
//return -1;
continue;
}
// 读取内容
if (read(fd, buf, MAX_SIZE) < 0)
{
//fprintf(stderr, "failed to read temp\n");
//return -1;
continue;
}
// 转换为浮点数打印
temp = atoi(buf) / 1000.0;
printf("temp: %.3f\n", temp);
if(temp>=65)
{
digitalWrite(GPIO_FAN,HIGH);
}
else if(temp<=45)
{
digitalWrite(GPIO_FAN,LOW);
}
// 关闭文件
close(fd);
sleep(5);
}
}
从程序可知,首先获取CPU温度,CPU温度超过65℃开启风扇,CPU温度降低到45℃关闭风扇,延时5s后,进行下一次判断。
C代码编译
pi@raspberrypi:~ $ gcc fan_ctrl.c -lwiringPi -o fan_ctrl
C程序执行
pi@raspberrypi:~ $ ./fan_ctrl
temp: 55.504
temp: 53.556
temp: 54.043
temp: 54.530
temp: 55.017
temp: 54.043
temp: 54.530
temp: 55.017
temp: 54.043
temp: 53.556
temp: 54.043
temp: 54.530
temp: 55.017
程序会5s打印一次CPU的温度信息。
至此说明,程序运行没有问题。如果想试试风扇的启停控制,可以适当修改源代码的启停温度点,即可测试。
智能温控软件程序开机自启动
新建自启动服务脚本
pi@raspberrypi:~ $ sudo touch /lib/systemd/system/fan_ctrl.service
pi@raspberrypi:~ $ sudo vim /lib/systemd/system/fan_ctrl.service
[Unit]
Description=temp control relay
After=network.target
[Service]
Type=simple
User=root
Restart=on-failure
RestartSec=5s
ExecStart=/home/pi/fan_ctrl &
ExecReload=/home/pi/fan_ctrl &
[Install]
WantedBy=multi-user.target
设置开机自启动
pi@raspberrypi:~ $ sudo systemctl daemon-reload
pi@raspberrypi:~ $ sudo systemctl start fan_ctrl.service
pi@raspberrypi:~ $ sudo systemctl enable fan_ctrl.service
Created symlink /etc/systemd/system/multi-user.target.wants/fan_ctrl.service → /lib/systemd/system/fan_ctrl.service.
pi@raspberrypi:~ $ sudo systemctl status fan_ctrl.service
● fan_ctrl.service - temp control relay
Loaded: loaded (/lib/systemd/system/fan_ctrl.service; enabled; vendor preset: enabled)
Active: active (running) since Sat 2020-12-26 17:11:29 CST; 25s ago
Main PID: 5409 (fan_ctrl)
Tasks: 1 (limit: 4915)
CGroup: /system.slice/fan_ctrl.service
└─5409 /home/pi/fan_ctrl &
12月 26 17:11:30 raspberrypi systemd[1]: Started temp control relay.
OK,一切均正常运行,还你世界一片安静。
总结
本节优点技术难度,要求有一点硬件电路知识、嵌入式软件知识和动手能力,不过折腾就是一种快乐。
生命不止,折腾不息。
Good luck!!!