demo地址:https://github.com/zackzhangCN/GPIODemo.git
Raspberry 4B发热量较大, 天热了, 被动散热扛不住了, 为了板子不被烧坏, 加上一个小小的5V散热扇, 为了能够让它根据CPU温度自动开关散热扇, 特地写下CPU风扇自动调节程序
通过GPIO操作硬件
Raspberry带有40个GPIO, 可以将散热扇连接到GPIO针脚, 通过程序控制GPIO针脚的高低电平达到控制硬件的目的.
Raspberry 4B GPIO引脚图:
创建springboot项目
引入java操作gpio的maven依赖
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.2.RELEASE</version>
<relativePath/>
</parent>
<dependencies>
<!--web-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--引入pi4j操作gpio端口依赖-->
<dependency>
<groupId>com.pi4j</groupId>
<artifactId>pi4j-core</artifactId>
<version>1.2</version>
</dependency>
</dependencies>
配置文件
server:
port: 8082
# Raspbian系统中cpu温度记录文件地址
cpu:
thermal:
path: /sys/class/thermal/thermal_zone0/temp
启动器
package cn.zack;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;
/**
* @author zack
*/
@EnableScheduling
@SpringBootApplication
public class CPUThermalApplication {
public static void main(String[] args) {
SpringApplication.run(CPUThermalApplication.class, args);
System.out.println("CPU温度调节系统启动完成...");
}
}
编写GPIO控制器
package cn.zack.utils;
import com.pi4j.io.gpio.GpioController;
import com.pi4j.io.gpio.GpioFactory;
/**
* @author cn.zack
* GPIO控制器
*/
public class GPIO_Utils {
private static GpioController gpioController;
/**
* 双锁检查 创建全局唯一GPIO控制器, 防止多线程操作GPIO烧毁电路
*
* @return
*/
public static GpioController getGpioController() {
if (gpioController == null) {
synchronized (GPIO_Utils.class) {
if (gpioController == null) {
gpioController = GpioFactory.getInstance();
}
}
}
return gpioController;
}
}
通过定时任务监控CPU温度, 控制散热
package cn.zack.schedule;
import cn.zack.utils.GPIO_Utils;
import com.pi4j.io.gpio.GpioController;
import com.pi4j.io.gpio.GpioPinDigitalOutput;
import com.pi4j.io.gpio.PinState;
import com.pi4j.io.gpio.RaspiPin;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.concurrent.TimeUnit;
/**
* @author zack
*/
@Service
public class CPU_Thermal_Schedule {
// 控制台输出信息
private static final Logger logger = LoggerFactory.getLogger(CPU_Thermal_Schedule.class);
// 获取gpio控制器
GpioController gpioController = GPIO_Utils.getGpioController();
// 初始化散热扇为开启状态
GpioPinDigitalOutput gpio00 = gpioController.provisionDigitalOutputPin(RaspiPin.GPIO_00, "GPIOControl", PinState.LOW);
static {
logger.info("初始化CPU散热扇");
}
@Value("${cpu.thermal.path}")
private String cpuThermalPath;
/**
* 定时监控CPU温度信息, 每分钟一次, 如果温度高于55°则开启散热扇, 低于50°则关闭散热扇
*/
@Scheduled(fixedRate = 1000 * 60)
public void autoControlCPUThermal() {
logger.info("开始调整CPU散热扇");
// 读取cpu温度
Integer cpuThermal = getCpuThermal();
// 高于55°, 开启散热扇
if (cpuThermal >= 55) {
gpioControl(0);
}
// 低于50°, 关闭散热扇
if (cpuThermal <= 50) {
gpioControl(1);
}
}
/**
* 获取cpu温度信息
*
* @return cpu温度
*/
public Integer getCpuThermal() {
Integer thermal = 0;
try {
// 读取cpu温度文件
Path path = Paths.get(cpuThermalPath);
List<String> list = Files.readAllLines(path);
String line1 = list.get(0);
// 取温度数值, 除1000, 得摄氏度值
thermal = Integer.parseInt(line1) / 1000;
logger.info("读取CPU温度为: {}, 摄氏度取整: {}°", line1, thermal);
} catch (IOException e) {
e.printStackTrace();
}
return thermal;
}
/**
* cpu散热扇开启或关闭
* 散热扇正极接引脚2(5V)
* 散热扇负极接引脚11(GPIO_01)
* 通过控制GPIO_01的高低电平来控制散热扇
*
* @param status
*/
public void gpioControl(Integer status) {
// 开启或者关闭散热扇
if (status == 0) {
gpio00.low();
logger.info("开启散热扇");
} else {
gpio00.blink(1, TimeUnit.MINUTES);
logger.info("关闭散热扇");
}
}
}
将项目打成jar包发布到Raspberry启动
其中, CPU散热扇正极接2号引脚(5V DC输出), 负极接程序中控制的11号引脚(GPIO_01).
启动命令:
java -jar XXX.jar
启动后CPU温度得到明显改善:
root@raspberrypi:/java/cpuThermal# cat /sys/class/thermal/thermal_zone0/temp
60025
root@raspberrypi:/java/cpuThermal# cat /sys/class/thermal/thermal_zone0/temp
57740
root@raspberrypi:/java/cpuThermal# cat /sys/class/thermal/thermal_zone0/temp
53898
root@raspberrypi:/java/cpuThermal# cat /sys/class/thermal/thermal_zone0/temp
47336
root@raspberrypi:/java/cpuThermal# cat /sys/class/thermal/thermal_zone0/temp
39106
root@raspberrypi:/java/cpuThermal#
启动成功: